Example #1
0
def run_backend(bypass_checks=False, flags_dict=None, frontend_pid=None):
    """
    Run the backend for the application.

    :param bypass_checks: whether we should bypass the checks or not
    :type bypass_checks: bool
    :param flags_dict: a dict containing the flag values set on app start.
    :type flags_dict: dict
    """
    # In the backend, we want all the components to log into logbook
    # that is: logging handlers and twisted logs
    from logbook.compat import redirect_logging
    from twisted.python.log import PythonLoggingObserver
    redirect_logging()
    observer = PythonLoggingObserver()
    observer.start()

    # NOTE: this needs to be used here, within the call since this function is
    # executed in a different process and it seems that the process/thread
    # identification isn't working 100%
    logger = get_logger()  # noqa

    # The backend is the one who always creates the certificates. Either if it
    # is run separately or in a process in the same app as the frontend.
    if flags.ZMQ_HAS_CURVE:
        generate_zmq_certificates()

    # ignore SIGINT since app.py takes care of signaling SIGTERM to us.
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGTERM, signal_handler)

    if flags_dict is not None:
        dict_to_flags(flags_dict)

    # HACK we should be able to run the ensure_server anyway but right now it
    # breaks if we run it twice.
    if not flags.STANDALONE:
        # start the events server
        # This is not needed for the standalone bundle since the launcher takes
        # care of it.
        event_server.ensure_server()

    backend = LeapBackend(bypass_checks=bypass_checks,
                          frontend_pid=frontend_pid)
    backend.run()
Example #2
0
def run_backend(bypass_checks=False, flags_dict=None, frontend_pid=None):
    """
    Run the backend for the application.
    This is called from the main app.py entrypoint, and is run in a child
    subprocess.

    :param bypass_checks: whether we should bypass the checks or not
    :type bypass_checks: bool
    :param flags_dict: a dict containing the flag values set on app start.
    :type flags_dict: dict
    """
    # In the backend, we want all the components to log into logbook
    # that is: logging handlers and twisted logs
    from logbook.compat import redirect_logging
    from twisted.python.log import PythonLoggingObserver
    redirect_logging()
    observer = PythonLoggingObserver()
    observer.start()

    if flags_dict is not None:
        dict_to_flags(flags_dict)

    common_flags.STANDALONE = flags.STANDALONE

    # NOTE: this needs to be used here, within the call since this function is
    # executed in a different process and it seems that the process/thread
    # identification isn't working 100%
    logger = get_logger()  # noqa

    # The backend is the one who always creates the certificates. Either if it
    # is run separately or in a process in the same app as the frontend.
    if flags.ZMQ_HAS_CURVE:
        generate_zmq_certificates()

    # ignore SIGINT since app.py takes care of signaling SIGTERM to us.
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGTERM, signal_handler)

    reactor.callWhenRunning(start_events_and_updater, logger)

    backend = LeapBackend(bypass_checks=bypass_checks,
                          frontend_pid=frontend_pid)
    backend.run()
import platform
import stat
import subprocess
import tempfile

from PySide import QtGui, QtCore

from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.services.eip import get_vpn_launcher
from leap.bitmask.services.eip.darwinvpnlauncher import DarwinVPNLauncher
from leap.bitmask.util import first
from leap.bitmask.util.privilege_policies import LinuxPolicyChecker
from leap.bitmask.logs.utils import get_logger

logger = get_logger()

# NOTE we could use a deferToThread here, but should
# be aware of this bug: http://www.themacaque.com/?p=1067

__all__ = ["init_platform"]

_system = platform.system()


class InitSignals(QtCore.QObject):
    """
    Signal container to communicate initialization events to differnt widgets.
    """
    eip_missing_helpers = QtCore.Signal()
Example #4
0
import stat

import zmq

try:
    import zmq.auth
except ImportError:
    pass

from leap.bitmask.config import flags
from leap.bitmask.logs.utils import get_logger
from leap.bitmask.util import get_path_prefix
from leap.common.files import mkdir_p
from leap.common.check import leap_assert

logger = get_logger()


def _get_keys_dir():
    """
    Return the path where the ZMQ certificates should be stored.

    :rtype: str
    """
    return os.path.join(get_path_prefix(), 'leap', 'zmq_certificates')


def _zmq_has_curve():
    """
    Return whether the current ZMQ has support for auth and CurveZMQ security.
Example #5
0
def run_frontend(options, flags_dict, backend_pid=None):
    """
    Run the GUI for the application.

    :param options: a dict of options parsed from the command line.
    :type options: dict
    :param flags_dict: a dict containing the flag values set on app start.
    :type flags_dict: dict
    """
    dict_to_flags(flags_dict)
    logger = get_logger()

    start_hidden = options["start_hidden"]

    # We force the style if on KDE so that it doesn't load all the kde
    # libs, which causes a compatibility issue in some systems.
    # For more info, see issue #3194
    if flags.STANDALONE and os.environ.get("KDE_SESSION_UID") is not None:
        sys.argv.append("-style")
        sys.argv.append("Cleanlooks")

    qApp = QtGui.QApplication(sys.argv)

    # To test the app in other language you can do:
    #     shell> LANG=es bitmask
    # or in some rare case if the code above didn't work:
    #     shell> LC_ALL=es LANG=es bitmask
    locale = QtCore.QLocale.system().name()  # en_US, es_AR, ar_SA, etc
    locale_short = locale[:2]  # en, es, ar, etc
    rtl_languages = ('ar', )  # right now tested on 'arabic' only.

    systemQtTranslator = QtCore.QTranslator()
    if systemQtTranslator.load("qt_%s" % locale, ":/translations"):
        qApp.installTranslator(systemQtTranslator)

    bitmaskQtTranslator = QtCore.QTranslator()
    if bitmaskQtTranslator.load("%s.qm" % locale_short, ":/translations"):
        qApp.installTranslator(bitmaskQtTranslator)

    if locale_short in rtl_languages:
        qApp.setLayoutDirection(QtCore.Qt.LayoutDirection.RightToLeft)

    # Needed for initializing qsettings it will write
    # .config/leap/leap.conf top level app settings in a platform
    # independent way
    qApp.setOrganizationName("leap")
    qApp.setApplicationName("leap")
    qApp.setOrganizationDomain("leap.se")

    # HACK:
    # We need to do some 'python work' once in a while, otherwise, no python
    # code will be called and the Qt event loop will prevent the signal
    # handlers for SIGINT/SIGTERM to be called.
    # see: http://stackoverflow.com/a/4939113/687989
    timer = QtCore.QTimer()
    timer.start(500)  # You may change this if you wish.
    timer.timeout.connect(lambda: None)  # Let the interpreter run each 500 ms.

    window = MainWindow(start_hidden=start_hidden, backend_pid=backend_pid)

    my_pid = os.getpid()
    sig_handler = partial(signal_handler, window, my_pid, logger)
    signal.signal(signal.SIGINT, sig_handler)
    signal.signal(signal.SIGTERM, sig_handler)

    sys.exit(qApp.exec_())
Example #6
0
def start_app():
    """
    Starts the main event loop and launches the main window.
    """
    qt_hack_ubuntu()

    # Ignore the signals since we handle them in the subprocesses
    # signal.signal(signal.SIGINT, signal.SIG_IGN)

    # Parse arguments and store them
    opts = leap_argparse.get_options()
    do_display_version(opts)

    options = {
        'start_hidden': opts.start_hidden,
        'debug': opts.debug,
    }

    flags.STANDALONE = opts.standalone

    if platform.system() != 'Darwin':
        # XXX this hangs the OSX bundles.
        if getattr(sys, 'frozen', False):
            flags.STANDALONE = True

    flags.OFFLINE = opts.offline
    flags.MAIL_LOGFILE = opts.mail_log_file
    flags.APP_VERSION_CHECK = opts.app_version_check
    flags.API_VERSION_CHECK = opts.api_version_check
    flags.OPENVPN_VERBOSITY = opts.openvpn_verb
    flags.SKIP_WIZARD_CHECKS = opts.skip_wizard_checks

    flags.CA_CERT_FILE = opts.ca_cert_file

    flags.DEBUG = opts.debug

    common_flags.STANDALONE = flags.STANDALONE

    logger = get_logger(perform_rollover=True)

    # NOTE: since we are not using this right now, the code that replaces the
    # stdout needs to be reviewed when we enable this again
    # replace_stdout = True

    # XXX mail repair commands disabled for now
    # 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

    # 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.
    # XXX mail repair commands disabled for now
    # do_mail_plumbing(opts)

    PLAY_NICE = os.environ.get("LEAP_NICE")
    if PLAY_NICE and PLAY_NICE.isdigit():
        nice = os.nice(int(PLAY_NICE))
        logger.info("Setting NICE: %s" % nice)

    # TODO move to a different module: commands?
    if not we_are_the_one_and_only():
        # Bitmask is already running
        logger.warning("Tried to launch more than one instance "
                       "of Bitmask. Raising the existing "
                       "one instead.")
        sys.exit(1)

    check_requirements()

    logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    logger.info('Bitmask version %s' % VERSION)
    logger.info('leap.mail version %s' % MAIL_VERSION)
    log_lsb_release_info(logger)
    logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    logger.info('Starting app')

    backend_running = BackendProxy().check_online()
    logger.debug("Backend online: {0}".format(backend_running))

    flags_dict = flags_to_dict()

    backend_pid = None
    if not backend_running:
        frontend_pid = os.getpid()
        backend_process = multiprocessing.Process(target=run_backend,
                                                  name='Backend',
                                                  args=(opts.danger,
                                                        flags_dict,
                                                        frontend_pid))
        # we don't set the 'daemon mode' since we need to start child processes
        # in the backend
        # backend_process.daemon = True
        backend_process.start()
        backend_pid = backend_process.pid

    fix_qtplugins_path()
    run_frontend(options, flags_dict, backend_pid=backend_pid)
Example #7
0
def start_app():
    """
    Starts the main event loop and launches the main window.
    """
    # Ignore the signals since we handle them in the subprocesses
    # signal.signal(signal.SIGINT, signal.SIG_IGN)

    # Parse arguments and store them
    opts = leap_argparse.get_options()
    do_display_version(opts)

    options = {
        'start_hidden': opts.start_hidden,
        'debug': opts.debug,
    }

    flags.STANDALONE = opts.standalone
    flags.OFFLINE = opts.offline
    flags.MAIL_LOGFILE = opts.mail_log_file
    flags.APP_VERSION_CHECK = opts.app_version_check
    flags.API_VERSION_CHECK = opts.api_version_check
    flags.OPENVPN_VERBOSITY = opts.openvpn_verb
    flags.SKIP_WIZARD_CHECKS = opts.skip_wizard_checks

    flags.CA_CERT_FILE = opts.ca_cert_file

    flags.DEBUG = opts.debug

    common_flags.STANDALONE = flags.STANDALONE

    logger = get_logger(perform_rollover=True)

    # NOTE: since we are not using this right now, the code that replaces the
    # stdout needs to be reviewed when we enable this again
    # replace_stdout = True

    # XXX mail repair commands disabled for now
    # 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

    # 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.
    # XXX mail repair commands disabled for now
    # do_mail_plumbing(opts)

    PLAY_NICE = os.environ.get("LEAP_NICE")
    if PLAY_NICE and PLAY_NICE.isdigit():
        nice = os.nice(int(PLAY_NICE))
        logger.info("Setting NICE: %s" % nice)

    # TODO move to a different module: commands?
    if not we_are_the_one_and_only():
        # Bitmask is already running
        logger.warning("Tried to launch more than one instance "
                       "of Bitmask. Raising the existing "
                       "one instead.")
        sys.exit(1)

    check_requirements()

    logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    logger.info('Bitmask version %s' % VERSION)
    logger.info('leap.mail version %s' % MAIL_VERSION)
    log_lsb_release_info(logger)
    logger.info('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    logger.info('Starting app')

    backend_running = BackendProxy().check_online()
    logger.debug("Backend online: {0}".format(backend_running))

    flags_dict = flags_to_dict()

    backend_pid = None
    if not backend_running:
        frontend_pid = os.getpid()
        backend = lambda: run_backend(opts.danger, flags_dict, frontend_pid)
        backend_process = multiprocessing.Process(target=backend,
                                                  name='Backend')
        # we don't set the 'daemon mode' since we need to start child processes
        # in the backend
        # backend_process.daemon = True
        backend_process.start()
        backend_pid = backend_process.pid

    fix_qtplugins_path()
    run_frontend(options, flags_dict, backend_pid=backend_pid)