def is_admin(): # type: () -> bool """ Checks whether current program has administrative privileges in OS Works with Windows XP SP2+ and most Unixes :return: Boolean, True if admin privileges present """ current_os_name = os.name # Works with XP SP2 + if current_os_name == "nt": try: return IsUserAnAdmin() except Exception: raise EnvironmentError("Cannot check admin privileges") elif current_os_name == "posix": # Check for root on Posix # os.getuid only exists on postix OSes # pylint: disable=E1101 (no-member) return os.getuid() == 0 else: raise EnvironmentError( "OS does not seem to be supported for admin check. OS: {}".format( current_os_name))
def __init__(self, uac=True, shred_paths=None, exit=False): if uac and 'nt' == os.name and Windows.elevate_privileges(): # privileges escalated in other process sys.exit(0) Gtk.Application.__init__(self, application_id='org.gnome.Bleachbit', flags=Gio.ApplicationFlags.FLAGS_NONE) if not exit: from bleachbit import RecognizeCleanerML RecognizeCleanerML.RecognizeCleanerML() register_cleaners() GObject.threads_init() if shred_paths: self.shred_paths(shred_paths) return if 'nt' == os.name: # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # https://www.bleachbit.org/forum/074-fails-errors try: import sqlite3 except ImportError: logger.exception(_("Error loading the SQLite module: the antivirus software may be blocking it.")) if 'posix' == os.name and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.')) if 'nt' == os.name and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.')) self.append_text('\n') if exit: # This is used for automated testing of whether the GUI can start. print('Success') GObject.idle_add(lambda: self.quit(), priority=GObject.PRIORITY_LOW)
def RegisterPythonServer(filename, progids=None, verbose=0): if progids: if isinstance(progids, str): progids = [progids] # we know the CLSIDs we need, but we might not be an admin user # and otherwise unable to register them. So as long as the progids # exist and the DLL points at our version, assume it already is. why_not = None for progid in progids: try: clsid = pythoncom.MakeIID(progid) except pythoncom.com_error: # no progid - not registered. break # have a CLSID - open it. try: HKCR = winreg.HKEY_CLASSES_ROOT hk = winreg.OpenKey(HKCR, "CLSID\\%s" % clsid) dll = winreg.QueryValue(hk, "InprocServer32") except WindowsError: # no CLSID or InProcServer32 - not good! break ok_files = [os.path.basename(pythoncom.__file__), 'pythoncomloader%d%d.dll' % (sys.version_info[0], sys.version_info[1])] if os.path.basename(dll) not in ok_files: why_not = "%r is registered against a different Python version (%s)" % (progid, dll) break else: #print "Skipping registration of '%s' - already registered" % filename return # needs registration - see if its likely! try: from win32com.shell.shell import IsUserAnAdmin except ImportError: print("Can't import win32com.shell - no idea if you are an admin or not?") is_admin = False else: try: is_admin = IsUserAnAdmin() except pythoncom.com_error: # old, less-secure OS - assume *is* admin. is_admin = True if not is_admin: msg = "%r isn't registered, but I'm not an administrator who can register it." % progids[0] if why_not: msg += "\n(registration check failed as %s)" % why_not # throw a normal "class not registered" exception - we don't report # them the same way as "real" errors. raise pythoncom.com_error(winerror.CO_E_CLASSSTRING, msg, None, -1) # so theoretically we are able to register it. cmd = '%s "%s" --unattended > nul 2>&1' % (win32api.GetModuleFileName(0), filename) if verbose: print("Registering engine", filename) # print cmd rc = os.system(cmd) if rc: print("Registration command was:") print(cmd) raise RuntimeError("Registration of engine '%s' failed" % filename)
def cb_register_cleaners_done(self): """Called from register_cleaners()""" self.progressbar.hide() # update tree view self.tree_store.refresh_rows() # expand tree view self.view.expand_all() # Check for online updates. if not self._auto_exit and \ bleachbit.online_update_notification_enabled and \ options.get("check_online_updates") and \ not hasattr(self, 'checked_for_updates'): self.checked_for_updates = True self.check_online_updates() # Show information for first start. # (The first start flag is set also for each new version.) if options.get("first_start") and not self._auto_exit: if os.name == 'posix': self.append_text( _('Access the application menu by clicking the hamburger icon on the title bar.' )) pref = self.get_preferences_dialog() pref.run() if os.name == 'nt': self.append_text( _('Access the application menu by clicking the logo on the title bar.' )) options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') # Show notice about admin privileges. if os.name == 'posix' and os.path.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' ) + '\n') if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') # remove from idle loop (see GObject.idle_add) return False
def is_admin() -> bool: if os_is_windows(): from win32com.shell.shell import IsUserAnAdmin return IsUserAnAdmin() else: # Importing it this way since geteuid doesn't exist in windows and mypy complains there geteuid = cast(Callable[[], int], getattr(os, "geteuid")) return geteuid() == 0
def __init__(self, uac=True, shred_paths=None, exit=False): if uac and 'nt' == os.name and Windows.elevate_privileges(): # privileges escalated in other process sys.exit(0) if not exit: from bleachbit import RecognizeCleanerML RecognizeCleanerML.RecognizeCleanerML() register_cleaners() self.create_window() gobject.threads_init() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if 'nt' == os.name and 'windows_exe' == getattr(sys, 'frozen', None): # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) if shred_paths: self.shred_paths(shred_paths) return if options.get("first_start") and 'posix' == os.name: pref = PreferencesDialog(self.window, self.cb_refresh_operations) pref.run() options.set('first_start', False) if bleachbit.online_update_notification_enabled and options.get( "check_online_updates"): self.check_online_updates() if 'nt' == os.name: # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # https://www.bleachbit.org/forum/074-fails-errors try: import sqlite3 except ImportError: logger.exception( _("Error loading the SQLite module: the antivirus software may be blocking it." )) if 'posix' == os.name and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if 'nt' == os.name and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') if exit: # This is used for automated testing of whether the GUI can start. gobject.idle_add(lambda: gtk.main_quit(), priority=gobject.PRIORITY_LOW)
def __init__(self, auto_exit, *args, **kwargs): super(GUI, self).__init__(*args, **kwargs) self.auto_exit = auto_exit self.set_wmclass(APP_NAME, APP_NAME) self.populate_window() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if os.name == 'nt' and getattr(sys, 'frozen', None) == 'windows_exe': # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) Gtk.Settings.get_default().set_property( 'gtk-application-prefer-dark-theme', options.get('dark_mode')) if options.is_corrupt(): logger.error( _('Resetting the configuration file because it is corrupt: %s') % bleachbit.options_file) bleachbit.Options.init_configuration() if options.get("first_start") and os.name == 'posix' and not auto_exit: pref = PreferencesDialog(self, self.cb_refresh_operations) pref.run() options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') if os.name == 'posix' and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') GLib.idle_add(self.cb_refresh_operations)
def is_admin() -> bool: if os_is_windows(): # Do this import lazily as it is only available on Windows from win32com.shell.shell import IsUserAnAdmin # pylint:disable=import-outside-toplevel return IsUserAnAdmin() else: # Importing it this way since geteuid doesn't exist in windows and mypy complains there geteuid = cast(Callable[[], int], getattr(os, "geteuid")) return geteuid() == 0
def check_is_admin(): global _is_admin if _is_admin is None: from win32com.shell.shell import IsUserAnAdmin import pythoncom try: _is_admin = IsUserAnAdmin() except pythoncom.com_error, exc: if exc.hresult != winerror.E_NOTIMPL: raise # not impl on this platform - must be old - assume is admin _is_admin = True
def is_admin(): """ Checks whether current program has administrative privileges in OS Works with Windows XP SP2+ and most Unixes :return: Boolean, True if admin privileges present """ current_os_name = os.name # Works with XP SP2 + if current_os_name == 'nt': try: return IsUserAnAdmin() except Exception: raise EnvironmentError('Cannot check admin privileges') elif current_os_name == 'posix': # Check for root on Posix # os.getuid only exists on postix OSes return os.getuid() == 0 else: raise EnvironmentError( 'OS does not seem to be supported for admin check. OS: %s' % current_os_name)
def __init__(self, auto_exit, *args, **kwargs): super(GUI, self).__init__(*args, **kwargs) self.auto_exit = auto_exit self.set_wmclass(APP_NAME, APP_NAME) self.populate_window() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') from bleachbit.Log import GtkLoggerHandler self.gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(self.gtklog) # process any delayed logs from bleachbit.Log import DelayLog if isinstance(sys.stderr, DelayLog): for msg in sys.stderr.read(): self.append_text(msg) # if stderr was redirected - keep redirecting it sys.stderr = self.gtklog Gtk.Settings.get_default().set_property( 'gtk-application-prefer-dark-theme', options.get('dark_mode')) if options.is_corrupt(): logger.error( _('Resetting the configuration file because it is corrupt: %s') % bleachbit.options_file) bleachbit.Options.init_configuration() if options.get("first_start") and not auto_exit: if os.name == 'posix': self.append_text( _('Access the application menu by clicking the hamburger icon on the title bar.' )) pref = PreferencesDialog(self, self.cb_refresh_operations) pref.run() if os.name == 'nt': self.append_text( _('Access the application menu by clicking the logo on the title bar.' )) options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') if os.name == 'posix' and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') GLib.idle_add(self.cb_refresh_operations)
def wipe_contents(path, truncate=True): """Wipe files contents http://en.wikipedia.org/wiki/Data_remanence 2006 NIST Special Publication 800-88 (p. 7): "Studies have shown that most of today's media can be effectively cleared by one overwrite" """ def wipe_write(): size = getsize(path) try: f = open(path, 'wb') except IOError as e: if e.errno == errno.EACCES: # permission denied os.chmod(path, 0o200) # user write only f = open(path, 'wb') else: raise blanks = b'\0' * 4096 while size > 0: f.write(blanks) size -= 4096 f.flush() # flush to OS buffer os.fsync(f.fileno()) # force write to disk return f if 'nt' == os.name: from win32com.shell.shell import IsUserAnAdmin if 'nt' == os.name and IsUserAnAdmin(): from bleachbit.WindowsWipe import file_wipe, UnsupportedFileSystemError import warnings from bleachbit import _ try: file_wipe(path) except pywinerror as e: # 32=The process cannot access the file because it is being used by another process. # 33=The process cannot access the file because another process has # locked a portion of the file. if not e.winerror in (32, 33): # handle only locking errors raise # Try to truncate the file. This makes the behavior consistent # with Linux and with Windows when IsUserAdmin=False. try: with open(path, 'w') as f: truncate_f(f) except IOError as e2: if errno.EACCES == e2.errno: # Common when the file is locked # Errno 13 Permission Denied pass # translate exception to mark file to deletion in Command.py raise WindowsError(e.winerror, e.strerror) except UnsupportedFileSystemError as e: warnings.warn( _('There was at least one file on a file system that does not support advanced overwriting.' ), UserWarning) f = wipe_write() else: # The wipe succeed, so prepare to truncate. f = open(path, 'w') else: f = wipe_write() if truncate: truncate_f(f) f.close()