| | |
| | | private $enigma; |
| | | private $pgp_driver; |
| | | private $smime_driver; |
| | | private $password_time; |
| | | |
| | | public $decryptions = array(); |
| | | public $signatures = array(); |
| | | public $signed_parts = array(); |
| | | |
| | | const PASSWORD_TIME = 120; |
| | | public $decryptions = array(); |
| | | public $signatures = array(); |
| | | public $signed_parts = array(); |
| | | public $encrypted_parts = array(); |
| | | |
| | | const SIGN_MODE_BODY = 1; |
| | | const SIGN_MODE_SEPARATE = 2; |
| | |
| | | $this->rc = rcmail::get_instance(); |
| | | $this->enigma = $enigma; |
| | | |
| | | $this->password_time = $this->rc->config->get('enigma_password_time'); |
| | | |
| | | // this will remove passwords from session after some time |
| | | $this->get_passwords(); |
| | | if ($this->password_time) { |
| | | $this->get_passwords(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | // encrypted attachment, see parse_plain_encrypted() |
| | | if ($p['part']->need_decryption && $p['part']->body === null) { |
| | | $this->load_pgp_driver(); |
| | | |
| | | $storage = $this->rc->get_storage(); |
| | | $body = $storage->get_message_part($p['object']->uid, $p['part']->mime_id, $p['part'], null, null, true, 0, false); |
| | | $result = $this->pgp_decrypt($body); |
| | |
| | | $part = $p['structure']; |
| | | |
| | | // exit, if we're already inside a decrypted message |
| | | if ($part->encrypted) { |
| | | if (in_array($part->mime_id, $this->encrypted_parts)) { |
| | | return; |
| | | } |
| | | |
| | |
| | | |
| | | // Verify signature |
| | | if ($this->rc->action == 'show' || $this->rc->action == 'preview') { |
| | | $sig = $this->pgp_verify($body); |
| | | if ($this->rc->config->get('enigma_signatures', true)) { |
| | | $sig = $this->pgp_verify($body); |
| | | } |
| | | } |
| | | |
| | | // @TODO: Handle big bodies using (temp) files |
| | |
| | | */ |
| | | private function parse_pgp_signed(&$p) |
| | | { |
| | | if (!$this->rc->config->get('enigma_signatures', true)) { |
| | | return; |
| | | } |
| | | |
| | | // Verify signature |
| | | if ($this->rc->action == 'show' || $this->rc->action == 'preview') { |
| | | $this->load_pgp_driver(); |
| | |
| | | else { |
| | | $this->signed_parts[$msg_part->mime_id] = $struct->mime_id; |
| | | } |
| | | |
| | | // Remove signature file from attachments list (?) |
| | | unset($struct->parts[1]); |
| | | } |
| | | } |
| | | |
| | |
| | | private function parse_smime_signed(&$p) |
| | | { |
| | | return; // @TODO |
| | | |
| | | if (!$this->rc->config->get('enigma_signatures', true)) { |
| | | return; |
| | | } |
| | | |
| | | // Verify signature |
| | | if ($this->rc->action == 'show' || $this->rc->action == 'preview') { |
| | |
| | | else { |
| | | $this->signed_parts[$msg_part->mime_id] = $struct->mime_id; |
| | | } |
| | | |
| | | // Remove signature file from attachments list |
| | | unset($struct->parts[1]); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | private function parse_plain_encrypted(&$p, $body) |
| | | { |
| | | if (!$this->rc->config->get('enigma_decryption', true)) { |
| | | return; |
| | | } |
| | | |
| | | $this->load_pgp_driver(); |
| | | $part = $p['structure']; |
| | | |
| | |
| | | // Store decryption status |
| | | $this->decryptions[$part->mime_id] = $result; |
| | | |
| | | // find parent part ID |
| | | if (strpos($part->mime_id, '.')) { |
| | | $items = explode('.', $part->mime_id); |
| | | array_pop($items); |
| | | $parent = implode('.', $items); |
| | | } |
| | | else { |
| | | $parent = 0; |
| | | } |
| | | |
| | | // Parse decrypted message |
| | | if ($result === true) { |
| | | $part->body = $body; |
| | | $part->body_modified = true; |
| | | $part->encrypted = true; |
| | | |
| | | // Remember it was decrypted |
| | | $this->encrypted_parts[] = $part->mime_id; |
| | | |
| | | // PGP signed inside? verify signature |
| | | if (preg_match('/^-----BEGIN PGP SIGNED MESSAGE-----/', $body)) { |
| | | $this->parse_plain_signed($p, $body); |
| | | } |
| | | |
| | | // Encrypted plain message may contain encrypted attachments |
| | | // in such case attachments have .pgp extension and application/octet-stream. |
| | | // in such case attachments have .pgp extension and type application/octet-stream. |
| | | // This is what happens when you select "Encrypt each attachment separately |
| | | // and send the message using inline PGP" in Thunderbird's Enigmail. |
| | | |
| | | // find parent part ID |
| | | if (strpos($part->mime_id, '.')) { |
| | | $items = explode('.', $part->mime_id); |
| | | array_pop($items); |
| | | $parent = implode('.', $items); |
| | | } |
| | | else { |
| | | $parent = 0; |
| | | } |
| | | |
| | | if ($p['object']->mime_parts[$parent]) { |
| | | foreach ((array)$p['object']->mime_parts[$parent]->parts as $p) { |
| | |
| | | } |
| | | } |
| | | } |
| | | // decryption failed, but the message may have already |
| | | // been cached with the modified parts (see above), |
| | | // let's bring the original state back |
| | | else if ($p['object']->mime_parts[$parent]) { |
| | | foreach ((array)$p['object']->mime_parts[$parent]->parts as $p) { |
| | | if ($p->need_decryption && !preg_match('/^(.*)\.pgp$/i', $p->filename, $m)) { |
| | | // modify filename |
| | | $p->filename .= '.pgp'; |
| | | // flag the part, it will be decrypted when needed |
| | | unset($p->need_decryption); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | private function parse_pgp_encrypted(&$p) |
| | | { |
| | | if (!$this->rc->config->get('enigma_decryption', true)) { |
| | | return; |
| | | } |
| | | |
| | | $this->load_pgp_driver(); |
| | | |
| | | $struct = $p['structure']; |
| | |
| | | */ |
| | | private function parse_smime_encrypted(&$p) |
| | | { |
| | | if (!$this->rc->config->get('enigma_decryption', true)) { |
| | | return; |
| | | } |
| | | |
| | | // $this->load_smime_driver(); |
| | | } |
| | | |
| | |
| | | $config = @unserialize($config); |
| | | } |
| | | |
| | | $threshold = time() - self::PASSWORD_TIME; |
| | | $threshold = time() - $this->password_time; |
| | | $keys = array(); |
| | | |
| | | // delete expired passwords |
| | | foreach ((array) $config as $key => $value) { |
| | | if ($value[1] < $threshold) { |
| | | if ($pass_time && $value[1] < $threshold) { |
| | | unset($config[$key]); |
| | | $modified = true; |
| | | } |
| | |
| | | $part->body_modified = true; |
| | | $part->encoding = 'stream'; |
| | | |
| | | // Cache the fact it was decrypted |
| | | $part->encrypted = true; |
| | | |
| | | // modify part identifier |
| | | if ($old_id) { |
| | | $part->mime_id = !$part->mime_id ? $old_id : ($old_id . '.' . $part->mime_id); |
| | | } |
| | | |
| | | // Cache the fact it was decrypted |
| | | $this->encrypted_parts[] = $part->mime_id; |
| | | |
| | | $msg->mime_parts[$part->mime_id] = $part; |
| | | |
| | | // modify sub-parts |