Beispiel #1
0
    def _connect(self):
        with self._lock:
            if self._pop3:
                try:
                    self._pop3.noop()
                    return
                except poplib.error_proto:
                    self._pop3 = None

            with ConnBroker.context(need=[ConnBroker.OUTGOING_POP3]):
                if self.conn_cls:
                    self._pop3 = self.conn_cls(self.host, self.port or 110)
                    self.secure = self.use_ssl
                elif self.use_ssl:
                    self._pop3 = poplib.POP3_SSL(self.host, self.port or 995)
                    self.secure = True
                else:
                    self._pop3 = poplib.POP3(self.host, self.port or 110)
                    self.secure = False

            if self.debug:
                self._pop3.set_debuglevel(self.debug)

            self._keys = None
            try:
                self._pop3.user(self.user)
                self._pop3.pass_(self.password)
            except poplib.error_proto:
                raise AccessError()
Beispiel #2
0
    def command(self):
        key_files = self.data.get("key_file", []) + [a for a in self.args
                                                     if not '://' in a]
        key_urls = self.data.get("key_url", []) + [a for a in self.args
                                                   if '://' in a]
        key_data = []
        key_data.extend(self.data.get("key_data", []))
        for key_file in key_files:
            with open(key_file) as file:
                key_data.append(file.read())
        for key_url in key_urls:
            with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
                uo = urllib2.urlopen(key_url)
            key_data.append(uo.read())

        rv = self._gnupg().import_keys('\n'.join(key_data))

        # Previous crypto evaluations may now be out of date, so we
        # clear the cache so users can see results right away.
        ClearParseCache(pgpmime=True)

        # Update the VCards!
        PGPKeysImportAsVCards(self.session,
                              arg=([i['fingerprint'] for i in rv['updated']] +
                                   [i['fingerprint'] for i in rv['imported']])
                              ).run()

        return self._success(_("Imported %d keys") % len(key_data), rv)
Beispiel #3
0
    def command(self):
        key_files = self.data.get("key_file", []) + [a for a in self.args
                                                     if not '://' in a]
        key_urls = self.data.get("key_url", []) + [a for a in self.args
                                                   if '://' in a]
        key_data = []
        key_data.extend(self.data.get("key_data", []))
        for key_file in key_files:
            with open(key_file) as file:
                key_data.append(file.read())
        for key_url in key_urls:
            with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
                uo = urllib2.urlopen(key_url)
            key_data.append(uo.read())

        rv = self._gnupg().import_keys('\n'.join(key_data))

        # Previous crypto evaluations may now be out of date, so we
        # clear the cache so users can see results right away.
        ClearParseCache(pgpmime=True)

        # FIXME: Start a keychain rescan, hopefully targetted on the keys
        #        we just added.

        return self._success(_("Imported %d keys") % len(key_data), rv)
Beispiel #4
0
 def _get(self, url):
     conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []
     if self.config.anonymous:
         conn_reject += [ConnBroker.OUTGOING_TRACKABLE]
     with ConnBroker.context(need=conn_need, reject=conn_reject):
         self.session.ui.mark('Getting: %s' % url)
         return urlopen(url, data=None, timeout=3).read()
Beispiel #5
0
    def command(self):
        html_variables = self.session.ui.html_variables
        request = html_variables["http_request"]

        if not (
            html_variables
            and security.valid_csrf_token(request, html_variables["http_session"], self.data.get("csrf", [""])[0])
        ):
            raise AccessError("Invalid CSRF token")

        url = self.data["url"][0]
        timeout = float(self.data.get("timeout", ["10"])[0])

        conn_reject = []  # FIXME: reject ConnBroker.OUTGOING_TRACKABLE ?
        if url[:6].lower() == "https:":
            conn_need = [ConnBroker.OUTGOING_HTTP]
        elif url[:5].lower() == "http:":
            conn_need = [ConnBroker.OUTGOING_HTTPS]
        else:
            raise AccessError("Invalid URL scheme")

        try:
            with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
                self.session.ui.mark("Getting: %s" % url)
                response = urlopen(url, data=None, timeout=timeout)
        except HTTPError, e:
            response = e
Beispiel #6
0
    def command(self):
        session = self.session
        html_variables = session.ui.html_variables

        if not (html_variables and
                session.ui.valid_csrf_token(self.data.get('csrf', [''])[0])):
            raise AccessError('Invalid CSRF token')

        url = self.data['url'][0]
        timeout = float(self.data.get('timeout', ['10'])[0])

        conn_reject = []  # FIXME: reject ConnBroker.OUTGOING_TRACKABLE ?
        if url[:6].lower() == 'https:':
            conn_need = [ConnBroker.OUTGOING_HTTP]
        elif url[:5].lower() == 'http:':
            conn_need = [ConnBroker.OUTGOING_HTTPS]
        else:
            raise AccessError('Invalid URL scheme')

        try:
            with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
                session.ui.mark('Getting: %s' % url)
                response = urlopen(url, data=None, timeout=timeout)
        except HTTPError, e:
            response = e
Beispiel #7
0
 def mkconn():
     if want_ssl:
         need = [ConnBroker.OUTGOING_IMAPS]
     else:
         need = [ConnBroker.OUTGOING_IMAP]
     with ConnBroker.context(need=need):
         return conn_cls(settings.get('host'),
                         int(settings.get('port')))
Beispiel #8
0
 def _urlget(self, url):
     if url.lower().startswith('https'):
         conn_needs = [ConnBroker.OUTGOING_HTTPS]
     else:
         conn_needs = [ConnBroker.OUTGOING_HTTP]
     with ConnBroker.context(need=conn_needs) as context:
         self.session.ui.mark('Getting: %s' % url)
         return urlopen(url, data=None, timeout=10).read()
Beispiel #9
0
 def mkconn():
     if want_ssl:
         need = [ConnBroker.OUTGOING_IMAPS]
     else:
         need = [ConnBroker.OUTGOING_IMAP]
     with ConnBroker.context(need=need):
         return conn_cls(settings.get('host'),
                         int(settings.get('port')))
Beispiel #10
0
 def _urlget(self, url):
     if url.lower().startswith('https'):
         conn_needs = [ConnBroker.OUTGOING_HTTPS]
     else:
         conn_needs = [ConnBroker.OUTGOING_HTTP]
     with ConnBroker.context(need=conn_needs) as context:
         self.session.ui.mark('Getting: %s' % url)
         return urlopen(url, data=None, timeout=10).read()
Beispiel #11
0
    def _nickserver_get_key(self, address, keytype="openpgp", server=None):
        if server == None: server = self._discover_server(address)

        data = urllib.urlencode({"address": address})
        with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
            r = urllib2.urlopen(server, data)
        result = r.read()
        result, signature = self._parse_result(result)
        return result, signature
Beispiel #12
0
    def _nickserver_get_key(self, address, keytype="openpgp", server=None):
        if server == None: server = self._discover_server(address)

        data = urllib.urlencode({"address": address})
        with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
            r = urllib2.urlopen(server, data)
        result = r.read()
        result, signature = self._parse_result(result)
        return result, signature
Beispiel #13
0
def _open_pop3_mailbox(session,
                       event,
                       host,
                       port,
                       username,
                       password,
                       auth_type,
                       protocol,
                       debug,
                       throw=False):
    cev = event.data['connection'] = {
        'live': False,
        'error': [False, _('Nothing is wrong')]
    }
    try:
        # FIXME: Nothing actually adds gmail or gmail-full to the protocol
        #        yet, so we're stuck in recent mode only for now.
        if (username.lower().split('@')[-1] in GMAIL_TLDS
                or 'gmail' in protocol):
            if 'gmail-full' not in protocol:
                username = '******' % username

        if 'ssl' in protocol:
            need = [ConnBroker.OUTGOING_POP3S]
        else:
            need = [ConnBroker.OUTGOING_POP3]

        with ConnBroker.context(need=need):
            return pop3.MailpileMailbox(host,
                                        port=port,
                                        user=username,
                                        password=password,
                                        auth_type=auth_type,
                                        use_ssl=('ssl' in protocol),
                                        session=session,
                                        debug=debug)
    except AccessError:
        cev['error'] = [
            'auth',
            _('Invalid username or password'), username,
            sha1b64(password)
        ]
    except (ssl.CertificateError, ssl.SSLError):
        cev['error'] = [
            'tls',
            _('Failed to make a secure TLS connection'),
            '%s:%s' % (host, port)
        ]
    except (IOError, OSError):
        cev['error'] = ['network', _('A network error occurred')]
        event.data['traceback'] = traceback.format_exc()

    if throw:
        raise throw(cev['error'][1])

    return None
Beispiel #14
0
 def sm_connect_server():
     server = (smtp_ssl and SMTP_SSL or SMTP
               )(local_hostname='mailpile.local', timeout=25)
     if 'sendmail' in session.config.sys.debug:
         server.set_debuglevel(1)
     if smtp_ssl or sendmail[:7] in ('smtorp', 'smtptls'):
         conn_needs = [ConnBroker.OUTGOING_ENCRYPTED]
     else:
         conn_needs = [ConnBroker.OUTGOING_SMTP]
     with ConnBroker.context(need=conn_needs) as ctx:
         server.connect(host, int(port))
     return server
Beispiel #15
0
 def sm_connect_server():
     server = (smtp_ssl and SMTP_SSL
               or SMTP)(local_hostname='mailpile.local', timeout=25)
     if 'sendmail' in session.config.sys.debug:
         server.set_debuglevel(1)
     if smtp_ssl or sendmail[:7] in ('smtorp', 'smtptls'):
         conn_needs = [ConnBroker.OUTGOING_ENCRYPTED]
     else:
         conn_needs = [ConnBroker.OUTGOING_SMTP]
     with ConnBroker.context(need=conn_needs) as ctx:
         server.connect(host, int(port))
     return server
Beispiel #16
0
    def auto_configure_tor(self, session, hostport=None):
        need_raw = [ConnBroker.OUTGOING_RAW]
        hostport = hostport or ('127.0.0.1', 9050)
        try:
            with ConnBroker.context(need=need_raw) as context:
                tor = socket.create_connection(hostport, timeout=10)
        except IOError:
            return  _('Failed to connect to Tor on %s:%s. Is it installed?'
                      ) % hostport

        # If that succeeded, we might have Tor!
        old_proto = session.config.sys.proxy.protocol
        session.config.sys.proxy.protocol = 'tor'
        session.config.sys.proxy.host = hostport[0]
        session.config.sys.proxy.port = hostport[1]
        session.config.sys.proxy.fallback = True

        # Configure connection broker, revert settings while we test
        ConnBroker.configure()
        session.config.sys.proxy.protocol = old_proto

        # Test it...
        need_tor = [ConnBroker.OUTGOING_HTTPS]
        try:
            with ConnBroker.context(need=need_tor) as context:
                motd = urlopen(MOTD_URL_TOR_ONLY_NO_MARS,
                               data=None, timeout=10).read()
                assert(motd.strip().endswith('}'))
            session.config.sys.proxy.protocol = 'tor'
            message = _('Successfully configured and enabled Tor!')
        except (IOError, AssertionError):
            ConnBroker.configure()
            message = _('Failed to configure Tor on %s:%s. Is the network down?'
                        ) % hostport
        return message
Beispiel #17
0
 def _probe_port(self, host, port, encrypted=False):
     import socket
     if encrypted:
         needs = [ConnBroker.OUTGOING_RAW, ConnBroker.OUTGOING_ENCRYPTED]
     else:
         needs = [ConnBroker.OUTGOING_RAW, ConnBroker.OUTGOING_CLEARTEXT]
     with ConnBroker.context(need=needs) as cb:
         try:
             # FIXME: magic number follows
             socket.create_connection((host, port), timeout=15).close()
             return True
         except (AssertionError, IOError, OSError, socket.error):
             pass
     return False
Beispiel #18
0
    def _get(self, url):
        if url.startswith('file:'):
            return open(url[5:], 'r').read()

        if url.startswith('https:'):
            conn_need = [ConnBroker.OUTGOING_HTTPS]
        elif url.startswith('http:'):
            conn_need = [ConnBroker.OUTGOING_HTTP]
        else:
            return _('Unsupported URL for message of the day: %s') % url

        with ConnBroker.context(need=conn_need) as ctx:
            self.session.ui.mark('Getting: %s' % url)
            return urlopen(url, data=None, timeout=10).read()
Beispiel #19
0
    def _get(self, url):
        if url.startswith('file:'):
            return open(url[5:], 'r').read()

        if url.startswith('https:'):
            conn_need = [ConnBroker.OUTGOING_HTTPS]
        elif url.startswith('http:'):
            conn_need = [ConnBroker.OUTGOING_HTTP]
        else:
            return _('Unsupported URL for message of the day: %s') % url

        with ConnBroker.context(need=conn_need) as ctx:
            self.session.ui.mark('Getting: %s' % url)
            return urlopen(url, data=None, timeout=10).read()
Beispiel #20
0
def secure_urlget(session, url, data=None, timeout=30, anonymous=False):
    from mailpile.conn_brokers import Master as ConnBroker
    from urllib2 import urlopen

    if session.config.prefs.web_content not in ("on", "anon"):
        raise IOError("Web content is disabled by policy")

    if url.startswith('https:'):
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTPS], []
    else:
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []

    if session.config.prefs.web_content == "anon" or anonymous:
        conn_reject += [ConnBroker.OUTGOING_TRACKABLE]

    with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
        return urlopen(url, data=None, timeout=timeout).read()
Beispiel #21
0
def secure_urlget(session, url, data=None, timeout=30, anonymous=False):
    from mailpile.conn_brokers import Master as ConnBroker
    from urllib2 import urlopen

    if session.config.prefs.web_content not in ("on", "anon"):
        raise IOError("Web content is disabled by policy")

    if url.startswith('https:'):
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTPS], []
    else:
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []

    if session.config.prefs.web_content == "anon" or anonymous:
        conn_reject += [ConnBroker.OUTGOING_TRACKABLE]

    with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
        return urlopen(url, data=None, timeout=timeout).read()
Beispiel #22
0
    def _connect(self):
        with self._lock:
            if self._pop3:
                try:
                    self._pop3.noop()
                    return
                except poplib.error_proto:
                    self._pop3 = None

            with ConnBroker.context(need=[ConnBroker.OUTGOING_POP3]):
                if self.conn_cls:
                    self._pop3 = self.conn_cls(self.host,
                                               self.port or 110,
                                               timeout=120)
                    self.secure = self.use_ssl
                elif self.use_ssl:
                    self._pop3 = wrappable_POP3_SSL(self.host,
                                                    self.port or 995,
                                                    timeout=120)
                    self.secure = True
                else:
                    self._pop3 = poplib.POP3(self.host,
                                             self.port or 110,
                                             timeout=120)
                    self.secure = False

            if hasattr(self._pop3, 'sock'):
                self._pop3.sock.settimeout(120)
            if self.debug:
                self._pop3.set_debuglevel(self.debug)

            self._keys = None
            try:
                if self.auth_type.lower() == 'oauth2':
                    from mailpile.plugins.oauth import OAuth2
                    token_info = OAuth2.GetFreshTokenInfo(
                        self.session, self.user)
                    if self.user and token_info and token_info.access_token:
                        raise AccessError("FIXME: Do OAUTH2 Auth!")
                    else:
                        raise AccessError()
                else:
                    self._pop3.user(self.user)
                    self._pop3.pass_(self.password.encode('utf-8'))
            except poplib.error_proto:
                raise AccessError()
Beispiel #23
0
            def sm_connect_server():
                server = (smtp_ssl and SMTP_SSL or SMTP
                          )(local_hostname='mailpile.local', timeout=25)
                if 'sendmail' in session.config.sys.debug:
                    server.set_debuglevel(1)
                if smtp_ssl or proto in ('smtorp', 'smtptls'):
                    conn_needs = [ConnBroker.OUTGOING_ENCRYPTED]
                else:
                    conn_needs = [ConnBroker.OUTGOING_SMTP]
                try:
                    with ConnBroker.context(need=conn_needs) as ctx:
                        server.connect(host, int(port))
                    server.ehlo_or_helo_if_needed()
                except (IOError, OSError, smtplib.SMTPServerDisconnected):
                    fail(_('Failed to connect to %s') % host, events,
                         details={'connection_error': True})

                return server
Beispiel #24
0
            def sm_connect_server():
                server = (smtp_ssl and SMTP_SSL or SMTP
                          )(local_hostname='mailpile.local', timeout=25)
                if 'sendmail' in session.config.sys.debug:
                    server.set_debuglevel(1)
                if smtp_ssl or proto in ('smtorp', 'smtptls'):
                    conn_needs = [ConnBroker.OUTGOING_ENCRYPTED]
                else:
                    conn_needs = [ConnBroker.OUTGOING_SMTP]
                try:
                    with ConnBroker.context(need=conn_needs) as ctx:
                        server.connect(host, int(port))
                        server.ehlo_or_helo_if_needed()
                except (IOError, OSError, smtplib.SMTPServerDisconnected):
                    fail(_('Failed to connect to %s') % host, events,
                         details={'connection_error': True})

                return server
Beispiel #25
0
    def command(self):
        if self.data.get('_method'):
            secret, style, port = self.args
            if secret != GetUserSecret(self.session.config):
                raise AccessError('Invalid User Secret')
        elif len(self.args) == 2:
            style, port = self.args
        elif len(self.args) == 1:
            style, port = 'main', self.args[0]

        with ConnBroker.context(need=[ConnBroker.OUTGOING_RAW]):
            guic = GuiOMaticConnection(
                self.session.config,
                socket.create_connection(('localhost', int(port))),
                main=(style == 'main'))
        guic.start()

        return self._success("OK")
Beispiel #26
0
    def command(self):
        if self.data.get('_method'):
            secret, style, port = self.args
            if secret != GetUserSecret(self.session.config):
                raise AccessError('Invalid User Secret')
        elif len(self.args) == 2:
            style, port = self.args
        elif len(self.args) == 1:
            style, port = 'main', self.args[0]

        with ConnBroker.context(need=[ConnBroker.OUTGOING_RAW]):
            guic = GuiOMaticConnection(self.session.config,
                                       socket.create_connection(
                                           ('localhost', int(port))),
                                       main=(style == 'main'))
        guic.start()

        return self._success("OK")
Beispiel #27
0
    def _connect(self):
        with self._lock:
            if self._pop3:
                try:
                    self._pop3.noop()
                    return
                except poplib.error_proto:
                    self._pop3 = None

            with ConnBroker.context(need=[ConnBroker.OUTGOING_POP3]):
                if self.conn_cls:
                    self._pop3 = self.conn_cls(self.host, self.port or 110,
                                               timeout=120)
                    self.secure = self.use_ssl
                elif self.use_ssl:
                    self._pop3 = wrappable_POP3_SSL(self.host, self.port or 995,
                                                    timeout=120)
                    self.secure = True
                else:
                    self._pop3 = poplib.POP3(self.host, self.port or 110,
                                             timeout=120)
                    self.secure = False

            if hasattr(self._pop3, 'sock'):
                self._pop3.sock.settimeout(120)
            if self.debug:
                self._pop3.set_debuglevel(self.debug)

            self._keys = None
            try:
                if self.auth_type.lower() == 'oauth2':
                    from mailpile.plugins.oauth import OAuth2
                    token_info = OAuth2.GetFreshTokenInfo(self.session,
                                                          self.user)
                    if self.user and token_info and token_info.access_token:
                        raise AccessError("FIXME: Do OAUTH2 Auth!")
                    else:
                        raise AccessError()
                else:
                    self._pop3.user(self.user)
                    self._pop3.pass_(self.password.encode('utf-8'))
            except poplib.error_proto:
                raise AccessError()
Beispiel #28
0
            def sm_startup():
                if 'sendmail' in session.config.sys.debug:
                    server.set_debuglevel(1)
                if smtp_ssl or sendmail[:7] in ('smtorp', 'smtptls'):
                    conn_needs = [ConnBroker.OUTGOING_ENCRYPTED]
                else:
                    conn_needs = [ConnBroker.OUTGOING_SMTP]
                with ConnBroker.context(need=conn_needs) as ctx:
                    server.connect(host, int(port))

                if not smtp_ssl:
                    # We always try to enable TLS, even if the user just
                    # requested plain-text smtp.  But we only throw errors
                    # if the user asked for encryption.
                    try:
                        server.starttls()
                    except:
                        if sendmail.startswith('smtptls'):
                            raise InsecureSmtpError()

                if user and pwd:
                    try:
                        server.login(user.encode('utf-8'), pwd.encode('utf-8'))
                    except UnicodeDecodeError:
                        fail(_('Bad character in username or password'),
                             events,
                             details={'authentication_error': True})
                    except smtplib.SMTPAuthenticationError:
                        fail(_('Invalid username or password'), events,
                             details={'authentication_error': True})

                smtp_do_or_die(_('Sender rejected by SMTP server'),
                               events, server.mail, frm)
                for rcpt in to:
                    rc, msg = server.rcpt(rcpt)
                    if (rc == SMTORP_HASHCASH_RCODE and
                            msg.startswith(SMTORP_HASHCASH_PREFIX)):
                        rc, msg = server.rcpt(SMTorP_HashCash(rcpt, msg))
                    if rc != 250:
                        fail(_('Server rejected recpient: %s') % rcpt, events)
                rcode, rmsg = server.docmd('DATA')
                if rcode != 354:
                    fail(_('Server rejected DATA: %s %s') % (rcode, rmsg))
Beispiel #29
0
 def _getkey(self, key):
     if key["fingerprint"] and not key["url"]:
         res = self._gnupg().recv_key(key["fingerprint"])
     elif key["url"]:
         with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
             r = urllib2.urlopen(key["url"])
         result = r.readlines()
         start = 0
         end = len(result)
         # Hack to deal with possible HTML results from keyservers:
         for i in range(len(result)):
             if result[i].startswith("-----BEGIN PGP"):
                 start = i
             elif result[i].startswith("-----END PGP"):
                 end = i
         result = "".join(result[start:end])
         res = self._gnupg().import_keys(result)
         return res
     else:
         raise ValueError("Need a fingerprint or a URL")
Beispiel #30
0
 def _getkey(self, key):
     if key["fingerprint"] and not key["url"]:
         res = self._gnupg().recv_key(key["fingerprint"])
     elif key["url"]:
         with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]):
             r = urllib2.urlopen(key["url"])
         result = r.readlines()
         start = 0
         end = len(result)
         # Hack to deal with possible HTML results from keyservers:
         for i in range(len(result)):
             if result[i].startswith("-----BEGIN PGP"):
                 start = i
             elif result[i].startswith("-----END PGP"):
                 end = i
         result = "".join(result[start:end])
         res = self._gnupg().import_keys(result)
         return res
     else:
         raise ValueError("Need a fingerprint or a URL")
Beispiel #31
0
def secure_urlget(session, url, data=None, timeout=30, anonymous=False):
    from mailpile.conn_brokers import Master as ConnBroker
    from urllib2 import urlopen

    if session.config.prefs.web_content not in ("on", "anon"):
        raise IOError("Web content is disabled by policy")

    if url[:5].lower() not in ('http:', 'https'):
        raise IOError('Non-HTTP URLs are forbidden: {0!s}'.format(url))

    if url.startswith('https:'):
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTPS], []
    else:
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []

    if session.config.prefs.web_content == "anon" or anonymous:
        conn_reject += [ConnBroker.OUTGOING_TRACKABLE]

    with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
        # Flagged #nosec, because the URL scheme is constrained above
        return urlopen(url, data=None, timeout=timeout).read()  # nosec
Beispiel #32
0
def secure_urlget(session, url, data=None, timeout=30, anonymous=False):
    from mailpile.conn_brokers import Master as ConnBroker
    from urllib2 import urlopen

    if session.config.prefs.web_content not in ("on", "anon"):
        raise IOError("Web content is disabled by policy")

    if url[:5].lower() not in ('http:', 'https'):
        raise IOError('Non-HTTP URLs are forbidden: %s' % url)

    if url.startswith('https:'):
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTPS], []
    else:
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []

    if session.config.prefs.web_content == "anon" or anonymous:
        conn_reject += [ConnBroker.OUTGOING_TRACKABLE]

    with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
        # Flagged #nosec, because the URL scheme is constrained above
        return urlopen(url, data=None, timeout=timeout).read()  # nosec
Beispiel #33
0
    def _lookup(self, address, strict_email_match=True):
        local, _, domain = address.partition("@")
        local_part_encoded = _zbase_encode(
            hashlib.sha1(local.lower().encode('utf-8')).digest())

        error = None
        for urlfmt in self.URL_FORMATS:
            url = urlfmt % {
                'd': domain,
                'l': local_part_encoded,
                'q': urllib.urlencode({'l': local})
            }

            try:
                with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTPS]):
                    r = urllib2.urlopen(url)
                error = None
                break
            except (urllib2.URLError, ssl.CertificateError):
                error = 'TLS'  # Wrong TLS keys are common. :-(
            except urllib2.HTTPError as e:
                if e.code == 404:
                    error = '404'
                    # Since we are testing openpgpkey.* first, if we actually get a
                    # valid response back we should treat that as authoritative and
                    # not waste cycles checking the bare domain too.
                    break
                else:
                    error = str(e)

        if not error:
            result = r.read()
            keydata = get_keydata(result)[0]
            self.key_cache[keydata["fingerprint"]] = result
        elif error in ('TLS', '404'):
            return {}  # Suppress these errors, they are common.
        else:
            raise ValueError(error)

        return {keydata["fingerprint"]: keydata}
Beispiel #34
0
    def _lookup(self, address, strict_email_match=True):
        local, _, domain = address.partition("@")
        local_part_encoded = _zbase_encode(
            hashlib.sha1(local.lower().encode('utf-8')).digest())

        error = None
        for urlfmt in self.URL_FORMATS:
            url = urlfmt % {
                'd': domain,
                'l': local_part_encoded,
                'q': urllib.urlencode({'l': local})}

            try:
                with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTPS]):
                    r = urllib2.urlopen(url)
                error = None
                break
            except (urllib2.URLError, ssl.CertificateError):
                error = 'TLS'  # Wrong TLS keys are common. :-(
            except urllib2.HTTPError as e:
                if e.code == 404:
                    error = '404'
                    # Since we are testing openpgpkey.* first, if we actually get a
                    # valid response back we should treat that as authoritative and
                    # not waste cycles checking the bare domain too.
                    break
                else:
                    error = str(e)

        if not error:
            result = r.read()
            keydata = get_keydata(result)[0]
            self.key_cache[keydata["fingerprint"]] = result
        elif error in ('TLS', '404'):
            return {}  # Suppress these errors, they are common.
        else:
            raise ValueError(error)

        return {keydata["fingerprint"]: keydata}
Beispiel #35
0
def secure_urlget(session,
                  url,
                  data=None,
                  timeout=30,
                  anonymous=False,
                  maxbytes=None,
                  padding=True):
    from mailpile.conn_brokers import Master as ConnBroker
    from urllib2 import build_opener

    if session.config.prefs.web_content not in ("on", "anon"):
        raise IOError("Web content is disabled by policy")

    if url[:5].lower() not in ('http:', 'https'):
        raise IOError('Non-HTTP URLs are forbidden: %s' % url)

    # User Agent forging and padding...
    ffrv = int(time.time() / (7 * 24 * 3600 * 4)) - 649 + 60
    headers = [('User-Agent', (
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:%s.0) Gecko/20100101 Firefox/%s.0'
        % (ffrv, ffrv)))]
    if padding:
        headers.append(('X-Pad', 'PA%sD' % ('A' * (160 - len(url) % 160))))

    if url[:6].lower() == 'https:':
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTPS], []
    else:
        conn_need, conn_reject = [ConnBroker.OUTGOING_HTTP], []

    if session.config.prefs.web_content == "anon" or anonymous:
        conn_reject += [ConnBroker.OUTGOING_TRACKABLE]

    with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
        url_opener = build_opener()
        url_opener.addheaders = headers
        # Flagged #nosec, because the URL scheme is constrained above
        fd = url_opener.open(url, None, timeout=timeout)  # nosec

    return fd.read(maxbytes)
    def command(self):
        session = self.session
        html_variables = session.ui.html_variables

        if not (html_variables and session.ui.valid_csrf_token(
                self.data.get('csrf', [''])[0])):
            raise AccessError('Invalid CSRF token')

        url = self.data['url'][0]
        timeout = float(self.data.get('timeout', ['10'])[0])

        conn_reject = []  # FIXME: reject ConnBroker.OUTGOING_TRACKABLE ?
        if url[:6].lower() == 'https:':
            conn_need = [ConnBroker.OUTGOING_HTTP]
        elif url[:5].lower() == 'http:':
            conn_need = [ConnBroker.OUTGOING_HTTPS]
        else:
            raise AccessError('Invalid URL scheme')

        try:
            with ConnBroker.context(need=conn_need, reject=conn_reject) as ctx:
                session.ui.mark('Getting: %s' % url)
                response = urlopen(url, data=None, timeout=timeout)
        except HTTPError as e:
            response = e

        data = response.read()
        headers = response.headers
        contenttype = headers.get('content-type', 'application/octet-stream')

        request = html_variables['http_request']
        request.send_http_response(response.code, response.msg)
        request.send_standard_headers(mimetype=contenttype,
                                      header_list=[('Content-Length',
                                                    len(data))])
        request.wfile.write(data)

        raise SuppressHtmlOutput()
Beispiel #37
0
    def _connect(self):
        with self._lock:
            if self._pop3:
                try:
                    self._pop3.noop()
                    return
                except poplib.error_proto:
                    self._pop3 = None

            with ConnBroker.context(need=[ConnBroker.OUTGOING_POP3]):
                if self.conn_cls:
                    self._pop3 = self.conn_cls(self.host, self.port or 110)
                    self.secure = self.use_ssl
                elif self.use_ssl:
                    self._pop3 = wrappable_POP3_SSL(self.host, self.port
                                                    or 995)
                    self.secure = True
                else:
                    self._pop3 = poplib.POP3(self.host, self.port or 110)
                    self.secure = False

            if self.debug:
                self._pop3.set_debuglevel(self.debug)

            self._keys = None
            try:
                if self.auth_type.lower() == 'oauth2':
                    token_info = OAuth2.GetFreshTokenInfo(
                        self.session, self.user)
                    if self.user and token_info and token_info.access_token:
                        raise AccessError("FIXME: Do OAUTH2 Auth!")
                    else:
                        raise AccessError()
                else:
                    self._pop3.user(self.user)
                    self._pop3.pass_(self.password)
            except poplib.error_proto:
                raise AccessError()
Beispiel #38
0
    def _connect(self):
        with self._lock:
            if self._pop3:
                try:
                    self._pop3.noop()
                    return
                except poplib.error_proto:
                    self._pop3 = None

            with ConnBroker.context(need=[ConnBroker.OUTGOING_POP3]):
                if self.conn_cls:
                    self._pop3 = self.conn_cls(self.host, self.port or 110)
                    self.secure = self.use_ssl
                elif self.use_ssl:
                    self._pop3 = wrappable_POP3_SSL(self.host, self.port or 995)
                    self.secure = True
                else:
                    self._pop3 = poplib.POP3(self.host, self.port or 110)
                    self.secure = False

            if self.debug:
                self._pop3.set_debuglevel(self.debug)

            self._keys = None
            try:
                if self.auth_type.lower() == 'oauth2':
                    token_info = OAuth2.GetFreshTokenInfo(self.session,
                                                          self.user)
                    if self.user and token_info and token_info.access_token:
                        raise AccessError("FIXME: Do OAUTH2 Auth!")
                    else:
                        raise AccessError()
                else:
                    self._pop3.user(self.user)
                    self._pop3.pass_(self.password)
            except poplib.error_proto:
                raise AccessError()
Beispiel #39
0
    def _lookup(self, address, strict_email_match=True):
        local, _, domain = address.partition("@")
        local_part_encoded = _zbase_encode(
            hashlib.sha1(local.lower().encode('utf-8')).digest())

        url = ("https://%s/.well-known/openpgpkey/hu/%s" %
               (domain, local_part_encoded))

        # This fails A LOT, so just swallow the most common errors.
        try:
            with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTPS]):
                r = urllib2.urlopen(url)
        except urllib2.URLError:
            # This gets thrown on TLS key mismatch
            return {}
        except urllib2.HTTPError as e:
            if e.code == 404:
                return {}
            raise

        result = r.read()
        keydata = get_keydata(result)[0]
        self.key_cache[keydata["fingerprint"]] = result
        return {keydata["fingerprint"]: keydata}
Beispiel #40
0
 def mkconn():
     with ConnBroker.context(need=[ConnBroker.OUTGOING_IMAP]):
         return conn_cls(settings.get('host'),
                         int(settings.get('port')))
Beispiel #41
0
 def mkconn():
     with ConnBroker.context(need=[ConnBroker.OUTGOING_IMAP]):
         return conn_cls(my_config.host, my_config.port)
Beispiel #42
0
 def mkconn():
     with ConnBroker.context(need=[ConnBroker.OUTGOING_IMAP]):
         return conn_cls(settings.get('host'),
                         int(settings.get('port')))
Beispiel #43
0
 def _get(self, url):
     with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]) as context:
         self.session.ui.mark('Getting: %s' % url)
         return urlopen(url, data=None, timeout=3).read()
Beispiel #44
0
 def _urlget(self, url):
     with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]) as context:
         self.session.ui.mark('Getting: %s' % url)
         return urlopen(url, data=None, timeout=3).read()
Beispiel #45
0
 def mkconn():
     with ConnBroker.context(need=[ConnBroker.OUTGOING_IMAP]):
         return conn_cls(my_config.host, my_config.port)