summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/leap/bitmask/app.py11
-rw-r--r--src/leap/bitmask/config/providerconfig.py10
-rw-r--r--src/leap/bitmask/gui/mainwindow.py88
-rw-r--r--src/leap/bitmask/gui/ui/wizard.ui93
-rw-r--r--src/leap/bitmask/gui/wizard.py3
-rw-r--r--src/leap/bitmask/services/__init__.py10
-rw-r--r--src/leap/bitmask/services/eip/eipconfig.py2
-rw-r--r--src/leap/bitmask/services/eip/vpnlaunchers.py39
-rw-r--r--src/leap/bitmask/util/leap_log_handler.py3
-rw-r--r--src/leap/bitmask/util/log_silencer.py95
10 files changed, 212 insertions, 142 deletions
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 7ee54342..49edc8eb 100644
--- a/src/leap/bitmask/services/eip/vpnlaunchers.py
+++ b/src/leap/bitmask/services/eip/vpnlaunchers.py
@@ -431,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']
@@ -679,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']
@@ -851,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