| | |
| | | function tpl_key_data($attrib) |
| | | { |
| | | $out = ''; |
| | | $table = new html_table(array('cols' => 2)); |
| | | $table = new html_table(array('cols' => 2)); |
| | | |
| | | // Key user ID |
| | | $table->add('title', $this->enigma->gettext('keyuserid')); |
| | |
| | | $out .= html::tag('fieldset', null, |
| | | html::tag('legend', null, |
| | | $this->enigma->gettext('basicinfo')) . $table->show($attrib)); |
| | | /* |
| | | |
| | | // Subkeys |
| | | $table = new html_table(array('cols' => 6)); |
| | | // Columns: Type, ID, Algorithm, Size, Created, Expires |
| | | $table = new html_table(array('cols' => 5, 'id' => 'enigmasubkeytable', 'class' => 'records-table')); |
| | | |
| | | $table->add_header('id', $this->enigma->gettext('subkeyid')); |
| | | $table->add_header('algo', $this->enigma->gettext('subkeyalgo')); |
| | | $table->add_header('created', $this->enigma->gettext('subkeycreated')); |
| | | $table->add_header('expires', $this->enigma->gettext('subkeyexpires')); |
| | | $table->add_header('usage', $this->enigma->gettext('subkeyusage')); |
| | | |
| | | $now = time(); |
| | | $date_format = $this->rc->config->get('date_format', 'Y-m-d'); |
| | | $usage_map = array( |
| | | enigma_key::CAN_ENCRYPT => $this->enigma->gettext('typeencrypt'), |
| | | enigma_key::CAN_SIGN => $this->enigma->gettext('typesign'), |
| | | enigma_key::CAN_CERTIFY => $this->enigma->gettext('typecert'), |
| | | enigma_key::CAN_AUTHENTICATE => $this->enigma->gettext('typeauth'), |
| | | ); |
| | | |
| | | foreach ($this->data->subkeys as $subkey) { |
| | | $algo = $subkey->get_algorithm(); |
| | | if ($algo && $subkey->length) { |
| | | $algo .= ' (' . $subkey->length . ')'; |
| | | } |
| | | |
| | | $usage = array(); |
| | | foreach ($usage_map as $key => $text) { |
| | | if ($subkey->usage & $key) { |
| | | $usage[] = $text; |
| | | } |
| | | } |
| | | |
| | | $table->add('id', $subkey->get_short_id()); |
| | | $table->add('algo', $algo); |
| | | $table->add('created', $subkey->created ? $this->rc->format_date($subkey->created, $date_format, false) : ''); |
| | | $table->add('expires', $subkey->expires ? $this->rc->format_date($subkey->expires, $date_format, false) : $this->enigma->gettext('expiresnever')); |
| | | $table->add('usage', implode(',', $usage)); |
| | | $table->set_row_attribs($subkey->revoked || ($subkey->expires && $subkey->expires < $now) ? 'deleted' : ''); |
| | | } |
| | | |
| | | $out .= html::tag('fieldset', null, |
| | | html::tag('legend', null, |
| | | $this->enigma->gettext('subkeys')) . $table->show($attrib)); |
| | | html::tag('legend', null, |
| | | $this->enigma->gettext('subkeys')) . $table->show()); |
| | | |
| | | // Additional user IDs |
| | | $table = new html_table(array('cols' => 2)); |
| | | // Columns: User ID, Validity |
| | | $table = new html_table(array('cols' => 2, 'id' => 'enigmausertable', 'class' => 'records-table')); |
| | | |
| | | $table->add_header('id', $this->enigma->gettext('userid')); |
| | | $table->add_header('valid', $this->enigma->gettext('uservalid')); |
| | | |
| | | foreach ($this->data->users as $user) { |
| | | $username = $user->name; |
| | | if ($user->comment) { |
| | | $username .= ' (' . $user->comment . ')'; |
| | | } |
| | | $username .= ' <' . $user->email . '>'; |
| | | |
| | | $table->add('id', rcube::Q(trim($username))); |
| | | $table->add('valid', $this->enigma->gettext($user->valid ? 'valid' : 'unknown')); |
| | | $table->set_row_attribs($user->revoked || !$user->valid ? 'deleted' : ''); |
| | | } |
| | | |
| | | $out .= html::tag('fieldset', null, |
| | | html::tag('legend', null, |
| | | $this->enigma->gettext('userids')) . $table->show($attrib)); |
| | | */ |
| | | html::tag('legend', null, |
| | | $this->enigma->gettext('userids')) . $table->show()); |
| | | |
| | | return $out; |
| | | } |
| | | |
| | |
| | | */ |
| | | private function key_export() |
| | | { |
| | | $this->rc->request_security_check(rcube_utils::INPUT_GET); |
| | | |
| | | $keys = rcube_utils::get_input_value('_keys', rcube_utils::INPUT_GPC); |
| | | $engine = $this->enigma->load_engine(); |
| | | $list = $keys == '*' ? $engine->list_keys() : explode(',', $keys); |
| | |
| | | $menu->add(null, $chbox->show($this->rc->config->get('enigma_encrypt_all') ? 1 : 0, |
| | | array('name' => '_enigma_encrypt', 'id' => 'enigmaencryptopt'))); |
| | | |
| | | $menu->add(null, html::label(array('for' => 'enigmaattachpubkeyopt'), |
| | | rcube::Q($this->enigma->gettext('attachpubkeymsg')))); |
| | | $menu->add(null, $chbox->show($this->rc->config->get('enigma_attach_pubkey') ? 1 : 0, |
| | | array('name' => '_enigma_attachpubkey', 'id' => 'enigmaattachpubkeyopt'))); |
| | | |
| | | $menu = html::div(array('id' => 'enigmamenu', 'class' => 'popupmenu'), $menu->show()); |
| | | |
| | | // Options menu contents |
| | |
| | | $part_id = $p['part']->mime_id; |
| | | |
| | | // Decryption status |
| | | if (isset($engine->decryptions[$part_id])) { |
| | | if (($found = $this->find_part_id($part_id, $engine->decryptions)) !== null |
| | | && ($status = $engine->decryptions[$found]) |
| | | ) { |
| | | $attach_scripts = true; |
| | | |
| | | // get decryption status |
| | | $status = $engine->decryptions[$part_id]; |
| | | // show the message only once |
| | | unset($engine->decryptions[$found]); |
| | | |
| | | // display status info |
| | | $attrib['id'] = 'enigma-message'; |
| | |
| | | $attrib['class'] = 'enigmaerror'; |
| | | $code = $status->getCode(); |
| | | |
| | | if ($code == enigma_error::E_KEYNOTFOUND) { |
| | | if ($code == enigma_error::KEYNOTFOUND) { |
| | | $msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')), |
| | | $this->enigma->gettext('decryptnokey'))); |
| | | } |
| | | else if ($code == enigma_error::E_BADPASS) { |
| | | $msg = rcube::Q($this->enigma->gettext('decryptbadpass')); |
| | | else if ($code == enigma_error::BADPASS) { |
| | | $missing = $status->getData('missing'); |
| | | $label = 'decrypt' . (!empty($missing) ? 'no' : 'bad') . 'pass'; |
| | | $msg = rcube::Q($this->enigma->gettext($label)); |
| | | $this->password_prompt($status); |
| | | } |
| | | else { |
| | | $msg = rcube::Q($this->enigma->gettext('decrypterror')); |
| | | } |
| | | } |
| | | else if ($status === enigma_engine::ENCRYPTED_PARTIALLY) { |
| | | $attrib['class'] = 'enigmawarning'; |
| | | $msg = rcube::Q($this->enigma->gettext('decryptpartial')); |
| | | } |
| | | else { |
| | | $attrib['class'] = 'enigmanotice'; |
| | |
| | | } |
| | | |
| | | // Signature verification status |
| | | if (isset($engine->signed_parts[$part_id]) |
| | | && ($sig = $engine->signatures[$engine->signed_parts[$part_id]]) |
| | | if (($found = $this->find_part_id($part_id, $engine->signatures)) !== null |
| | | && ($sig = $engine->signatures[$found]) |
| | | ) { |
| | | $attach_scripts = true; |
| | | |
| | | // show the message only once |
| | | unset($engine->signatures[$found]); |
| | | |
| | | // display status info |
| | | $attrib['id'] = 'enigma-message'; |
| | |
| | | if ($sig instanceof enigma_signature) { |
| | | $sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>'; |
| | | |
| | | if ($sig->valid === enigma_error::E_UNVERIFIED) { |
| | | if ($sig->valid === enigma_error::UNVERIFIED) { |
| | | $attrib['class'] = 'enigmawarning'; |
| | | $msg = str_replace('$sender', $sender, $this->enigma->gettext('sigunverified')); |
| | | $msg = str_replace('$keyid', $sig->id, $msg); |
| | | $msg = rcube::Q($msg); |
| | | } |
| | | else if ($sig->valid) { |
| | | $attrib['class'] = 'enigmanotice'; |
| | | $msg = rcube::Q(str_replace('$sender', $sender, $this->enigma->gettext('sigvalid'))); |
| | | $attrib['class'] = $sig->partial ? 'enigmawarning' : 'enigmanotice'; |
| | | $label = 'sigvalid' . ($sig->partial ? 'partial' : ''); |
| | | $msg = rcube::Q(str_replace('$sender', $sender, $this->enigma->gettext($label))); |
| | | } |
| | | else { |
| | | $attrib['class'] = 'enigmawarning'; |
| | | $msg = rcube::Q(str_replace('$sender', $sender, $this->enigma->gettext('siginvalid'))); |
| | | } |
| | | } |
| | | else if ($sig && $sig->getCode() == enigma_error::E_KEYNOTFOUND) { |
| | | else if ($sig && $sig->getCode() == enigma_error::KEYNOTFOUND) { |
| | | $attrib['class'] = 'enigmawarning'; |
| | | $msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($sig->getData('id')), |
| | | $this->enigma->gettext('signokey'))); |
| | |
| | | // $msg .= '<br /><pre>'.$sig->body.'</pre>'; |
| | | |
| | | $p['prefix'] .= html::div($attrib, $msg); |
| | | |
| | | // Display each signature message only once |
| | | unset($engine->signatures[$engine->signed_parts[$part_id]]); |
| | | } |
| | | |
| | | if ($attach_scripts) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Handle message_ready hook (encryption/signing) |
| | | * Handle message_ready hook (encryption/signing/attach public key) |
| | | */ |
| | | function message_ready($p) |
| | | { |
| | | $savedraft = !empty($_POST['_draft']) && empty($_GET['_saveonly']); |
| | | |
| | | if (!$savedraft && rcube_utils::get_input_value('_enigma_attachpubkey', rcube_utils::INPUT_POST)) { |
| | | $p = $this->attach_public($p); |
| | | } |
| | | |
| | | if (!$savedraft && rcube_utils::get_input_value('_enigma_sign', rcube_utils::INPUT_POST)) { |
| | | $this->enigma->load_engine(); |
| | |
| | | if ($mode && ($status instanceof enigma_error)) { |
| | | $code = $status->getCode(); |
| | | |
| | | if ($code == enigma_error::E_KEYNOTFOUND) { |
| | | if ($code == enigma_error::KEYNOTFOUND) { |
| | | $vars = array('email' => $status->getData('missing')); |
| | | $msg = 'enigma.' . $mode . 'nokey'; |
| | | } |
| | | else if ($code == enigma_error::E_BADPASS) { |
| | | $msg = 'enigma.' . $mode . 'badpass'; |
| | | $type = 'warning'; |
| | | |
| | | else if ($code == enigma_error::BADPASS) { |
| | | $this->password_prompt($status); |
| | | } |
| | | else { |
| | | $msg = 'enigma.' . $mode . 'error'; |
| | | } |
| | | |
| | | $this->rc->output->show_message($msg, $type ?: 'error', $vars); |
| | | if ($msg) { |
| | | $this->rc->output->show_message($msg, $type ?: 'error', $vars); |
| | | } |
| | | |
| | | $this->rc->output->send('iframe'); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Add sender's public key (PGP). |
| | | */ |
| | | function attach_public($p) |
| | | { |
| | | // get sender's PGP pubkey for attachment |
| | | $this->enigma->load_engine(); |
| | | $key = $this->enigma->engine->list_keys($p['message']->headers()['From']); |
| | | $keyID = $key[0]->subkeys[0]->get_short_id(); |
| | | $pubkey_armor = $this->enigma->engine->get_gpg_pubkey_for_attach($p['message']->headers()['From']); |
| | | |
| | | if(!$pubkey_armor instanceof enigma_error) { |
| | | $p['message']->addAttachment($pubkey_armor, 'application/pgp-keys', "0x$keyID.asc", false); |
| | | } |
| | | |
| | | return $p; |
| | | } |
| | | |
| | | /** |
| | | * Handler for message_compose_body hook |
| | | * Display error when the message cannot be encrypted |
| | | * and provide a way to try again with a password. |
| | |
| | | if ($status instanceof enigma_error) { |
| | | $code = $status->getCode(); |
| | | |
| | | if ($code == enigma_error::E_KEYNOTFOUND) { |
| | | if ($code == enigma_error::KEYNOTFOUND) { |
| | | $msg = rcube::Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')), |
| | | $this->enigma->gettext('decryptnokey'))); |
| | | } |
| | | else if ($code == enigma_error::E_BADPASS) { |
| | | else if ($code == enigma_error::BADPASS) { |
| | | $this->password_prompt($status, array('compose-init' => true)); |
| | | return $p; |
| | | } |
| | |
| | | $this->rc->output->show_message($msg, 'error'); |
| | | } |
| | | |
| | | // Check sign/ecrypt options for signed/encrypted drafts |
| | | $this->rc->output->set_env('enigma_force_encrypt', !empty($engine->decryptions)); |
| | | $this->rc->output->set_env('enigma_force_sign', !empty($engine->signatures)); |
| | | |
| | | return $p; |
| | | } |
| | | |
| | | /** |
| | | * Check if the part or its parent exists in the array |
| | | * of decryptions/signatures. Returns found ID. |
| | | */ |
| | | private function find_part_id($part_id, $data) |
| | | { |
| | | $ids = explode('.', $part_id); |
| | | $i = 0; |
| | | $count = count($ids); |
| | | |
| | | while ($i < $count && strlen($part = implode('.', array_slice($ids, 0, ++$i)))) { |
| | | if (array_key_exists($part, $data)) { |
| | | return $part; |
| | | } |
| | | } |
| | | } |
| | | } |