예제 #1
0
  def evaluate_pgp(self, tree, check_sigs=True, decrypt=False):
    pgpdata = []
    for part in tree['text_parts']:

      # Handle signed messages
      if check_sigs and GnuPG:
        if part['type'] == 'pgpbeginsigned':
          pgpdata = [part]
        elif part['type'] == 'pgpsignedtext':
          pgpdata.append(part)
        elif part['type'] == 'pgpsignature':
          pgpdata.append(part)
          try:
            message = ''.join([p['data'].encode(p['charset']) for p in pgpdata])
            gpg = GnuPG().run(['--utf8-strings', '--verify'],
                              create_fhs=['stdin', 'stderr'])
            gpg.handles['stdin'].write(message)
            gpg.handles['stdin'].close()
            result = ''
            for fh in ('stderr', ):
              result += gpg.handles[fh].read()
              gpg.handles[fh].close()
            gpg.wait()
            pgpdata[0]['data'] = result.decode('utf-8')+'\n'
            for p in pgpdata:
              p['type'] = self.PGP_OK.get(p['type'], p['type'])
          except IOError:
            part['data'] += result.decode('utf-8')
          except:
            part['data'] += traceback.format_exc()
          pgpdata = []

      if decrypt and GnuPG:
        if part['type'] in ('pgpbegin', 'pgptext'):
          pgpdata.append(part)
        elif part['type'] == 'pgpend':
          pgpdata.append(part)
          try:
            message = ''.join([p['data'] for p in pgpdata])
            gpg = GnuPG().run(['--utf8-strings'],
                              create_fhs=['stdin', 'stdout', 'stderr'])
            gpg.handles['stdin'].write(message)
            gpg.handles['stdin'].close()
            results = {}
            for fh in ('stderr', 'stdout'):
              results[fh] = gpg.handles[fh].read()
              gpg.handles[fh].close()
            gpg.wait()
            pgpdata[0]['data'] = results['stderr'].decode('utf-8')+'\n'
            pgpdata[1]['data'] = self._decode_gpg(message, results['stdout'])
            for p in pgpdata:
              p['type'] = self.PGP_OK.get(p['type'], p['type'])
          except IOError:
            part['data'] += results['stderr'].decode('utf-8')
          except:
            part['data'] += traceback.format_exc()
          pgpdata = []

    return tree
예제 #2
0
파일: gpg.py 프로젝트: zouxc-zz/Mailpile
 def fingerprints(self):
     """Fetch a key's fingerprints and other details."""
     session, config, arg = self.session, self.session.config, self.args[0]
     keys = []
     try:
         session.ui.mark('Listing available GPG keys')
         gpg = GnuPG().run(['--fingerprint', arg],
                           create_fhs=['stderr', 'stdout'])
         keylines = gpg.handles['stdout'].readlines()
         raise Exception("IMPLEMENT ME!")
         session.ui.display_gpg_keys(keys)
     except IOError:
         return False
     return True
예제 #3
0
파일: pgpmime.py 프로젝트: wtest/Mailpile
    def parse_pgpmime(self, message):
        sig_count, sig_parts, sig_alg = 0, [], 'SHA1'
        enc_count, enc_parts, enc_ver = 0, [], None

        for part in message.walk():
            mimetype = part.get_content_type()

            if (sig_count > 1) and (mimetype == 'application/pgp-signature'):
                sig = tempfile.NamedTemporaryFile()
                sig.write(part.get_payload())
                sig.flush()
                msg = '\r\n'.join(
                    sig_parts[0].as_string().splitlines(False)) + '\r\n'

                result = None
                try:
                    gpg = GnuPG().run(
                        ['--utf8-strings', '--verify', sig.name, '-'],
                        create_fhs=['stdin', 'stderr'])
                    gpg.handles['stdin'].write(msg)
                    gpg.handles['stdin'].close()
                    result = gpg.handles['stderr'].read().decode('utf-8')
                    gpg.wait()
                    summary = ('verified', result)
                except IOError:
                    summary = ('signed', result or 'Error running GnuPG')

                for sig_part in sig_parts:
                    sig_part.openpgp = summary

                # Reset!
                sig_count, sig_parts = 0, []

            elif sig_count > 0:
                sig_parts.append(part)
                sig_count += 1

            elif enc_count > 0:
                # FIXME: Decrypt and parse!
                pass

            elif mimetype == 'multipart/signed':
                sig_alg = part.get_param('micalg',
                                         'pgp-sha1').split('-')[1].upper()
                sig_count = 1

            elif mimetype == 'multipart/encrypted':
                enc_count = 1
예제 #4
0
파일: gpg.py 프로젝트: zouxc-zz/Mailpile
    def recv_key(self):
        """Fetch a PGP public key from a keyserver."""

        session, config, arg = self.session, self.session.config, self.args[0]
        try:
            session.ui.mark('Invoking GPG to fetch key %s' % arg)
            keyserver = config.get('gpg_keyserver', 'pool.sks-keyservers.net')
            gpg = GnuPG().run([
                '--utf8-strings', '--keyserver', keyserver, '--recv-key', arg
            ],
                              create_fhs=['stderr'])
            session.ui.debug(gpg.handles['stderr'].read().decode('utf-8'))
            gpg.handles['stderr'].close()
            gpg.wait()
            session.ui.mark('Fetched key %s' % arg)
        except IOError:
            return self._error('Failed to fetch key %s' % arg)
        return True
예제 #5
0
파일: gpg.py 프로젝트: zouxc-zz/Mailpile
    def list_keys(self):
        """Get a list of available PGP public keys."""

        session, config = self.session, self.session.config
        keys = []
        try:
            session.ui.mark('Listing available GPG keys')
            gpg = GnuPG().run(['--list-keys'], create_fhs=['stderr', 'stdout'])
            keylines = gpg.handles['stdout'].readlines()
            curkey = {}
            for line in keylines:
                if line[0:3] == "pub":
                    if curkey != {}:
                        keys.append(curkey)
                        curkey = {}
                    args = line.split("pub")[1].strip().split(" ")
                    if len(args) == 3:
                        expiry = args[2]
                    else:
                        expiry = None
                    keytype, keyid = args[0].split("/")
                    created = args[1]
                    curkey["subkeys"] = []
                    curkey["uids"] = []
                    curkey["pub"] = {
                        "keyid": keyid,
                        "type": keytype,
                        "created": created,
                        "expires": expiry
                    }
                elif line[0:3] == "sec":
                    if curkey != {}:
                        keys.append(curkey)
                        curkey = {}
                    args = line.split("pub")[1].strip().split(" ")
                    if len(args) == 3:
                        expiry = args[2]
                    else:
                        expiry = None
                    keytype, keyid = args[0].split("/")
                    created = args[1]
                    curkey["subkeys"] = []
                    curkey["uids"] = []
                    curkey["sec"] = {
                        "keyid": keyid,
                        "type": keytype,
                        "created": created,
                        "expires": expiry
                    }
                elif line[0:3] == "uid":
                    curkey["uids"].append(line.split("uid")[1].strip())
                elif line[0:3] == "sub":
                    args = line.split("sub")[1].strip().split(" ")
                    if len(args) == 3:
                        expiry = args[2]
                    else:
                        expiry = None
                    keytype, keyid = args[0].split("/")
                    created = args[1]
                    curkey["subkeys"].append({
                        "keyid": keyid,
                        "type": keytype,
                        "created": created,
                        "expires": expiry
                    })
            gpg.handles['stderr'].close()
            gpg.handles['stdout'].close()
            gpg.wait()
            session.ui.display_gpg_keys(keys)
        except IndexError, e:
            self._ignore_exception()
예제 #6
0
    def parse_pgpmime(self, message):
        sig_count, sig_parts, sig_alg = 0, [], 'SHA1'
        enc_count, enc_parts, enc_ver = 0, [], None

        for part in message.walk():
            mimetype = part.get_content_type()
            if (sig_count > 1) and (mimetype == 'application/pgp-signature'):
                sig = tempfile.NamedTemporaryFile()
                sig.write(part.get_payload())
                sig.flush()
                msg = '\r\n'.join(
                    sig_parts[0].as_string().splitlines(False)) + '\r\n'

                result = None
                try:
                    gpg = GnuPG().run(
                        ['--utf8-strings', '--verify', sig.name, '-'],
                        create_fhs=['stdin', 'stderr'])
                    gpg.handles['stdin'].write(msg)
                    gpg.handles['stdin'].close()
                    result = gpg.handles['stderr'].read().decode('utf-8')
                    gpg.wait()
                    summary = ('verified', result)
                except IOError:
                    if not result:
                        summary = ('signed', 'Error running GnuPG')
                    else:
                        reslines = [
                            g.split("gpg: ")[1]
                            for g in result.strip().split("\n")
                        ]
                        matchgr = re.match(
                            ".*made (.*) using (.*) key ID ([a-zA-Z0-9]{8}).*",
                            reslines[0])
                        keyid = matchgr.groups()[2]
                        keytype = matchgr.groups()[1]
                        datetime = matchgr.groups()[0]

                        # FIXME: This should understand what kind of UI we have.
                        summary = (
                            'signed',
                            "Signed %s with %s key 0x%s (<a onclick=\"mailpile.gpgrecvkey('%s');\">fetch key</a>)"
                            % (datetime, keytype, keyid, keyid))

                for sig_part in sig_parts:
                    sig_part.openpgp = summary

                # Reset!
                sig_count, sig_parts = 0, []

            elif sig_count > 0:
                sig_parts.append(part)
                sig_count += 1

            elif enc_count > 0 and (mimetype == 'application/octet-stream'):
                # FIXME: Decrypt and parse!
                crypt = tempfile.NamedTemporaryFile()
                crypt.write(part.get_payload())
                crypt.flush()
                msg = '\r\n'.join(part.as_string().splitlines(False)) + '\r\n'
                print msg

                result = None
                try:
                    gpg = GnuPG().run(['--utf8-strings', '--decrypt'],
                                      create_fhs=['stdin', 'stdout', 'stderr'])
                    gpg.handles['stdin'].write(msg)
                    gpg.handles['stdin'].close()
                    result = gpg.handles['stdout'].read().decode('utf-8')
                    gpg.wait()
                    print "Decrypted:"
                    print result
                    summary = ('decrypted', result)
                    # part.attach(result)
                    s = StringIO.StringIO()
                    s.write(result)
                    m = Parser().parse(s)
                    print m
                    m = Message()
                    m.set_payload(result)
                    part.set_payload([m])
                    # print part.__module__
                    # enc_parts.append(part)
                except IOError:
                    if not result:
                        summary = ('encrypted', 'Error running GnuPG')
                    else:
                        #reslines = [g.split("gpg: ")[1] for g in result.strip().split("\n")]
                        #matchgr = re.match(".*made (.*) using (.*) key ID ([a-zA-Z0-9]{8}).*", reslines[0])
                        #keyid = matchgr.groups()[2]
                        #keytype = matchgr.groups()[1]
                        #datetime = matchgr.groups()[0]

                        # FIXME: This should understand what kind of UI we have.
                        print "FAIL"
                        summary = ('encrypted', result)

                for enc_part in enc_parts:
                    enc_part.openpgp = summary

                # Reset!
                enc_count, enc_parts = 0, []
            elif mimetype == 'multipart/signed':
                sig_alg = part.get_param('micalg',
                                         'pgp-sha1').split('-')[1].upper()
                sig_count = 1

            elif mimetype == 'multipart/encrypted':
                enc_count = 1