11#!/usr/bin/env python
22
3- # _ _ _ _ _
3+ # _ _ _ _ _
44# | | | | (_) | |
55# _ _ ___| |__ | | _ _| | |
66# | | | |/___) _ \| |_/ ) | | |
@@ -92,11 +92,11 @@ def __add__(self, other):
9292
9393def log (settings , msg ):
9494 log_file = settings ['log_file' ]
95-
95+
9696 contents = '\n {0} {1}\n Current state:\n ' .format (str (datetime .now ()), msg )
9797 with open (log_file , 'a+' ) as log :
9898 log .write (contents )
99-
99+
100100 # Log current USB state
101101 if CURRENT_PLATFORM .startswith ("DARWIN" ):
102102 os .system ("system_profiler SPUSBDataType >> " + log_file )
@@ -105,7 +105,7 @@ def log(settings, msg):
105105
106106def shred (settings ):
107107 shredder = settings ['remove_file_cmd' ]
108-
108+
109109 # List logs and settings to be removed
110110 if settings ['melt_usbkill' ]:
111111 settings ['folders_to_remove' ].append (os .path .dirname (settings ['log_file' ]))
@@ -116,39 +116,39 @@ def shred(settings):
116116 else :
117117 settings ['files_to_remove' ].append (os .path .realpath (__file__ ))
118118 settings ['files_to_remove' ].append (usbkill_folder + "/usbkill.ini" )
119-
119+
120120 # Remove files and folders
121121 for _file in settings ['files_to_remove' ] + settings ['folders_to_remove' ]:
122122 os .system (shredder + _file )
123-
123+
124124def kill_computer (settings ):
125125 # Log what is happening:
126126 if not settings ['melt_usbkill' ]: # No need to spend time on logging if logs will be removed
127127 log (settings , "Detected a USB change. Dumping the list of connected devices and killing the computer..." )
128-
128+
129129 # Shred as specified in settings
130130 shred (settings )
131-
131+
132132 # Execute kill commands in order.
133133 for command in settings ['kill_commands' ]:
134134 os .system (command )
135-
135+
136136 if settings ['do_sync' ]:
137137 # Sync the filesystem to save recent changes
138138 os .system ("sync" )
139139 else :
140140 # If syncing is risky because it might take too long, then sleep for 5ms.
141141 # This will still allow for syncing in most cases.
142142 sleep (0.05 )
143-
143+
144144 # Wipe ram and/or swap
145145 if settings ['do_wipe_ram' ] and settings ['do_wipe_swap' ]:
146146 os .system (settings ['wipe_ram_cmd' ] + " & " + settings ['wipe_swap_cmd' ])
147147 elif settings ['do_wipe_ram' ]:
148148 os .system (settings ['wipe_ram_cmd' ])
149149 elif settings ['do_wipe_swap' ]:
150150 os .system (settings ['wipe_swap_cmd' ])
151-
151+
152152 if settings ['shut_down' ]: # (Use argument --no-shut-down to prevent a shutdown.)
153153 # Finally poweroff computer immediately
154154 if CURRENT_PLATFORM .startswith ("DARWIN" ):
@@ -160,7 +160,7 @@ def kill_computer(settings):
160160 else :
161161 # Linux-based systems - Will shutdown
162162 os .system ("poweroff -f" )
163-
163+
164164 # Exit the process to prevent executing twice (or more) all commands
165165 sys .exit (0 )
166166
@@ -180,7 +180,7 @@ def check_inside(result, devices):
180180 try :
181181 result ["Built-in_Device" ]
182182 except KeyError :
183-
183+
184184 # Check if vendor_id/product_id is available for this one
185185 try :
186186 # Ensure vendor_id and product_id are present
@@ -209,15 +209,15 @@ def check_inside(result, devices):
209209 for result_deep in result ["_items" ]:
210210 # Check what's inside the _items array
211211 check_inside (result_deep , devices )
212-
212+
213213 except KeyError : {}
214-
214+
215215 # Run the loop
216216 devices = []
217217 for result in df [0 ]["_items" ]:
218218 check_inside (result , devices )
219219 return devices
220-
220+
221221def lsusb ():
222222 # A Python version of the command 'lsusb' that returns a list of connected usbids
223223 if CURRENT_PLATFORM .startswith ("DARWIN" ):
@@ -230,9 +230,9 @@ def lsusb():
230230def program_present (program ):
231231 if sys .version_info [0 ] == 3 :
232232 # Python3
233- from shutil import which
233+ from shutil import which
234234 return which (program ) != None
235-
235+
236236 else :
237237 """
238238 Test if an executable exist in Python2
@@ -251,7 +251,7 @@ def is_exe(fpath):
251251 if is_exe (exe_file ):
252252 return True
253253 return False
254-
254+
255255def load_settings (filename ):
256256 # Libraries that are only needed in this function:
257257 from json import loads as jsonloads
@@ -287,7 +287,7 @@ def get_setting(name, gtype=''):
287287
288288 # Read all lines of settings file
289289 config .read (filename )
290-
290+
291291 # Build settings
292292 settings = dict ({
293293 'sleep_time' : get_setting ('sleep' , 'FLOAT' ),
@@ -300,26 +300,26 @@ def get_setting(name, gtype=''):
300300 'do_sync' : get_setting ('do_sync' , 'BOOL' ),
301301 'kill_commands' : jsonloads (get_setting ('kill_commands' ).strip ())
302302 })
303-
303+
304304 settings ['do_wipe_ram' ] = False
305305 if get_setting ('do_wipe_ram' , 'BOOL' ):
306306 settings ['do_wipe_ram' ] = True
307307 settings ['wipe_ram_cmd' ] = get_setting ('wipe_ram_cmd' ) + " "
308-
308+
309309 settings ['do_wipe_swap' ] = False
310310 if get_setting ('do_wipe_swap' , 'BOOL' ):
311311 settings ['do_wipe_swap' ] = True
312312 settings ['wipe_swap_cmd' ] = get_setting ('wipe_swap_cmd' ) + " "
313313
314314 return settings
315-
315+
316316def loop (settings ):
317317 # Main loop that checks every 'sleep_time' seconds if computer should be killed.
318318 # Allows only whitelisted usb devices to connect!
319319 # Does not allow usb device that was present during program start to disconnect!
320320 start_devices = lsusb ()
321321 acceptable_devices = start_devices + settings ['whitelist' ]
322-
322+
323323 # Write to logs that loop is starting:
324324 msg = "[INFO] Started patrolling the USB ports every " + str (settings ['sleep_time' ]) + " seconds..."
325325 log (settings , msg )
@@ -331,7 +331,7 @@ def loop(settings):
331331 current_devices = lsusb ()
332332
333333 # Check that all current devices are in the set of acceptable devices
334- # and their cardinality is less than or equal to what is allowed
334+ # and their cardinality is less than or equal to what is allowed
335335 for device , count in current_devices .items ():
336336 if device not in acceptable_devices :
337337 # A device with unknown usbid detected
@@ -341,15 +341,15 @@ def loop(settings):
341341 kill_computer (settings )
342342
343343 # Check that all start devices are still present in current devices
344- # and their cardinality still the same
344+ # and their cardinality still the same
345345 for device , count in start_devices .items ():
346346 if device not in current_devices :
347347 # A usbid has disappeared completely
348348 kill_computer (settings )
349349 if count > current_devices [device ]:
350350 # Count of a usbid device is lower than at program start (not enough devices for given usbid)
351351 kill_computer (settings )
352-
352+
353353 sleep (settings ['sleep_time' ])
354354
355355def startup_checks ():
@@ -363,26 +363,26 @@ def startup_checks():
363363
364364 # Check arguments
365365 args = sys .argv [1 :]
366-
367- # Check for help
366+
367+ # Check for help
368368 if '-h' in args or '--help' in args :
369369 sys .exit (help_message )
370-
370+
371371 if '--version' in args :
372372 print ('usbkill' , __version__ )
373373 sys .exit (0 )
374-
374+
375375 copy_settings = False
376376 if '--cs' in args :
377377 args .remove ('--cs' )
378378 copy_settings = True
379-
379+
380380 shut_down = True
381381 if '--no-shut-down' in args :
382382 print ("[NOTICE] Ready to execute all the (potentially destructive) commands, but NOT shut down the computer." )
383383 args .remove ('--no-shut-down' )
384384 shut_down = False
385-
385+
386386 # Check all other args
387387 if len (args ) > 0 :
388388 sys .exit ("\n [ERROR] Argument not understood. Can only understand -h\n " )
@@ -408,17 +408,17 @@ def startup_checks():
408408 sys .exit ("\n [ERROR] You have lost your settings file. Get a new copy of the usbkill.ini and place it in /etc/ or in " + sources_path + "/\n " )
409409 print ("[NOTICE] Copying install/setting.ini to " + SETTINGS_FILE )
410410 os .system ("cp " + sources_path + "install/usbkill.ini " + SETTINGS_FILE )
411-
411+
412412 # Load settings
413413 settings = load_settings (SETTINGS_FILE )
414414 settings ['shut_down' ] = shut_down
415-
415+
416416 # Make sure no spaces a present in paths to be wiped.
417417 for name in settings ['folders_to_remove' ] + settings ['files_to_remove' ]:
418418 if ' ' in name :
419419 msg += "[ERROR][WARNING] '" + name + "'as specified in your usbkill.ini contains a space.\n "
420420 sys .exit (msg )
421-
421+
422422 # Make sure srm is present if it will be used.
423423 if settings ['melt_usbkill' ] or len (settings ['folders_to_remove' ] + settings ['files_to_remove' ]) > 0 :
424424 if not program_present ('srm' ):
@@ -437,32 +437,30 @@ def startup_checks():
437437 sys .exit ("[ERROR] usbkill configured to destroy data, but srm not installed.\n " )
438438 if not settings ['wipe_swap_cmd' ].startswith ('sswap' ):
439439 sys .exit ("[ERROR] wipe_swap_cmd should start with `sswap'. sswap should be used for automated data overwrite.\n " )
440-
440+
441441 # Make sure there is a logging folder
442442 log_folder = os .path .dirname (settings ['log_file' ])
443443 if not os .path .isdir (log_folder ):
444444 os .mkdir (log_folder )
445-
445+
446446 return settings
447447
448448def go ():
449449 # Run startup checks and load settings
450450 settings = startup_checks ()
451-
451+
452452 # Define exit handler now that settings are loaded...
453453 def exit_handler (signum , frame ):
454454 print ("\n [INFO] Exiting because exit signal was received\n " )
455455 log (settings , "[INFO] Exiting because exit signal was received" )
456456 sys .exit (0 )
457-
457+
458458 # Register handlers for clean exit of program
459459 for sig in [signal .SIGINT , signal .SIGTERM , signal .SIGQUIT , ]:
460460 signal .signal (sig , exit_handler )
461-
461+
462462 # Start main loop
463463 loop (settings )
464-
464+
465465if __name__ == "__main__" :
466466 go ()
467-
468-
0 commit comments