summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changes/feature_init-check-resolvconf1
-rw-r--r--src/leap/bitmask/app.py105
-rw-r--r--src/leap/bitmask/backend_app.py0
-rw-r--r--src/leap/bitmask/frontend_app.py0
-rw-r--r--src/leap/bitmask/gui/loggerwindow.py2
-rw-r--r--src/leap/bitmask/gui/mainwindow.py2
-rw-r--r--src/leap/bitmask/logs/__init__.py3
-rw-r--r--src/leap/bitmask/logs/leap_log_handler.py (renamed from src/leap/bitmask/util/leap_log_handler.py)2
-rw-r--r--src/leap/bitmask/logs/log_silencer.py (renamed from src/leap/bitmask/util/log_silencer.py)0
-rw-r--r--src/leap/bitmask/logs/streamtologger.py (renamed from src/leap/bitmask/util/streamtologger.py)0
-rw-r--r--src/leap/bitmask/logs/tests/test_leap_log_handler.py (renamed from src/leap/bitmask/util/tests/test_leap_log_handler.py)2
-rw-r--r--src/leap/bitmask/logs/tests/test_streamtologger.py (renamed from src/leap/bitmask/util/tests/test_streamtologger.py)2
-rw-r--r--src/leap/bitmask/logs/utils.py92
-rw-r--r--src/leap/bitmask/platform_init/initializers.py71
-rw-r--r--src/leap/bitmask/services/eip/linuxvpnlauncher.py21
-rw-r--r--src/leap/bitmask/util/__init__.py5
16 files changed, 174 insertions, 134 deletions
diff --git a/changes/feature_init-check-resolvconf b/changes/feature_init-check-resolvconf
new file mode 100644
index 00000000..81733910
--- /dev/null
+++ b/changes/feature_init-check-resolvconf
@@ -0,0 +1 @@
+- Warn user if resolvconf cannot be found.
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.