diff options
Diffstat (limited to 'src')
15 files changed, 173 insertions, 134 deletions
| diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 05f81f0b..e965604a 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -39,7 +39,6 @@  # M:::::::::::~NMMM7???7MMMM:::::::::::::::::::::::NMMMI??I7MMMM:::::::::::::M  # M::::::::::::::7MMMMMMM+:::::::::::::::::::::::::::?MMMMMMMZ:::::::::::::::M  #                (thanks to: http://www.glassgiant.com/ascii/) -import logging  import signal  import sys  import os @@ -50,10 +49,7 @@ from PySide import QtCore, QtGui  from leap.bitmask import __version__ as VERSION  from leap.bitmask.util import leap_argparse -from leap.bitmask.util import log_silencer, LOG_FORMAT -from leap.bitmask.util.leap_log_handler import LeapLogHandler -from leap.bitmask.util.streamtologger import StreamToLogger -from leap.bitmask.platform_init import IS_WIN +from leap.bitmask.logs.utils import get_logger  from leap.bitmask.services.mail import plumber  from leap.common.events import server as event_server  from leap.mail import __version__ as MAIL_VERSION @@ -89,90 +85,6 @@ def sigterm_handler(*args, **kwargs):      mainwindow.quit() -def add_logger_handlers(debug=False, logfile=None, replace_stdout=True): -    """ -    Create the logger and attach the handlers. - -    :param debug: the level of the messages that we should log -    :type debug: bool -    :param logfile: the file name of where we should to save the logs -    :type logfile: str -    :return: the new logger with the attached handlers. -    :rtype: logging.Logger -    """ -    # TODO: get severity from command line args -    if debug: -        level = logging.DEBUG -    else: -        level = logging.WARNING - -    # Create logger and formatter -    logger = logging.getLogger(name='leap') -    logger.setLevel(level) -    formatter = logging.Formatter(LOG_FORMAT) - -    # Console handler -    try: -        import coloredlogs -        console = coloredlogs.ColoredStreamHandler(level=level) -    except ImportError: -        console = logging.StreamHandler() -        console.setLevel(level) -        console.setFormatter(formatter) -        using_coloredlog = False -    else: -        using_coloredlog = True - -    if using_coloredlog: -        replace_stdout = False - -    silencer = log_silencer.SelectiveSilencerFilter() -    console.addFilter(silencer) -    logger.addHandler(console) -    logger.debug('Console handler plugged!') - -    # LEAP custom handler -    leap_handler = LeapLogHandler() -    leap_handler.setLevel(level) -    leap_handler.addFilter(silencer) -    logger.addHandler(leap_handler) -    logger.debug('Leap handler plugged!') - -    # File handler -    if logfile is not None: -        logger.debug('Setting logfile to %s ', logfile) -        fileh = logging.FileHandler(logfile) -        fileh.setLevel(logging.DEBUG) -        fileh.setFormatter(formatter) -        fileh.addFilter(silencer) -        logger.addHandler(fileh) -        logger.debug('File handler plugged!') - -    if replace_stdout: -        replace_stdout_stderr_with_logging(logger) - -    return logger - - -def replace_stdout_stderr_with_logging(logger): -    """ -    Replace: -        - the standard output -        - the standard error -        - the twisted log output -    with a custom one that writes to the logger. -    """ -    # Disabling this on windows since it breaks ALL THE THINGS -    # The issue for this is #4149 -    if not IS_WIN: -        sys.stdout = StreamToLogger(logger, logging.DEBUG) -        sys.stderr = StreamToLogger(logger, logging.ERROR) - -        # Replace twisted's logger to use our custom output. -        from twisted.python import log -        log.startLogging(sys.stdout) - -  def do_display_version(opts):      """      Display version and exit. @@ -214,6 +126,14 @@ def main():      mail_logfile = opts.mail_log_file      start_hidden = opts.start_hidden +    replace_stdout = True +    if opts.repair or opts.import_maildir: +        # We don't want too much clutter on the comand mode +        # this could be more generic with a Command class. +        replace_stdout = False + +    logger = get_logger(debug, logfile, replace_stdout) +      #############################################################      # Given how paths and bundling works, we need to delay the imports      # of certain parts that depend on this path settings. @@ -232,13 +152,6 @@ def main():      BaseConfig.standalone = standalone -    replace_stdout = True -    if opts.repair or opts.import_maildir: -        # We don't want too much clutter on the comand mode -        # this could be more generic with a Command class. -        replace_stdout = False -    logger = add_logger_handlers(debug, logfile, replace_stdout) -      # ok, we got logging in place, we can satisfy mail plumbing requests      # and show logs there. it normally will exit there if we got that path.      do_mail_plumbing(opts) diff --git a/src/leap/bitmask/backend_app.py b/src/leap/bitmask/backend_app.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/leap/bitmask/backend_app.py diff --git a/src/leap/bitmask/frontend_app.py b/src/leap/bitmask/frontend_app.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/leap/bitmask/frontend_app.py diff --git a/src/leap/bitmask/gui/loggerwindow.py b/src/leap/bitmask/gui/loggerwindow.py index f19b172f..3a8354b1 100644 --- a/src/leap/bitmask/gui/loggerwindow.py +++ b/src/leap/bitmask/gui/loggerwindow.py @@ -27,7 +27,7 @@ from twisted.internet import threads  from ui_loggerwindow import Ui_LoggerWindow  from leap.bitmask.util.constants import PASTEBIN_API_DEV_KEY -from leap.bitmask.util.leap_log_handler import LeapLogHandler +from leap.bitmask.logs.leap_log_handler import LeapLogHandler  from leap.bitmask.util import pastebin  from leap.common.check import leap_assert, leap_assert_type diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index a3b81fde..c61b7dc9 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -52,7 +52,7 @@ from leap.bitmask.services import EIP_SERVICE, MX_SERVICE  from leap.bitmask.util import make_address  from leap.bitmask.util.keyring_helpers import has_keyring -from leap.bitmask.util.leap_log_handler import LeapLogHandler +from leap.bitmask.logs.leap_log_handler import LeapLogHandler  if IS_WIN:      from leap.bitmask.platform_init.locks import WindowsLock diff --git a/src/leap/bitmask/logs/__init__.py b/src/leap/bitmask/logs/__init__.py new file mode 100644 index 00000000..0516b304 --- /dev/null +++ b/src/leap/bitmask/logs/__init__.py @@ -0,0 +1,3 @@ +# levelname length == 8, since 'CRITICAL' is the longest +LOG_FORMAT = ('%(asctime)s - %(levelname)-8s - ' +              'L#%(lineno)-4s : %(name)s:%(funcName)s() - %(message)s') diff --git a/src/leap/bitmask/util/leap_log_handler.py b/src/leap/bitmask/logs/leap_log_handler.py index 807e53d4..24141638 100644 --- a/src/leap/bitmask/util/leap_log_handler.py +++ b/src/leap/bitmask/logs/leap_log_handler.py @@ -21,7 +21,7 @@ import logging  from PySide import QtCore -from leap.bitmask.util import LOG_FORMAT +from leap.bitmask.logs import LOG_FORMAT  class LogHandler(logging.Handler): diff --git a/src/leap/bitmask/util/log_silencer.py b/src/leap/bitmask/logs/log_silencer.py index 56b290e4..56b290e4 100644 --- a/src/leap/bitmask/util/log_silencer.py +++ b/src/leap/bitmask/logs/log_silencer.py diff --git a/src/leap/bitmask/util/streamtologger.py b/src/leap/bitmask/logs/streamtologger.py index 25a06718..25a06718 100644 --- a/src/leap/bitmask/util/streamtologger.py +++ b/src/leap/bitmask/logs/streamtologger.py diff --git a/src/leap/bitmask/util/tests/test_leap_log_handler.py b/src/leap/bitmask/logs/tests/test_leap_log_handler.py index 518fd35b..20b09aef 100644 --- a/src/leap/bitmask/util/tests/test_leap_log_handler.py +++ b/src/leap/bitmask/logs/tests/test_leap_log_handler.py @@ -24,7 +24,7 @@ except ImportError:  import logging -from leap.bitmask.util.leap_log_handler import LeapLogHandler +from leap.bitmask.logs.leap_log_handler import LeapLogHandler  from leap.bitmask.util.pyside_tests_helper import BasicPySlotCase  from leap.common.testing.basetest import BaseLeapTest diff --git a/src/leap/bitmask/util/tests/test_streamtologger.py b/src/leap/bitmask/logs/tests/test_streamtologger.py index fc97b794..9bbadde8 100644 --- a/src/leap/bitmask/util/tests/test_streamtologger.py +++ b/src/leap/bitmask/logs/tests/test_streamtologger.py @@ -26,7 +26,7 @@ except ImportError:  import logging  import sys -from leap.bitmask.util.streamtologger import StreamToLogger +from leap.bitmask.logs.streamtologger import StreamToLogger  from leap.common.testing.basetest import BaseLeapTest diff --git a/src/leap/bitmask/logs/utils.py b/src/leap/bitmask/logs/utils.py new file mode 100644 index 00000000..06959c45 --- /dev/null +++ b/src/leap/bitmask/logs/utils.py @@ -0,0 +1,92 @@ +import logging +import sys + +from leap.bitmask.logs import LOG_FORMAT +from leap.bitmask.logs.log_silencer import SelectiveSilencerFilter +from leap.bitmask.logs.leap_log_handler import LeapLogHandler +from leap.bitmask.logs.streamtologger import StreamToLogger +from leap.bitmask.platform_init import IS_WIN + + +def get_logger(debug=False, logfile=None, replace_stdout=True): +    """ +    Create the logger and attach the handlers. + +    :param debug: the level of the messages that we should log +    :type debug: bool +    :param logfile: the file name of where we should to save the logs +    :type logfile: str +    :return: the new logger with the attached handlers. +    :rtype: logging.Logger +    """ +    # TODO: get severity from command line args +    if debug: +        level = logging.DEBUG +    else: +        level = logging.WARNING + +    # Create logger and formatter +    logger = logging.getLogger(name='leap') +    logger.setLevel(level) +    formatter = logging.Formatter(LOG_FORMAT) + +    # Console handler +    try: +        import coloredlogs +        console = coloredlogs.ColoredStreamHandler(level=level) +    except ImportError: +        console = logging.StreamHandler() +        console.setLevel(level) +        console.setFormatter(formatter) +        using_coloredlog = False +    else: +        using_coloredlog = True + +    if using_coloredlog: +        replace_stdout = False + +    silencer = SelectiveSilencerFilter() +    console.addFilter(silencer) +    logger.addHandler(console) +    logger.debug('Console handler plugged!') + +    # LEAP custom handler +    leap_handler = LeapLogHandler() +    leap_handler.setLevel(level) +    leap_handler.addFilter(silencer) +    logger.addHandler(leap_handler) +    logger.debug('Leap handler plugged!') + +    # File handler +    if logfile is not None: +        logger.debug('Setting logfile to %s ', logfile) +        fileh = logging.FileHandler(logfile) +        fileh.setLevel(logging.DEBUG) +        fileh.setFormatter(formatter) +        fileh.addFilter(silencer) +        logger.addHandler(fileh) +        logger.debug('File handler plugged!') + +    if replace_stdout: +        replace_stdout_stderr_with_logging(logger) + +    return logger + + +def replace_stdout_stderr_with_logging(logger): +    """ +    Replace: +        - the standard output +        - the standard error +        - the twisted log output +    with a custom one that writes to the logger. +    """ +    # Disabling this on windows since it breaks ALL THE THINGS +    # The issue for this is #4149 +    if not IS_WIN: +        sys.stdout = StreamToLogger(logger, logging.DEBUG) +        sys.stderr = StreamToLogger(logger, logging.ERROR) + +        # Replace twisted's logger to use our custom output. +        from twisted.python import log +        log.startLogging(sys.stdout) diff --git a/src/leap/bitmask/platform_init/initializers.py b/src/leap/bitmask/platform_init/initializers.py index 14d96c9b..b282a229 100644 --- a/src/leap/bitmask/platform_init/initializers.py +++ b/src/leap/bitmask/platform_init/initializers.py @@ -14,15 +14,14 @@  #  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -  """ -Platform dependant initializing code +Platform-dependant initialization code.  """ -  import logging  import os  import platform  import stat +import sys  import subprocess  import tempfile @@ -47,7 +46,7 @@ _system = platform.system()  def init_platform():      """ -    Returns the right initializer for the platform we are running in, or +    Return the right initializer for the platform we are running in, or      None if no proper initializer is found      """      initializer = None @@ -79,7 +78,7 @@ UPDOWN_BADEXEC_MSG = BADEXEC_MSG % (  def get_missing_updown_dialog():      """ -    Creates a dialog for notifying of missing updown scripts. +    Create a dialog for notifying of missing updown scripts.      Returns that dialog.      :rtype: QtGui.QMessageBox instance @@ -101,7 +100,7 @@ def get_missing_updown_dialog():  def check_missing():      """ -    Checks for the need of installing missing scripts, and +    Check for the need of installing missing scripts, and      raises a dialog to ask user for permission to do it.      """      config = LeapSettings() @@ -149,7 +148,7 @@ def check_missing():  def _windows_has_tap_device():      """ -    Loops over the windows registry trying to find if the tap0901 tap driver +    Loop over the windows registry trying to find if the tap0901 tap driver      has been installed on this machine.      """      import _winreg as reg @@ -175,7 +174,7 @@ def _windows_has_tap_device():  def WindowsInitializer():      """ -    Raises a dialog in case that the windows tap driver has not been found +    Raise a dialog in case that the windows tap driver has not been found      in the registry, asking the user for permission to install the driver      """      if not _windows_has_tap_device(): @@ -219,7 +218,7 @@ def WindowsInitializer():  def _darwin_has_tun_kext():      """ -    Returns True only if we found a directory under the system kext folder +    Return True only if we found a directory under the system kext folder      containing a kext named tun.kext, AND we found a startup item named 'tun'      """      # XXX we should be smarter here and use kextstats output. @@ -235,7 +234,7 @@ def _darwin_has_tun_kext():  def _darwin_install_missing_scripts(badexec, notfound):      """ -    Tries to install the missing up/down scripts. +    Try to install the missing up/down scripts.      :param badexec: error for notifying execution error during command.      :type badexec: str @@ -290,7 +289,7 @@ def _darwin_install_missing_scripts(badexec, notfound):  def DarwinInitializer():      """ -    Raises a dialog in case that the osx tuntap driver has not been found +    Raise a dialog in case that the osx tuntap driver has not been found      in the registry, asking the user for permission to install the driver      """      # XXX split this function into several @@ -344,9 +343,49 @@ def DarwinInitializer():  #  # Linux initializers  # + +def _get_missing_resolvconf_dialog(): +    """ +    Create a dialog for notifying about missing openresolv. + +    :rtype: QtGui.QMessageBox instance +    """ +    NO_RESOLVCONF = ( +        "Could not find <b>resolvconf</b> installed in your system.\n" +        "Do you want to quit Bitmask now?") + +    EXPLAIN = ( +        "Encrypted Internet needs resolvconf installed to work properly.\n" +        "Please use your package manager to install it.\n") + +    msg = QtGui.QMessageBox() +    msg.setWindowTitle(msg.tr("Missing resolvconf framework")) +    msg.setText(msg.tr(NO_RESOLVCONF)) +    # but maybe the user really deserve to know more +    msg.setInformativeText(msg.tr(EXPLAIN)) +    msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) +    msg.setDefaultButton(QtGui.QMessageBox.Yes) +    return msg + + +def _linux_check_resolvconf(): +    """ +    Raise a dialog warning about the lack of the resolvconf framework. +    """ +    RESOLVCONF_PATH = "/sbin/resolvconf" +    missing = not os.path.isfile(RESOLVCONF_PATH) + +    if missing: +        msg = _get_missing_resolvconf_dialog() +        ret = msg.exec_() + +        if ret == QtGui.QMessageBox.Yes: +            sys.exit() + +  def _linux_install_missing_scripts(badexec, notfound):      """ -    Tries to install the missing up/down scripts. +    Try to install the missing up/down scripts.      :param badexec: error for notifying execution error during command.      :type badexec: str @@ -397,7 +436,11 @@ def _linux_install_missing_scripts(badexec, notfound):  def LinuxInitializer():      """ -    Raises a dialog in case that either updown scripts or policykit file -    are missing or they have incorrect permissions. +    Raise a dialog if needed files are missing. + +    Missing files can be either system-wide resolvconf, bitmask-root, or +    policykit file. The dialog will also be raised if some of those files are +    found to have incorrect permissions.      """ +    _linux_check_resolvconf()      check_missing() diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 54845a8a..955768d1 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -63,28 +63,21 @@ def _is_auth_agent_running():      :return: True if it's running, False if it's not.      :rtype: boolean      """ +    # Note that gnome-shell does not uses a separate process for the +    # polkit-agent, it uses a polkit-agent within its own process so we can't +    # ps-grep a polkit process, we can ps-grep gnome-shell itself. +      # the [x] thing is to avoid grep match itself      polkit_options = [          'ps aux | grep "polkit-[g]nome-authentication-agent-1"',          'ps aux | grep "polkit-[k]de-authentication-agent-1"',          'ps aux | grep "polkit-[m]ate-authentication-agent-1"', -        'ps aux | grep "[l]xpolkit"' +        'ps aux | grep "[l]xpolkit"', +        'ps aux | grep "[g]nome-shell"',      ]      is_running = [commands.getoutput(cmd) for cmd in polkit_options] -    # gnome-shell does not uses a separate process for the polkit-agent, it -    # uses a polkit-agent within its own process so we can't ps-grep it. -    is_running = any(is_running) -    if not is_running: -        is_gnome_shell = commands.getoutput('ps aux | grep [g]nome-shell') - -        # $DESKTOP_SESSION == 'gnome' -> gnome-shell -        # $DESKTOP_SESSION == 'gnome-fallback' -> gnome-shell fallback mode, -        # uses polkit-gnome... -        if is_gnome_shell and os.getenv("DESKTOP_SESSION") == 'gnome': -            is_running = True - -    return is_running +    return any(is_running)  def _try_to_launch_agent(): diff --git a/src/leap/bitmask/util/__init__.py b/src/leap/bitmask/util/__init__.py index 2b2cd874..c35be99e 100644 --- a/src/leap/bitmask/util/__init__.py +++ b/src/leap/bitmask/util/__init__.py @@ -28,11 +28,6 @@ from leap.common.config import get_path_prefix as common_get_path_prefix  # We'll give your money back if it does not alleviate the eye strain, at least. -# levelname length == 8, since 'CRITICAL' is the longest -LOG_FORMAT = ('%(asctime)s - %(levelname)-8s - ' -              'L#%(lineno)-4s : %(name)s:%(funcName)s() - %(message)s') - -  def first(things):      """      Return the head of a collection. | 
