Esempio n. 1
0
 def _create_new_key(self, vcard, keytype):
     passphrase = okay_random(26, self.session.config.master_key
                              ).lower()
     random_uid = vcard.random_uid
     bits = int(keytype.replace('RSA', ''))
     key_args = {
         # FIXME: EC keys!
         'bits': bits,
         'name': vcard.fn,
         'email': vcard.email,
         'passphrase': passphrase,
         'comment': ''
     }
     event = Event(source=self,
                   message=_('Generating new %d bit PGP key. '
                             'This may take some time!') % bits,
                   flags=Event.INCOMPLETE,
                   data={'keygen_started': int(time.time()),
                         'profile_id': random_uid},
                   private_data=key_args)
     self._key_generator = GnuPGKeyGenerator(
        # FIXME: Passphrase handling is a problem here
        variables=dict_merge(GnuPGKeyGenerator.VARIABLES, key_args),
        on_complete=(random_uid,
                     lambda: self._new_key_created(event, random_uid,
                                                   passphrase))
     )
     self._key_generator.start()
     self.session.config.event_log.log_event(event)
Esempio n. 2
0
    def setup_command(self, session):
        changed = authed = False
        results = {
            'secret_keys': self.list_secret_keys(),
        }
        error_info = None

        if self.data.get('_method') == 'POST' or self._testing():

            # 1st, are we choosing or creating a new key?
            choose_key = self.data.get('choose_key', [''])[0]
            if choose_key and not error_info:
                if (choose_key not in results['secret_keys'] and
                        choose_key != '!CREATE'):
                    error_info = (_('Invalid key'), {
                        'invalid_key': True,
                        'chosen_key': choose_key
                    })

            # 2nd, check authentication...
            #
            # FIXME: Creating a new key will allow a malicious actor to
            #        bypass authentication and change settings.
            #
            try:
                passphrase = self.data.get('passphrase', [''])[0]
                passphrase2 = self.data.get('passphrase_confirm', [''])[0]
                chosen_key = ((not error_info) and choose_key
                              ) or session.config.prefs.gpg_recipient

                if not error_info:
                    assert(passphrase == passphrase2)
                    if chosen_key == '!CREATE':
                        assert(passphrase != '')
                        sps = SecurePassphraseStorage(passphrase)
                    elif chosen_key:
                        sps = mailpile.auth.VerifyAndStorePassphrase(
                            session.config,
                            passphrase=passphrase,
                            key=chosen_key)
                    else:
                        sps = mailpile.auth.VerifyAndStorePassphrase(
                            session.config, passphrase=passphrase)
                    if not chosen_key:
                        choose_key = '!CREATE'
                    results['updated_passphrase'] = True
                    session.config.gnupg_passphrase.data = sps.data
                    mailpile.auth.SetLoggedIn(self)
            except AssertionError:
                error_info = (_('Invalid passphrase'), {
                    'invalid_passphrase': True,
                    'chosen_key': session.config.prefs.gpg_recipient
                })

            # 3rd, if necessary master key and/or GPG key
            with BLOCK_HTTPD_LOCK, Idle_HTTPD():
                if choose_key and not error_info:
                    session.config.prefs.gpg_recipient = choose_key
                    # FIXME: This should probably only happen if the GPG
                    #        key was successfully created.
                    self.make_master_key()
                    changed = True

                with Setup.KEY_WORKER_LOCK:
                    if ((not error_info) and
                            (session.config.prefs.gpg_recipient
                             == '!CREATE') and
                            (Setup.KEY_CREATING_THREAD is None or
                             Setup.KEY_CREATING_THREAD.failed)):
                        gk = GnuPGKeyGenerator(
                            sps=session.config.gnupg_passphrase,
                            on_complete=('notify',
                                         lambda: self.gpg_key_ready(gk)))
                        Setup.KEY_CREATING_THREAD = gk
                        Setup.KEY_CREATING_THREAD.start()

            # Finally we update misc. settings
            for key in self.HTTP_POST_VARS.keys():
                # FIXME: This should probably only happen if the GPG
                #        key was successfully created.

                # Continue iff all is well...
                if error_info:
                    break
                if key in (['choose_key', 'passphrase', 'passphrase_confirm'] +
                           TestableWebbable.HTTP_POST_VARS.keys()):
                    continue
                try:
                    val = self.data.get(key, [''])[0]
                    if val:
                        session.config.prefs[key] = self.TRUTHY[val.lower()]
                        changed = True
                except (ValueError, KeyError):
                    error_info = (_('Invalid preference'), {
                        'invalid_setting': True,
                        'variable': key
                    })

        results.update({
            'creating_key': (Setup.KEY_CREATING_THREAD is not None and
                             Setup.KEY_CREATING_THREAD.running),
            'creating_failed': (Setup.KEY_CREATING_THREAD is not None and
                                Setup.KEY_CREATING_THREAD.failed),
            'chosen_key': session.config.prefs.gpg_recipient,
            'prefs': {
                'index_encrypted': session.config.prefs.index_encrypted,
                'obfuscate_index': session.config.prefs.obfuscate_index,
                'encrypt_mail': session.config.prefs.encrypt_mail,
                'encrypt_index': session.config.prefs.encrypt_index,
                'encrypt_vcards': session.config.prefs.encrypt_vcards,
                'encrypt_events': session.config.prefs.encrypt_events,
                'encrypt_misc': session.config.prefs.encrypt_misc
            }
        })

        if changed:
            self._background_save(config=True)

        if error_info:
            return self._error(error_info[0],
                               info=error_info[1], result=results)
        elif changed:
            return self._success(_('Updated crypto preferences'), results)
        else:
            return self._success(_('Configure crypto preferences'), results)