Esempio n. 1
0
    def __init__(self):
        """
        Initializes smtp variables.
        """
        self.smtp_config = SMTPConfig()
        self.smtp_connection = None
        self.smtp_machine = None
        self._smtp_service = None
        self._smtp_port = None

        self.smtp_bootstrapper = SMTPBootstrapper()
        self.smtp_bootstrapper.download_config.connect(
            self.smtp_bootstrapped_stage)

        leap_register(signal=leap_events.SMTP_SERVICE_STARTED,
                      callback=self._handle_smtp_events,
                      reqcbk=lambda req, resp: None)
        leap_register(signal=leap_events.SMTP_SERVICE_FAILED_TO_START,
                      callback=self._handle_smtp_events,
                      reqcbk=lambda req, resp: None)
    def __init__(self, soledad_proxy, keymanager_proxy, signaler=None):
        """
        Constructor for the Mail component.

        :param soledad_proxy: proxy to pass around a Soledad object.
        :type soledad_proxy: zope.ProxyBase
        :param keymanager_proxy: proxy to pass around a Keymanager object.
        :type keymanager_proxy: zope.ProxyBase
        :param signaler: Object in charge of handling communication
                         back to the frontend
        :type signaler: Signaler
        """
        self.key = "mail"
        self._signaler = signaler
        self._soledad_proxy = soledad_proxy
        self._keymanager_proxy = keymanager_proxy
        self._imap_controller = IMAPController(self._soledad_proxy,
                                               self._keymanager_proxy)
        self._smtp_bootstrapper = SMTPBootstrapper()
        self._smtp_config = SMTPConfig()
Esempio n. 3
0
class SMTPControl(object):

    PORT_KEY = "port"
    IP_KEY = "ip_address"

    def __init__(self):
        """
        Initializes smtp variables.
        """
        self.smtp_config = SMTPConfig()
        self.smtp_connection = None
        self.smtp_machine = None
        self._smtp_service = None
        self._smtp_port = None

        self.smtp_bootstrapper = SMTPBootstrapper()
        self.smtp_bootstrapper.download_config.connect(
            self.smtp_bootstrapped_stage)

        leap_register(signal=leap_events.SMTP_SERVICE_STARTED,
                      callback=self._handle_smtp_events,
                      reqcbk=lambda req, resp: None)
        leap_register(signal=leap_events.SMTP_SERVICE_FAILED_TO_START,
                      callback=self._handle_smtp_events,
                      reqcbk=lambda req, resp: None)

    def set_smtp_connection(self, smtp_connection):
        """
        Sets the smtp connection to an initialized connection.
        :param smtp_connection: an initialized smtp connection
        :type smtp_connection: SMTPConnection instance.
        """
        self.smtp_connection = smtp_connection

    def start_smtp_service(self, host, port, cert):
        """
        Starts the smtp service.

        :param host: the hostname of the remove SMTP server.
        :type host: str
        :param port: the port of the remote SMTP server
        :type port: str
        :param cert: the client certificate for authentication
        :type cert: str
        """
        # 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.
        self.smtp_connection.qtsigs.connecting_signal.emit()
        from leap.mail.smtp import setup_smtp_gateway
        self._smtp_service, self._smtp_port = setup_smtp_gateway(
            port=2013,
            userid=self.userid,
            keymanager=self._keymanager,
            smtp_host=host,
            smtp_port=port,
            smtp_cert=cert,
            smtp_key=cert,
            encrypted_only=False)

    def stop_smtp_service(self):
        """
        Stops the smtp service (port and factory).
        """
        self.smtp_connection.qtsigs.disconnecting_signal.emit()
        # TODO We should homogenize both services.
        if self._smtp_service is not None:
            logger.debug('Stopping smtp service.')
            self._smtp_port.stopListening()
            self._smtp_service.doStop()

    @QtCore.Slot()
    def smtp_bootstrapped_stage(self, data):
        """
        SLOT
        TRIGGERS:
          self.smtp_bootstrapper.download_config

        If there was a problem, displays it, otherwise it does nothing.
        This is used for intermediate bootstrapping stages, in case
        they fail.

        :param data: result from the bootstrapping stage for Soledad
        :type data: dict
        """
        passed = data[self.smtp_bootstrapper.PASSED_KEY]
        if not passed:
            logger.error(data[self.smtp_bootstrapper.ERROR_KEY])
            return
        logger.debug("Done bootstrapping SMTP")
        self.check_smtp_config()

    def check_smtp_config(self):
        """
        Checks smtp config and tries to download smtp client cert if needed.
        Currently called when smtp_bootstrapped_stage has successfuly finished.
        """
        logger.debug("Checking SMTP config...")
        leap_assert(self.smtp_bootstrapper._provider_config,
                    "smtp bootstrapper does not have a provider_config")

        provider_config = self.smtp_bootstrapper._provider_config
        smtp_config = self.smtp_config
        hosts = smtp_config.get_hosts()
        # 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]

            client_cert = smtp_config.get_client_cert_path(
                provider_config,
                about_to_download=True)

            # XXX change this logic!
            # check_config should be called from within start_service,
            # and not the other way around.
            if not is_file(client_cert):
                self.smtp_bootstrapper._download_client_certificates()
            if os.path.isfile(client_cert):
                self.start_smtp_service(host, port, client_cert)
            else:
                logger.warning("Tried to download email client "
                               "certificate, but could not find any")

        else:
            logger.warning("No smtp hosts configured")

    # handle smtp events

    def _handle_smtp_events(self, req):
        """
        Callback handler for the SMTP events.

        :param req: Request type
        :type req: leap.common.events.events_pb2.SignalRequest
        """
        if req.event == leap_events.SMTP_SERVICE_STARTED:
            self.on_smtp_connected()
        elif req.event == leap_events.SMTP_SERVICE_FAILED_TO_START:
            self.on_smtp_failed()

    # emit connection signals

    def on_smtp_connecting(self):
        """
        Callback for SMTP connecting state.
        """
        self.smtp_connection.qtsigs.connecting_signal.emit()

    def on_smtp_connected(self):
        """
        Callback for SMTP connected state.
        """
        self.smtp_connection.qtsigs.connected_signal.emit()

    def on_smtp_failed(self):
        """
        Callback for SMTP failed state.
        """
        self.smtp_connection.qtsigs.connection_aborted_signal.emit()