diff options
22 files changed, 292 insertions, 160 deletions
@@ -686,12 +686,6 @@ License: GNU General Public License - http://en.wikipedia.org/wiki/GNU_General_P WebSite: http://wefunction.com/ IconPackage: WooFunction icon pack - http://www.iconspedia.com/pack/woofunction-icons-4136/ --- -data/images/Globe.png - -Author: Everaldo Coelho -License: LGPL - http://www.gnu.org/licenses/lgpl.html -WebSite: http://www.everaldo.com/ ---- data/images/oxygen-icons/ The following icons were created based on 'mail-unread.png' from oxygen: diff --git a/changes/VERSION_COMPAT b/changes/VERSION_COMPAT index 32391745..cd6e4ef1 100644 --- a/changes/VERSION_COMPAT +++ b/changes/VERSION_COMPAT @@ -3,8 +3,15 @@ # introduced in internal leap dependencies. # Add your changes here so we can properly update # requirements.pip during the release process. +# (leave header when resetting) ################################################# +# +# BEGIN DEPENDENCY LIST ------------------------- +# leap.foo.bar>=x.y.z leap.common>=0.3.2 # leap.common.config.get_path_prefix +# +leap.mail>=0.3.2 +# smtp returns factory diff --git a/changes/bug-3595_fix-gateway-selection-problem b/changes/bug-3595_fix-gateway-selection-problem new file mode 100644 index 00000000..7225eed0 --- /dev/null +++ b/changes/bug-3595_fix-gateway-selection-problem @@ -0,0 +1 @@ + o Fix gateway selection problem. Closes 3595. diff --git a/changes/bug-3657_display-correct-service-name-in-wiard b/changes/bug-3657_display-correct-service-name-in-wiard new file mode 100644 index 00000000..4fe3d0b1 --- /dev/null +++ b/changes/bug-3657_display-correct-service-name-in-wiard @@ -0,0 +1 @@ + o Display Encrypted Mail instead of mx in wizard. Closes #3657. diff --git a/changes/bug_3553_logout-stop-mail b/changes/bug_3553_logout-stop-mail new file mode 100644 index 00000000..ee898137 --- /dev/null +++ b/changes/bug_3553_logout-stop-mail @@ -0,0 +1 @@ + o Logout stops imap and smtp services. Closes: #3553 diff --git a/changes/bug_3554_fix-polkit-auth-agent b/changes/bug_3554_fix-polkit-auth-agent new file mode 100644 index 00000000..9498868b --- /dev/null +++ b/changes/bug_3554_fix-polkit-auth-agent @@ -0,0 +1 @@ + o Properly daemonize polkit-gnome-authentication-agent. Closes: #3554 diff --git a/changes/bug_3615-wizard-typo b/changes/bug_3615-wizard-typo new file mode 100644 index 00000000..89e18174 --- /dev/null +++ b/changes/bug_3615-wizard-typo @@ -0,0 +1 @@ + o Fix typo in wizard: stablish -> establish. Closes #3615. diff --git a/changes/feature-3616_remove-last-page-from-wizard b/changes/feature-3616_remove-last-page-from-wizard new file mode 100644 index 00000000..cc02c02c --- /dev/null +++ b/changes/feature-3616_remove-last-page-from-wizard @@ -0,0 +1 @@ + o Remove last page from wizard. Closes #3616. diff --git a/changes/feature_3504_add_log_silencer b/changes/feature_3504_add_log_silencer new file mode 100644 index 00000000..7c551162 --- /dev/null +++ b/changes/feature_3504_add_log_silencer @@ -0,0 +1 @@ + o Allow to selectively silence logs from different leap components. Closes: #3504 diff --git a/data/images/Globe.png b/data/images/Globe.png Binary files differdeleted file mode 100644 index 7549433b..00000000 --- a/data/images/Globe.png +++ /dev/null diff --git a/pkg/requirements.pip b/pkg/requirements.pip index e04127b7..7d0f79af 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -16,6 +16,7 @@ ipaddr twisted qt4reactor python-gnupg +python-daemon # this should not be needed for Windows. leap.common>=0.3.0 leap.soledad.client>=0.3.0 diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 6ffa1d25..0dce5e61 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -25,6 +25,7 @@ from functools import partial from PySide import QtCore, QtGui from leap.bitmask.util import leap_argparse +from leap.bitmask.util import log_silencer from leap.bitmask.util.leap_log_handler import LeapLogHandler from leap.bitmask.util.streamtologger import StreamToLogger from leap.common.events import server as event_server @@ -51,7 +52,7 @@ def install_qtreactor(logger): logger.debug("Qt4 reactor installed") -def add_logger_handlers(debug=False, logfile=None): +def add_logger_handlers(debug=False, logfile=None, standalone=False): """ Create the logger and attach the handlers. @@ -71,6 +72,7 @@ def add_logger_handlers(debug=False, logfile=None): # Create logger and formatter logger = logging.getLogger(name='leap') logger.setLevel(level) + log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' formatter = logging.Formatter(log_format) @@ -78,12 +80,16 @@ def add_logger_handlers(debug=False, logfile=None): console = logging.StreamHandler() console.setLevel(level) console.setFormatter(formatter) + + silencer = log_silencer.SelectiveSilencerFilter(standalone=standalone) + 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!') @@ -93,6 +99,7 @@ def add_logger_handlers(debug=False, logfile=None): fileh = logging.FileHandler(logfile) fileh.setLevel(logging.DEBUG) fileh.setFormatter(formatter) + fileh.addFilter(silencer) logger.addHandler(fileh) logger.debug('File handler plugged!') @@ -155,7 +162,7 @@ def main(): # pylint: avoid unused import assert(locale_rc) - logger = add_logger_handlers(debug, logfile) + logger = add_logger_handlers(debug, logfile, standalone) replace_stdout_stderr_with_logging(logger) if not we_are_the_one_and_only(): diff --git a/src/leap/bitmask/config/providerconfig.py b/src/leap/bitmask/config/providerconfig.py index c65932be..a7808399 100644 --- a/src/leap/bitmask/config/providerconfig.py +++ b/src/leap/bitmask/config/providerconfig.py @@ -24,6 +24,7 @@ import os from leap.bitmask.config.provider_spec import leap_provider_spec from leap.common.check import leap_check from leap.common.config.baseconfig import BaseConfig, LocalizedKey +from leap.bitmask.services import get_service_display_name logger = logging.getLogger(__name__) @@ -130,9 +131,11 @@ class ProviderConfig(BaseConfig): Returns a string with the available services in the current provider, ready to be shown to the user. """ - services_str = ", ".join(self.get_services()) - services_str = services_str.replace( - "openvpn", "Encrypted Internet") + services = [] + for service in self.get_services(): + services.append(get_service_display_name(service)) + + services_str = ", ".join(services) return services_str def get_ca_cert_path(self, about_to_download=False): @@ -216,3 +219,4 @@ if __name__ == "__main__": print provider.get_languages() print provider.get_name() print provider.get_services() + print provider.get_services_string() diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 6d612d4e..7a94fd0f 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -14,9 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. - """ -Main window for the leap client +Main window for Bitmask. """ import logging import os @@ -102,6 +101,7 @@ class MainWindow(QtGui.QMainWindow): raise_window = QtCore.Signal([]) soledad_ready = QtCore.Signal([]) mail_client_logged_in = QtCore.Signal([]) + logout = QtCore.Signal([]) # We use this flag to detect abnormal terminations user_stopped_eip = False @@ -286,6 +286,8 @@ class MainWindow(QtGui.QMainWindow): self.soledad_ready.connect(self._start_imap_service) self.soledad_ready.connect(self._set_soledad_ready) self.mail_client_logged_in.connect(self._fetch_incoming_mail) + self.logout.connect(self._stop_imap_service) + self.logout.connect(self._stop_smtp_service) ################################# end Qt Signals connection ######## @@ -301,6 +303,7 @@ class MainWindow(QtGui.QMainWindow): self._soledad = None self._soledad_ready = False self._keymanager = None + self._smtp_service = None self._imap_service = None self._login_defer = None @@ -909,7 +912,7 @@ class MainWindow(QtGui.QMainWindow): self._srp_auth.logout_finished.connect( self._done_logging_out) - # TODO: Add errback! + # TODO Add errback! self._login_defer = self._srp_auth.authenticate(username, password) else: self._login_widget.set_status( @@ -976,7 +979,7 @@ class MainWindow(QtGui.QMainWindow): """ passed = data[self._soledad_bootstrapper.PASSED_KEY] if not passed: - # TODO: display in the GUI: + # TODO display in the GUI: # should pass signal to a slot in status_panel # that sets the global status logger.error("Soledad failed to start: %s" % @@ -1037,13 +1040,13 @@ class MainWindow(QtGui.QMainWindow): True) else: if self._enabled_services.count(self.MX_SERVICE) > 0: - pass # TODO: show MX status + pass # TODO show MX status #self._status_panel.set_eip_status( # self.tr("%s does not support MX") % # (self._provider_config.get_domain(),), # error=True) else: - pass # TODO: show MX status + pass # TODO show MX status #self._status_panel.set_eip_status( # self.tr("MX is disabled")) @@ -1070,25 +1073,43 @@ class MainWindow(QtGui.QMainWindow): logger.debug("Done bootstrapping SMTP") hosts = self._smtp_config.get_hosts() - # TODO: handle more than one host and define how to choose + # TODO handle more than one host and define how to choose if len(hosts) > 0: hostname = hosts.keys()[0] logger.debug("Using hostname %s for SMTP" % (hostname,)) host = hosts[hostname][self.IP_KEY].encode("utf-8") port = hosts[hostname][self.PORT_KEY] - # TODO: pick local smtp port in a better way - # TODO: Make the encrypted_only configurable + # TODO move the start to _start_smtp_service + + # TODO Make the encrypted_only configurable + # TODO pick local smtp port in a better way + # TODO remove hard-coded port and let leap.mail set + # the specific default. from leap.mail.smtp import setup_smtp_relay client_cert = self._eip_config.get_client_cert_path( self._provider_config) - setup_smtp_relay(port=2013, - keymanager=self._keymanager, - smtp_host=host, - smtp_port=port, - smtp_cert=client_cert, - smtp_key=client_cert, - encrypted_only=False) + self._smtp_service = setup_smtp_relay( + port=2013, + keymanager=self._keymanager, + smtp_host=host, + smtp_port=port, + smtp_cert=client_cert, + smtp_key=client_cert, + encrypted_only=False) + + def _stop_smtp_service(self): + """ + SLOT + TRIGGERS: + self.logout + """ + # There is a subtle difference here: + # we are stopping the factory for the smtp service here, + # but in the imap case we are just stopping the fetcher. + if self._smtp_service is not None: + logger.debug('Stopping smtp service.') + self._smtp_service.doStop() ################################################################### # Service control methods: imap @@ -1097,7 +1118,7 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - soledad_ready + self.soledad_ready """ if self._provider_config.provides_mx() and \ self._enabled_services.count(self.MX_SERVICE) > 0: @@ -1106,17 +1127,6 @@ class MainWindow(QtGui.QMainWindow): self._imap_service = imap.start_imap_service( self._soledad, self._keymanager) - else: - if self._enabled_services.count(self.MX_SERVICE) > 0: - pass # TODO: show MX status - #self._status_panel.set_eip_status( - # self.tr("%s does not support MX") % - # (self._provider_config.get_domain(),), - # error=True) - else: - pass # TODO: show MX status - #self._status_panel.set_eip_status( - # self.tr("MX is disabled")) def _on_mail_client_logged_in(self, req): """ @@ -1128,13 +1138,27 @@ class MainWindow(QtGui.QMainWindow): """ SLOT TRIGGERS: - mail_client_logged_in + self.mail_client_logged_in """ # TODO have a mutex over fetch operation. if self._imap_service: logger.debug('Client connected, fetching mail...') self._imap_service.fetch() + def _stop_imap_service(self): + """ + SLOT + TRIGGERS: + self.logout + """ + # There is a subtle difference here: + # we are just stopping the fetcher here, + # but in the smtp case we are stopping the factory. + # We should homogenize both services. + if self._imap_service is not None: + logger.debug('Stopping imap service.') + self._imap_service.stop() + # end service control methods (imap) ################################################################### @@ -1146,7 +1170,8 @@ class MainWindow(QtGui.QMainWindow): :rtype: tuple (str, str) (host, port) """ - # TODO: make this properly multiplatform + # TODO make this properly multiplatform + # TODO get this out of gui/ if platform.system() == "Windows": host = "localhost" @@ -1399,6 +1424,7 @@ class MainWindow(QtGui.QMainWindow): # XXX: If other defers are doing authenticated stuff, this # might conflict with those. CHECK! threads.deferToThread(self._srp_auth.logout) + self.logout.emit() def _done_logging_out(self, ok, message): """ @@ -1573,7 +1599,7 @@ class MainWindow(QtGui.QMainWindow): """ Cleanup and tidely close the main window before quitting. """ - # TODO: separate the shutting down of services from the + # TODO separate the shutting down of services from the # UI stuff. self._cleanup_and_quit() diff --git a/src/leap/bitmask/gui/ui/wizard.ui b/src/leap/bitmask/gui/ui/wizard.ui index 3b8f1215..2a412784 100644 --- a/src/leap/bitmask/gui/ui/wizard.ui +++ b/src/leap/bitmask/gui/ui/wizard.ui @@ -183,7 +183,7 @@ <item row="2" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> - <string>Can we stablish a secure connection?</string> + <string>Can we establish a secure connection?</string> </property> </widget> </item> @@ -740,97 +740,6 @@ </item> </layout> </widget> - <widget class="QWizardPage" name="finish_page"> - <property name="title"> - <string>Congratulations!</string> - </property> - <property name="subTitle"> - <string>You have successfully configured Bitmask.</string> - </property> - <attribute name="pageId"> - <string notr="true">6</string> - </attribute> - <layout class="QGridLayout" name="gridLayout_10"> - <item row="1" column="0"> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="1"> - <spacer name="verticalSpacer_9"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="label_23"> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/mask-icon.png</pixmap> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QLabel" name="label_25"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - <property name="pixmap"> - <pixmap resource="../../../../../data/resources/mainwindow.qrc">:/images/Globe.png</pixmap> - </property> - </widget> - </item> - <item row="3" column="1"> - <spacer name="verticalSpacer_10"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>40</height> - </size> - </property> - </spacer> - </item> - <item row="1" column="3"> - <spacer name="horizontalSpacer_5"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> </widget> <customwidgets> <customwidget> diff --git a/src/leap/bitmask/gui/wizard.py b/src/leap/bitmask/gui/wizard.py index ac0f032f..e004e6cf 100644 --- a/src/leap/bitmask/gui/wizard.py +++ b/src/leap/bitmask/gui/wizard.py @@ -52,7 +52,6 @@ class Wizard(QtGui.QWizard): SETUP_PROVIDER_PAGE = 3 REGISTER_USER_PAGE = 4 SERVICES_PAGE = 5 - FINISH_PAGE = 6 WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") @@ -144,7 +143,7 @@ class Wizard(QtGui.QWizard): self.page(self.REGISTER_USER_PAGE).setButtonText( QtGui.QWizard.CommitButton, self.tr("&Next >")) - self.page(self.FINISH_PAGE).setButtonText( + self.page(self.SERVICES_PAGE).setButtonText( QtGui.QWizard.FinishButton, self.tr("Connect")) # XXX: Temporary removal for enrollment policy diff --git a/src/leap/bitmask/services/__init__.py b/src/leap/bitmask/services/__init__.py index 924ca547..339f9cc6 100644 --- a/src/leap/bitmask/services/__init__.py +++ b/src/leap/bitmask/services/__init__.py @@ -26,6 +26,8 @@ DEPLOYED = ["openvpn", "mx"] def get_service_display_name(service, standalone=False): """ Returns the name to display of the given service. + If there is no configured name for that service, then returns the same + parameter :param service: the 'machine' service name :type service: str @@ -42,8 +44,10 @@ def get_service_display_name(service, standalone=False): EIP_LABEL = _tr("Encrypted Internet") MX_LABEL = _tr("Encrypted Mail") - service_display = [EIP_LABEL, MX_LABEL] - service_config = ["openvpn", "mx"] + service_display = { + "openvpn": EIP_LABEL, + "mx": MX_LABEL + } # If we need to add a warning about eip needing # administrative permissions to start. That can be either @@ -52,7 +56,7 @@ def get_service_display_name(service, standalone=False): if standalone or is_missing_policy_permissions(): EIP_LABEL += " " + _tr("(will need admin password to start)") - return service_display[service_config.index(service)] + return service_display.get(service, service) def get_supported(services): diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py index 1f49f9cd..1cb7419e 100644 --- a/src/leap/bitmask/services/eip/eipconfig.py +++ b/src/leap/bitmask/services/eip/eipconfig.py @@ -141,7 +141,7 @@ class VPNGatewaySelector(object): if time.daylight: local_offset = time.altzone - return local_offset / 3600 + return -local_offset / 3600 class EIPConfig(BaseConfig): diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py index 5921882b..49edc8eb 100644 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ b/src/leap/bitmask/services/eip/vpnlaunchers.py @@ -23,8 +23,8 @@ import logging import getpass import os import platform -import subprocess import stat +import subprocess try: import grp except ImportError: @@ -34,6 +34,7 @@ from abc import ABCMeta, abstractmethod from functools import partial from leap.bitmask.config.leapsettings import LeapSettings + from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector from leap.bitmask.util import first @@ -218,19 +219,19 @@ def _is_auth_agent_running(): return any(is_running) -def _try_to_launch_agent(): +def _try_to_launch_agent(standalone=False): """ Tries to launch a polkit daemon. """ - opts = [ - "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1", - # XXX add kde thing here - ] - for cmd in opts: - try: - subprocess.Popen([cmd], shell=True) - except: - pass + env = None + if standalone is True: + env = { + "PYTHONPATH": os.path.abspath('../../../../lib/')} + try: + subprocess.call(["python", "-m", "leap.bitmask.util.polkit_agent"], + shell=True, env=env) + except Exception as exc: + logger.exception(exc) class LinuxVPNLauncher(VPNLauncher): @@ -314,7 +315,7 @@ class LinuxVPNLauncher(VPNLauncher): """ if _is_pkexec_in_system(): if not _is_auth_agent_running(): - _try_to_launch_agent() + _try_to_launch_agent(ProviderConfig.standalone) if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) leap_assert(len(pkexec_possibilities) > 0, @@ -430,7 +431,7 @@ class LinuxVPNLauncher(VPNLauncher): logger.error('No gateway was found!') raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] @@ -678,11 +679,22 @@ class DarwinVPNLauncher(VPNLauncher): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() + gateways = [] + leap_settings = LeapSettings(ProviderConfig.standalone) + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] + + if not gateways: + logger.error('No gateway was found!') + raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {gw}".format( - gw=', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] @@ -850,10 +862,22 @@ class WindowsVPNLauncher(VPNLauncher): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() + gateways = [] + leap_settings = LeapSettings(ProviderConfig.standalone) + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] + + if not gateways: + logger.error('No gateway was found!') + raise VPNLauncherException(self.tr('No gateway was found!')) - logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] diff --git a/src/leap/bitmask/util/leap_log_handler.py b/src/leap/bitmask/util/leap_log_handler.py index 9adb21a5..98924c12 100644 --- a/src/leap/bitmask/util/leap_log_handler.py +++ b/src/leap/bitmask/util/leap_log_handler.py @@ -90,6 +90,9 @@ class HandlerAdapter(object): def setLevel(self, *args, **kwargs): return self._handler.setLevel(*args, **kwargs) + def addFilter(self, *args, **kwargs): + return self._handler.addFilter(*args, **kwargs) + def handle(self, *args, **kwargs): return self._handler.handle(*args, **kwargs) diff --git a/src/leap/bitmask/util/log_silencer.py b/src/leap/bitmask/util/log_silencer.py new file mode 100644 index 00000000..09aa2cff --- /dev/null +++ b/src/leap/bitmask/util/log_silencer.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# log_silencer.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +Filter for leap logs. +""" +import logging +import os +import re + +from leap.common.config import get_path_prefix + + +class SelectiveSilencerFilter(logging.Filter): + """ + Configurable filter for root leap logger. + + If you want to ignore components from the logging, just add them, + one by line, to ~/.config/leap/leap.dev.conf + """ + # TODO we can augment this by properly parsing the log-silencer file + # and having different sections: ignore, levels, ... + + # TODO use ConfigParser to unify sections [log-ignore] [log-debug] etc + + CONFIG_NAME = "leap.dev.conf" + + # Components to be completely silenced in the main bitmask logs. + # You probably should think twice before adding a component to + # the tuple below. Only very well tested components should go here, and + # only in those cases in which we gain more from silencing them than from + # having their logs into the main log file that the user will likely send + # to us. + SILENCER_RULES = ( + 'leap.common.events', + ) + + def __init__(self, standalone=False): + """ + Tries to load silencer rules from the default path, + or load from the SILENCER_RULES tuple if not found. + """ + self.standalone = standalone + self.rules = None + if os.path.isfile(self._rules_path): + self.rules = self._load_rules() + if not self.rules: + self.rules = self.SILENCER_RULES + + @property + def _rules_path(self): + """ + The configuration file for custom ignore rules. + """ + return os.path.join( + get_path_prefix(standalone=self.standalone), + "leap", self.CONFIG_NAME) + + def _load_rules(self): + """ + Loads a list of paths to be ignored from the logging. + """ + lines = open(self._rules_path).readlines() + return map(lambda line: re.sub('\s', '', line), + lines) + + def filter(self, record): + """ + Implements the filter functionality for this Filter + + :param record: the record to be examined + :type record: logging.LogRecord + :returns: a bool indicating whether the record should be logged or not. + :rtype: bool + """ + if not self.rules: + return True + logger_path = record.name + for path in self.rules: + if logger_path.startswith(path): + return False + return True diff --git a/src/leap/bitmask/util/polkit_agent.py b/src/leap/bitmask/util/polkit_agent.py new file mode 100644 index 00000000..a4650273 --- /dev/null +++ b/src/leap/bitmask/util/polkit_agent.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# polkit_agent.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +Daemonizes polkit authentication agent. +""" +import logging +import subprocess + +import daemon + +logger = logging.getLogger(__name__) + +BASE_PATH = "/usr/lib/policykit-1-gnome/"\ + + "polkit-%s-authentication-agent-1" + +GNOME_PATH = BASE_PATH % ("gnome",) +KDE_PATH = BASE_PATH % ("kde",) + + +def _launch_agent(): + logger.debug('Launching polkit auth agent') + print "launching polkit" + try: + subprocess.call(GNOME_PATH) + except Exception as exc: + try: + subprocess.call(KDE_PATH) + except Exception as exc: + logger.error('Exception while running polkit authentication agent ' + '%s' % (exc,)) + + +def launch(): + with daemon.DaemonContext(): + _launch_agent() + +if __name__ == "__main__": + launch() |