summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/enigma/README35
-rw-r--r--plugins/enigma/config.inc.php14
-rw-r--r--plugins/enigma/enigma.js206
-rw-r--r--plugins/enigma/enigma.php475
-rw-r--r--plugins/enigma/home/.htaccess2
-rw-r--r--plugins/enigma/lib/Crypt/GPG.php2542
-rw-r--r--plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php336
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Engine.php1758
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Exceptions.php473
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Key.php223
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Signature.php428
-rw-r--r--plugins/enigma/lib/Crypt/GPG/SubKey.php649
-rw-r--r--plugins/enigma/lib/Crypt/GPG/UserId.php373
-rw-r--r--plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php216
-rw-r--r--plugins/enigma/lib/enigma_driver.php106
-rw-r--r--plugins/enigma/lib/enigma_driver_gnupg.php305
-rw-r--r--plugins/enigma/lib/enigma_engine.php547
-rw-r--r--plugins/enigma/lib/enigma_error.php62
-rw-r--r--plugins/enigma/lib/enigma_key.php129
-rw-r--r--plugins/enigma/lib/enigma_signature.php34
-rw-r--r--plugins/enigma/lib/enigma_subkey.php57
-rw-r--r--plugins/enigma/lib/enigma_ui.php459
-rw-r--r--plugins/enigma/lib/enigma_userid.php31
-rw-r--r--plugins/enigma/localization/en_US.inc53
-rw-r--r--plugins/enigma/localization/ja_JP.inc55
-rw-r--r--plugins/enigma/skins/default/enigma.css182
-rw-r--r--plugins/enigma/skins/default/enigma.pngbin1592 -> 0 bytes
-rw-r--r--plugins/enigma/skins/default/enigma_error.pngbin1960 -> 0 bytes
-rw-r--r--plugins/enigma/skins/default/key.pngbin1743 -> 0 bytes
-rw-r--r--plugins/enigma/skins/default/key_add.pngbin1967 -> 0 bytes
-rw-r--r--plugins/enigma/skins/default/keys_toolbar.pngbin14977 -> 0 bytes
-rw-r--r--plugins/enigma/skins/default/templates/keyimport.html20
-rw-r--r--plugins/enigma/skins/default/templates/keyinfo.html17
-rw-r--r--plugins/enigma/skins/default/templates/keys.html76
-rw-r--r--plugins/kolab_addressbook/kolab_addressbook.php140
-rw-r--r--plugins/kolab_addressbook/localization/en_US.inc7
-rw-r--r--plugins/kolab_addressbook/rcube_kolab_contacts.php829
-rw-r--r--plugins/kolab_core/README.txt32
-rw-r--r--plugins/kolab_core/config.inc.php.dist8
-rw-r--r--plugins/kolab_core/kolab_core.php30
-rw-r--r--plugins/kolab_core/rcube_kolab.php109
41 files changed, 0 insertions, 11018 deletions
diff --git a/plugins/enigma/README b/plugins/enigma/README
deleted file mode 100644
index afb23224c..000000000
--- a/plugins/enigma/README
+++ /dev/null
@@ -1,35 +0,0 @@
-------------------------------------------------------------------
-THIS IS NOT EVEN AN "ALPHA" STATE. USE ONLY FOR DEVELOPMENT!!!!!!!
-------------------------------------------------------------------
-
-WARNING: Don't use with gnupg-2.x!
-
-Enigma Plugin Status:
-
-* DONE:
-
-- PGP signed messages verification
-- Handling of PGP keys files attached to incoming messages
-- PGP encrypted messages decryption (started)
-- PGP keys management UI (started)
-
-* TODO (must have):
-
-- Parsing of decrypted messages into array (see rcube_mime_struct) and then into rcube_message_part structure
- (create core class rcube_mime_parser or take over PEAR::Mail_mimeDecode package and improve it)
-- Sending encrypted/signed messages (probably some changes in core will be needed)
-- Per-Identity settings (including keys/certs) (+ split Identities details page into tabs)
-- Handling big messages with temp files (including changes in Roundcube core)
-- Performance improvements (some caching, code review)
-- better (and more) icons
-
-* TODO (later):
-
-- Keys generation
-- Certs generation
-- Keys/Certs info in Contacts details page (+ split Contact details page into tabs)
-- Key server support
-- S/MIME signed messages verification
-- S/MIME encrypted messages decryption
-- Handling of S/MIME certs files attached to incoming messages
-- SSL (S/MIME) Certs management
diff --git a/plugins/enigma/config.inc.php b/plugins/enigma/config.inc.php
deleted file mode 100644
index ca841d0ac..000000000
--- a/plugins/enigma/config.inc.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-// Enigma Plugin options
-// --------------------
-
-// A driver to use for PGP. Default: "gnupg".
-$rcmail_config['enigma_pgp_driver'] = 'gnupg';
-
-// A driver to use for S/MIME. Default: "phpssl".
-$rcmail_config['enigma_smime_driver'] = 'phpssl';
-
-// Keys directory for all users. Default 'enigma/home'.
-// Must be writeable by PHP process
-$rcmail_config['enigma_pgp_homedir'] = null;
diff --git a/plugins/enigma/enigma.js b/plugins/enigma/enigma.js
deleted file mode 100644
index 29c648224..000000000
--- a/plugins/enigma/enigma.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/* Enigma Plugin */
-
-if (window.rcmail)
-{
- rcmail.addEventListener('init', function(evt)
- {
- if (rcmail.env.task == 'settings') {
- rcmail.register_command('plugin.enigma', function() { rcmail.goto_url('plugin.enigma') }, true);
- rcmail.register_command('plugin.enigma-key-import', function() { rcmail.enigma_key_import() }, true);
- rcmail.register_command('plugin.enigma-key-export', function() { rcmail.enigma_key_export() }, true);
-
- if (rcmail.gui_objects.keyslist)
- {
- var p = rcmail;
- rcmail.keys_list = new rcube_list_widget(rcmail.gui_objects.keyslist,
- {multiselect:false, draggable:false, keyboard:false});
- rcmail.keys_list.addEventListener('select', function(o){ p.enigma_key_select(o); });
- rcmail.keys_list.init();
- rcmail.keys_list.focus();
-
- rcmail.enigma_list();
-
- rcmail.register_command('firstpage', function(props) {return rcmail.enigma_list_page('first'); });
- rcmail.register_command('previouspage', function(props) {return rcmail.enigma_list_page('previous'); });
- rcmail.register_command('nextpage', function(props) {return rcmail.enigma_list_page('next'); });
- rcmail.register_command('lastpage', function(props) {return rcmail.enigma_list_page('last'); });
- }
-
- if (rcmail.env.action == 'edit-prefs') {
- rcmail.register_command('search', function(props) {return rcmail.enigma_search(props); }, true);
- rcmail.register_command('reset-search', function(props) {return rcmail.enigma_search_reset(props); }, true);
- }
- else if (rcmail.env.action == 'plugin.enigma') {
- rcmail.register_command('plugin.enigma-import', function() { rcmail.enigma_import() }, true);
- rcmail.register_command('plugin.enigma-export', function() { rcmail.enigma_export() }, true);
- }
- }
- });
-}
-
-/*********************************************************/
-/********* Enigma Settings/Keys/Certs UI *********/
-/*********************************************************/
-
-// Display key(s) import form
-rcube_webmail.prototype.enigma_key_import = function()
-{
- this.enigma_loadframe(null, '&_a=keyimport');
-};
-
-// Submit key(s) form
-rcube_webmail.prototype.enigma_import = function()
-{
- var form, file;
- if (form = this.gui_objects.importform) {
- file = document.getElementById('rcmimportfile');
- if (file && !file.value) {
- alert(this.get_label('selectimportfile'));
- return;
- }
- form.submit();
- this.set_busy(true, 'importwait');
- this.lock_form(form, true);
- }
-};
-
-// list row selection handler
-rcube_webmail.prototype.enigma_key_select = function(list)
-{
- var id;
- if (id = list.get_single_selection())
- this.enigma_loadframe(id);
-};
-
-// load key frame
-rcube_webmail.prototype.enigma_loadframe = function(id, url)
-{
- var frm, win;
- if (this.env.contentframe && window.frames && (frm = window.frames[this.env.contentframe])) {
- if (!id && !url && (win = window.frames[this.env.contentframe])) {
- if (win.location && win.location.href.indexOf(this.env.blankpage)<0)
- win.location.href = this.env.blankpage;
- return;
- }
- this.set_busy(true);
- if (!url)
- url = '&_a=keyinfo&_id='+id;
- frm.location.href = this.env.comm_path+'&_action=plugin.enigma&_framed=1' + url;
- }
-};
-
-// Search keys/certs
-rcube_webmail.prototype.enigma_search = function(props)
-{
- if (!props && this.gui_objects.qsearchbox)
- props = this.gui_objects.qsearchbox.value;
-
- if (props || this.env.search_request) {
- var params = {'_a': 'keysearch', '_q': urlencode(props)},
- lock = this.set_busy(true, 'searching');
-// if (this.gui_objects.search_filter)
- // addurl += '&_filter=' + this.gui_objects.search_filter.value;
- this.env.current_page = 1;
- this.enigma_loadframe();
- this.enigma_clear_list();
- this.http_post('plugin.enigma', params, lock);
- }
-
- return false;
-}
-
-// Reset search filter and the list
-rcube_webmail.prototype.enigma_search_reset = function(props)
-{
- var s = this.env.search_request;
- this.reset_qsearch();
-
- if (s) {
- this.enigma_loadframe();
- this.enigma_clear_list();
-
- // refresh the list
- this.enigma_list();
- }
-
- return false;
-}
-
-// Keys/certs listing
-rcube_webmail.prototype.enigma_list = function(page)
-{
- var params = {'_a': 'keylist'},
- lock = this.set_busy(true, 'loading');
-
- this.env.current_page = page ? page : 1;
-
- if (this.env.search_request)
- params._q = this.env.search_request;
- if (page)
- params._p = page;
-
- this.enigma_clear_list();
- this.http_post('plugin.enigma', params, lock);
-}
-
-// Change list page
-rcube_webmail.prototype.enigma_list_page = function(page)
-{
- if (page == 'next')
- page = this.env.current_page + 1;
- else if (page == 'last')
- page = this.env.pagecount;
- else if (page == 'prev' && this.env.current_page > 1)
- page = this.env.current_page - 1;
- else if (page == 'first' && this.env.current_page > 1)
- page = 1;
-
- this.enigma_list(page);
-}
-
-// Remove list rows
-rcube_webmail.prototype.enigma_clear_list = function()
-{
- this.enigma_loadframe();
- if (this.keys_list)
- this.keys_list.clear(true);
-}
-
-// Adds a row to the list
-rcube_webmail.prototype.enigma_add_list_row = function(r)
-{
- if (!this.gui_objects.keyslist || !this.keys_list)
- return false;
-
- var list = this.keys_list,
- tbody = this.gui_objects.keyslist.tBodies[0],
- rowcount = tbody.rows.length,
- even = rowcount%2,
- css_class = 'message'
- + (even ? ' even' : ' odd'),
- // for performance use DOM instead of jQuery here
- row = document.createElement('tr'),
- col = document.createElement('td');
-
- row.id = 'rcmrow' + r.id;
- row.className = css_class;
-
- col.innerHTML = r.name;
- row.appendChild(col);
- list.insert_row(row);
-}
-
-/*********************************************************/
-/********* Enigma Message methods *********/
-/*********************************************************/
-
-// Import attached keys/certs file
-rcube_webmail.prototype.enigma_import_attachment = function(mime_id)
-{
- var lock = this.set_busy(true, 'loading');
- this.http_post('plugin.enigmaimport', '_uid='+this.env.uid+'&_mbox='
- +urlencode(this.env.mailbox)+'&_part='+urlencode(mime_id), lock);
-
- return false;
-};
-
diff --git a/plugins/enigma/enigma.php b/plugins/enigma/enigma.php
deleted file mode 100644
index fb7c98635..000000000
--- a/plugins/enigma/enigma.php
+++ /dev/null
@@ -1,475 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Enigma Plugin for Roundcube |
- | Version 0.1 |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-/*
- This class contains only hooks and action handlers.
- Most plugin logic is placed in enigma_engine and enigma_ui classes.
-*/
-
-class enigma extends rcube_plugin
-{
- public $task = 'mail|settings';
- public $rc;
- public $engine;
-
- private $env_loaded;
- private $message;
- private $keys_parts = array();
- private $keys_bodies = array();
-
-
- /**
- * Plugin initialization.
- */
- function init()
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
-
- if ($this->rc->task == 'mail') {
- // message parse/display hooks
- $this->add_hook('message_part_structure', array($this, 'parse_structure'));
- $this->add_hook('message_body_prefix', array($this, 'status_message'));
-
- // message displaying
- if ($rcmail->action == 'show' || $rcmail->action == 'preview') {
- $this->add_hook('message_load', array($this, 'message_load'));
- $this->add_hook('template_object_messagebody', array($this, 'message_output'));
- $this->register_action('plugin.enigmaimport', array($this, 'import_file'));
- }
- // message composing
- else if ($rcmail->action == 'compose') {
- $this->load_ui();
- $this->ui->init($section);
- }
- // message sending (and draft storing)
- else if ($rcmail->action == 'sendmail') {
- //$this->add_hook('outgoing_message_body', array($this, 'msg_encode'));
- //$this->add_hook('outgoing_message_body', array($this, 'msg_sign'));
- }
- }
- else if ($this->rc->task == 'settings') {
- // add hooks for Enigma settings
- $this->add_hook('preferences_sections_list', array($this, 'preferences_section'));
- $this->add_hook('preferences_list', array($this, 'preferences_list'));
- $this->add_hook('preferences_save', array($this, 'preferences_save'));
-
- // register handler for keys/certs management
- $this->register_action('plugin.enigma', array($this, 'preferences_ui'));
-
- // grab keys/certs management iframe requests
- $section = get_input_value('_section', RCUBE_INPUT_GET);
- if ($this->rc->action == 'edit-prefs' && preg_match('/^enigma(certs|keys)/', $section)) {
- $this->load_ui();
- $this->ui->init($section);
- }
- }
- }
-
- /**
- * Plugin environment initialization.
- */
- function load_env()
- {
- if ($this->env_loaded)
- return;
-
- $this->env_loaded = true;
-
- // Add include path for Enigma classes and drivers
- $include_path = $this->home . '/lib' . PATH_SEPARATOR;
- $include_path .= ini_get('include_path');
- set_include_path($include_path);
-
- // load the Enigma plugin configuration
- $this->load_config();
-
- // include localization (if wasn't included before)
- $this->add_texts('localization/');
- }
-
- /**
- * Plugin UI initialization.
- */
- function load_ui()
- {
- if ($this->ui)
- return;
-
- // load config/localization
- $this->load_env();
-
- // Load UI
- $this->ui = new enigma_ui($this, $this->home);
- }
-
- /**
- * Plugin engine initialization.
- */
- function load_engine()
- {
- if ($this->engine)
- return;
-
- // load config/localization
- $this->load_env();
-
- $this->engine = new enigma_engine($this);
- }
-
- /**
- * Handler for message_part_structure hook.
- * Called for every part of the message.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function parse_structure($p)
- {
- $struct = $p['structure'];
-
- if ($p['mimetype'] == 'text/plain' || $p['mimetype'] == 'application/pgp') {
- $this->parse_plain($p);
- }
- else if ($p['mimetype'] == 'multipart/signed') {
- $this->parse_signed($p);
- }
- else if ($p['mimetype'] == 'multipart/encrypted') {
- $this->parse_encrypted($p);
- }
- else if ($p['mimetype'] == 'application/pkcs7-mime') {
- $this->parse_encrypted($p);
- }
-
- return $p;
- }
-
- /**
- * Handler for preferences_sections_list hook.
- * Adds Enigma settings sections into preferences sections list.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_section($p)
- {
- // add labels
- $this->add_texts('localization/');
-
- $p['list']['enigmasettings'] = array(
- 'id' => 'enigmasettings', 'section' => $this->gettext('enigmasettings'),
- );
- $p['list']['enigmacerts'] = array(
- 'id' => 'enigmacerts', 'section' => $this->gettext('enigmacerts'),
- );
- $p['list']['enigmakeys'] = array(
- 'id' => 'enigmakeys', 'section' => $this->gettext('enigmakeys'),
- );
-
- return $p;
- }
-
- /**
- * Handler for preferences_list hook.
- * Adds options blocks into Enigma settings sections in Preferences.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_list($p)
- {
- if ($p['section'] == 'enigmasettings') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
- else if ($p['section'] == 'enigmacerts') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
- else if ($p['section'] == 'enigmakeys') {
- // This makes that section is not removed from the list
- $p['blocks']['dummy']['options']['dummy'] = array();
- }
-
- return $p;
- }
-
- /**
- * Handler for preferences_save hook.
- * Executed on Enigma settings form submit.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function preferences_save($p)
- {
- if ($p['section'] == 'enigmasettings') {
- $a['prefs'] = array(
-// 'dummy' => get_input_value('_dummy', RCUBE_INPUT_POST),
- );
- }
-
- return $p;
- }
-
- /**
- * Handler for keys/certs management UI template.
- */
- function preferences_ui()
- {
- $this->load_ui();
- $this->ui->init();
- }
-
- /**
- * Handler for message_body_prefix hook.
- * Called for every displayed (content) part of the message.
- * Adds infobox about signature verification and/or decryption
- * status above the body.
- *
- * @param array Original parameters
- *
- * @return array Modified parameters
- */
- function status_message($p)
- {
- $part_id = $p['part']->mime_id;
-
- // skip: not a message part
- if ($p['part'] instanceof rcube_message)
- return $p;
-
- // skip: message has no signed/encoded content
- if (!$this->engine)
- return $p;
-
- // Decryption status
- if (isset($this->engine->decryptions[$part_id])) {
-
- // get decryption status
- $status = $this->engine->decryptions[$part_id];
-
- // Load UI and add css script
- $this->load_ui();
- $this->ui->add_css();
-
- // display status info
- $attrib['id'] = 'enigma-message';
-
- if ($status instanceof enigma_error) {
- $attrib['class'] = 'enigmaerror';
- $code = $status->getCode();
- if ($code == enigma_error::E_KEYNOTFOUND)
- $msg = Q(str_replace('$keyid', enigma_key::format_id($status->getData('id')),
- $this->gettext('decryptnokey')));
- else if ($code == enigma_error::E_BADPASS)
- $msg = Q($this->gettext('decryptbadpass'));
- else
- $msg = Q($this->gettext('decrypterror'));
- }
- else {
- $attrib['class'] = 'enigmanotice';
- $msg = Q($this->gettext('decryptok'));
- }
-
- $p['prefix'] .= html::div($attrib, $msg);
- }
-
- // Signature verification status
- if (isset($this->engine->signed_parts[$part_id])
- && ($sig = $this->engine->signatures[$this->engine->signed_parts[$part_id]])
- ) {
- // add css script
- $this->load_ui();
- $this->ui->add_css();
-
- // display status info
- $attrib['id'] = 'enigma-message';
-
- if ($sig instanceof enigma_signature) {
- if ($sig->valid) {
- $attrib['class'] = 'enigmanotice';
- $sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>';
- $msg = Q(str_replace('$sender', $sender, $this->gettext('sigvalid')));
- }
- else {
- $attrib['class'] = 'enigmawarning';
- $sender = ($sig->name ? $sig->name . ' ' : '') . '<' . $sig->email . '>';
- $msg = Q(str_replace('$sender', $sender, $this->gettext('siginvalid')));
- }
- }
- else if ($sig->getCode() == enigma_error::E_KEYNOTFOUND) {
- $attrib['class'] = 'enigmawarning';
- $msg = Q(str_replace('$keyid', enigma_key::format_id($sig->getData('id')),
- $this->gettext('signokey')));
- }
- else {
- $attrib['class'] = 'enigmaerror';
- $msg = Q($this->gettext('sigerror'));
- }
-/*
- $msg .= '&nbsp;' . html::a(array('href' => "#sigdetails",
- 'onclick' => JS_OBJECT_NAME.".command('enigma-sig-details')"),
- Q($this->gettext('showdetails')));
-*/
- // test
-// $msg .= '<br /><pre>'.$sig->body.'</pre>';
-
- $p['prefix'] .= html::div($attrib, $msg);
-
- // Display each signature message only once
- unset($this->engine->signatures[$this->engine->signed_parts[$part_id]]);
- }
-
- return $p;
- }
-
- /**
- * Handler for plain/text message.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_plain(&$p)
- {
- $this->load_engine();
- $this->engine->parse_plain($p);
- }
-
- /**
- * Handler for multipart/signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_signed(&$p)
- {
- $this->load_engine();
- $this->engine->parse_signed($p);
- }
-
- /**
- * Handler for multipart/encrypted and application/pkcs7-mime message.
- *
- * @param array Reference to hook's parameters (see enigma::parse_structure())
- */
- private function parse_encrypted(&$p)
- {
- $this->load_engine();
- $this->engine->parse_encrypted($p);
- }
-
- /**
- * Handler for message_load hook.
- * Check message bodies and attachments for keys/certs.
- */
- function message_load($p)
- {
- $this->message = $p['object'];
-
- // handle attachments vcard attachments
- foreach ((array)$this->message->attachments as $attachment) {
- if ($this->is_keys_part($attachment)) {
- $this->keys_parts[] = $attachment->mime_id;
- }
- }
- // the same with message bodies
- foreach ((array)$this->message->parts as $idx => $part) {
- if ($this->is_keys_part($part)) {
- $this->keys_parts[] = $part->mime_id;
- $this->keys_bodies[] = $part->mime_id;
- }
- }
- // @TODO: inline PGP keys
-
- if ($this->keys_parts) {
- $this->add_texts('localization');
- }
- }
-
- /**
- * Handler for template_object_messagebody hook.
- * This callback function adds a box below the message content
- * if there is a key/cert attachment available
- */
- function message_output($p)
- {
- $attach_script = false;
-
- foreach ($this->keys_parts as $part) {
-
- // remove part's body
- if (in_array($part, $this->keys_bodies))
- $p['content'] = '';
-
- $style = "margin:0 1em; padding:0.2em 0.5em; border:1px solid #999; width: auto"
- ." border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px";
-
- // add box below messsage body
- $p['content'] .= html::p(array('style' => $style),
- html::a(array(
- 'href' => "#",
- 'onclick' => "return ".JS_OBJECT_NAME.".enigma_import_attachment('".JQ($part)."')",
- 'title' => $this->gettext('keyattimport')),
- html::img(array('src' => $this->url('skins/default/key_add.png'), 'style' => "vertical-align:middle")))
- . ' ' . html::span(null, $this->gettext('keyattfound')));
-
- $attach_script = true;
- }
-
- if ($attach_script) {
- $this->include_script('enigma.js');
- }
-
- return $p;
- }
-
- /**
- * Handler for attached keys/certs import
- */
- function import_file()
- {
- $this->load_engine();
- $this->engine->import_file();
- }
-
- /**
- * Checks if specified message part is a PGP-key or S/MIME cert data
- *
- * @param rcube_message_part Part object
- *
- * @return boolean True if part is a key/cert
- */
- private function is_keys_part($part)
- {
- // @TODO: S/MIME
- return (
- // Content-Type: application/pgp-keys
- $part->mimetype == 'application/pgp-keys'
- );
- }
-}
diff --git a/plugins/enigma/home/.htaccess b/plugins/enigma/home/.htaccess
deleted file mode 100644
index 8e6a345dc..000000000
--- a/plugins/enigma/home/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-Order allow,deny
-Deny from all \ No newline at end of file
diff --git a/plugins/enigma/lib/Crypt/GPG.php b/plugins/enigma/lib/Crypt/GPG.php
deleted file mode 100644
index 6e8e717e8..000000000
--- a/plugins/enigma/lib/Crypt/GPG.php
+++ /dev/null
@@ -1,2542 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Crypt_GPG is a package to use GPG from PHP
- *
- * This package provides an object oriented interface to GNU Privacy
- * Guard (GPG). It requires the GPG executable to be on the system.
- *
- * Though GPG can support symmetric-key cryptography, this package is intended
- * only to facilitate public-key cryptography.
- *
- * This file contains the main GPG class. The class in this file lets you
- * encrypt, decrypt, sign and verify data; import and delete keys; and perform
- * other useful GPG tasks.
- *
- * Example usage:
- * <code>
- * <?php
- * // encrypt some data
- * $gpg = new Crypt_GPG();
- * $gpg->addEncryptKey($mySecretKeyId);
- * $encryptedData = $gpg->encrypt($data);
- * ?>
- * </code>
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: GPG.php 302814 2010-08-26 15:43:07Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://pear.php.net/manual/en/package.encryption.crypt-gpg.php
- * @link http://www.gnupg.org/
- */
-
-/**
- * Signature handler class
- */
-require_once 'Crypt/GPG/VerifyStatusHandler.php';
-
-/**
- * Decryption handler class
- */
-require_once 'Crypt/GPG/DecryptStatusHandler.php';
-
-/**
- * GPG key class
- */
-require_once 'Crypt/GPG/Key.php';
-
-/**
- * GPG sub-key class
- */
-require_once 'Crypt/GPG/SubKey.php';
-
-/**
- * GPG user id class
- */
-require_once 'Crypt/GPG/UserId.php';
-
-/**
- * GPG process and I/O engine class
- */
-require_once 'Crypt/GPG/Engine.php';
-
-/**
- * GPG exception classes
- */
-require_once 'Crypt/GPG/Exceptions.php';
-
-// {{{ class Crypt_GPG
-
-/**
- * A class to use GPG from PHP
- *
- * This class provides an object oriented interface to GNU Privacy Guard (GPG).
- *
- * Though GPG can support symmetric-key cryptography, this class is intended
- * only to facilitate public-key cryptography.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-class Crypt_GPG
-{
- // {{{ class error constants
-
- /**
- * Error code returned when there is no error.
- */
- const ERROR_NONE = 0;
-
- /**
- * Error code returned when an unknown or unhandled error occurs.
- */
- const ERROR_UNKNOWN = 1;
-
- /**
- * Error code returned when a bad passphrase is used.
- */
- const ERROR_BAD_PASSPHRASE = 2;
-
- /**
- * Error code returned when a required passphrase is missing.
- */
- const ERROR_MISSING_PASSPHRASE = 3;
-
- /**
- * Error code returned when a key that is already in the keyring is
- * imported.
- */
- const ERROR_DUPLICATE_KEY = 4;
-
- /**
- * Error code returned the required data is missing for an operation.
- *
- * This could be missing key data, missing encrypted data or missing
- * signature data.
- */
- const ERROR_NO_DATA = 5;
-
- /**
- * Error code returned when an unsigned key is used.
- */
- const ERROR_UNSIGNED_KEY = 6;
-
- /**
- * Error code returned when a key that is not self-signed is used.
- */
- const ERROR_NOT_SELF_SIGNED = 7;
-
- /**
- * Error code returned when a public or private key that is not in the
- * keyring is used.
- */
- const ERROR_KEY_NOT_FOUND = 8;
-
- /**
- * Error code returned when an attempt to delete public key having a
- * private key is made.
- */
- const ERROR_DELETE_PRIVATE_KEY = 9;
-
- /**
- * Error code returned when one or more bad signatures are detected.
- */
- const ERROR_BAD_SIGNATURE = 10;
-
- /**
- * Error code returned when there is a problem reading GnuPG data files.
- */
- const ERROR_FILE_PERMISSIONS = 11;
-
- // }}}
- // {{{ class constants for data signing modes
-
- /**
- * Signing mode for normal signing of data. The signed message will not
- * be readable without special software.
- *
- * This is the default signing mode.
- *
- * @see Crypt_GPG::sign()
- * @see Crypt_GPG::signFile()
- */
- const SIGN_MODE_NORMAL = 1;
-
- /**
- * Signing mode for clearsigning data. Clearsigned signatures are ASCII
- * armored data and are readable without special software. If the signed
- * message is unencrypted, the message will still be readable. The message
- * text will be in the original encoding.
- *
- * @see Crypt_GPG::sign()
- * @see Crypt_GPG::signFile()
- */
- const SIGN_MODE_CLEAR = 2;
-
- /**
- * Signing mode for creating a detached signature. When using detached
- * signatures, only the signature data is returned. The original message
- * text may be distributed separately from the signature data. This is
- * useful for miltipart/signed email messages as per
- * {@link http://www.ietf.org/rfc/rfc3156.txt RFC 3156}.
- *
- * @see Crypt_GPG::sign()
- * @see Crypt_GPG::signFile()
- */
- const SIGN_MODE_DETACHED = 3;
-
- // }}}
- // {{{ class constants for fingerprint formats
-
- /**
- * No formatting is performed.
- *
- * Example: C3BC615AD9C766E5A85C1F2716D27458B1BBA1C4
- *
- * @see Crypt_GPG::getFingerprint()
- */
- const FORMAT_NONE = 1;
-
- /**
- * Fingerprint is formatted in the format used by the GnuPG gpg command's
- * default output.
- *
- * Example: C3BC 615A D9C7 66E5 A85C 1F27 16D2 7458 B1BB A1C4
- *
- * @see Crypt_GPG::getFingerprint()
- */
- const FORMAT_CANONICAL = 2;
-
- /**
- * Fingerprint is formatted in the format used when displaying X.509
- * certificates
- *
- * Example: C3:BC:61:5A:D9:C7:66:E5:A8:5C:1F:27:16:D2:74:58:B1:BB:A1:C4
- *
- * @see Crypt_GPG::getFingerprint()
- */
- const FORMAT_X509 = 3;
-
- // }}}
- // {{{ other class constants
-
- /**
- * URI at which package bugs may be reported.
- */
- const BUG_URI = 'http://pear.php.net/bugs/report.php?package=Crypt_GPG';
-
- // }}}
- // {{{ protected class properties
-
- /**
- * Engine used to control the GPG subprocess
- *
- * @var Crypt_GPG_Engine
- *
- * @see Crypt_GPG::setEngine()
- */
- protected $engine = null;
-
- /**
- * Keys used to encrypt
- *
- * The array is of the form:
- * <code>
- * array(
- * $key_id => array(
- * 'fingerprint' => $fingerprint,
- * 'passphrase' => null
- * )
- * );
- * </code>
- *
- * @var array
- * @see Crypt_GPG::addEncryptKey()
- * @see Crypt_GPG::clearEncryptKeys()
- */
- protected $encryptKeys = array();
-
- /**
- * Keys used to decrypt
- *
- * The array is of the form:
- * <code>
- * array(
- * $key_id => array(
- * 'fingerprint' => $fingerprint,
- * 'passphrase' => $passphrase
- * )
- * );
- * </code>
- *
- * @var array
- * @see Crypt_GPG::addSignKey()
- * @see Crypt_GPG::clearSignKeys()
- */
- protected $signKeys = array();
-
- /**
- * Keys used to sign
- *
- * The array is of the form:
- * <code>
- * array(
- * $key_id => array(
- * 'fingerprint' => $fingerprint,
- * 'passphrase' => $passphrase
- * )
- * );
- * </code>
- *
- * @var array
- * @see Crypt_GPG::addDecryptKey()
- * @see Crypt_GPG::clearDecryptKeys()
- */
- protected $decryptKeys = array();
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new GPG object
- *
- * Available options are:
- *
- * - <kbd>string homedir</kbd> - the directory where the GPG
- * keyring files are stored. If not
- * specified, Crypt_GPG uses the
- * default of <kbd>~/.gnupg</kbd>.
- * - <kbd>string publicKeyring</kbd> - the file path of the public
- * keyring. Use this if the public
- * keyring is not in the homedir, or
- * if the keyring is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * keyring with this option
- * (/foo/bar/pubring.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string privateKeyring</kbd> - the file path of the private
- * keyring. Use this if the private
- * keyring is not in the homedir, or
- * if the keyring is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * keyring with this option
- * (/foo/bar/secring.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string trustDb</kbd> - the file path of the web-of-trust
- * database. Use this if the trust
- * database is not in the homedir, or
- * if the database is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * trust database with this option
- * (/foo/bar/trustdb.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string binary</kbd> - the location of the GPG binary. If
- * not specified, the driver attempts
- * to auto-detect the GPG binary
- * location using a list of known
- * default locations for the current
- * operating system. The option
- * <kbd>gpgBinary</kbd> is a
- * deprecated alias for this option.
- * - <kbd>boolean debug</kbd> - whether or not to use debug mode.
- * When debug mode is on, all
- * communication to and from the GPG
- * subprocess is logged. This can be
- *
- * @param array $options optional. An array of options used to create the
- * GPG object. All options are optional and are
- * represented as key-value pairs.
- *
- * @throws Crypt_GPG_FileException if the <kbd>homedir</kbd> does not exist
- * and cannot be created. This can happen if <kbd>homedir</kbd> is
- * not specified, Crypt_GPG is run as the web user, and the web
- * user has no home directory. This exception is also thrown if any
- * of the options <kbd>publicKeyring</kbd>,
- * <kbd>privateKeyring</kbd> or <kbd>trustDb</kbd> options are
- * specified but the files do not exist or are are not readable.
- * This can happen if the user running the Crypt_GPG process (for
- * example, the Apache user) does not have permission to read the
- * files.
- *
- * @throws PEAR_Exception if the provided <kbd>binary</kbd> is invalid, or
- * if no <kbd>binary</kbd> is provided and no suitable binary could
- * be found.
- */
- public function __construct(array $options = array())
- {
- $this->setEngine(new Crypt_GPG_Engine($options));
- }
-
- // }}}
- // {{{ importKey()
-
- /**
- * Imports a public or private key into the keyring
- *
- * Keys may be removed from the keyring using
- * {@link Crypt_GPG::deletePublicKey()} or
- * {@link Crypt_GPG::deletePrivateKey()}.
- *
- * @param string $data the key data to be imported.
- *
- * @return array an associative array containing the following elements:
- * - <kbd>fingerprint</kbd> - the fingerprint of the
- * imported key,
- * - <kbd>public_imported</kbd> - the number of public
- * keys imported,
- * - <kbd>public_unchanged</kbd> - the number of unchanged
- * public keys,
- * - <kbd>private_imported</kbd> - the number of private
- * keys imported,
- * - <kbd>private_unchanged</kbd> - the number of unchanged
- * private keys.
- *
- * @throws Crypt_GPG_NoDataException if the key data is missing or if the
- * data is is not valid key data.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function importKey($data)
- {
- return $this->_importKey($data, false);
- }
-
- // }}}
- // {{{ importKeyFile()
-
- /**
- * Imports a public or private key file into the keyring
- *
- * Keys may be removed from the keyring using
- * {@link Crypt_GPG::deletePublicKey()} or
- * {@link Crypt_GPG::deletePrivateKey()}.
- *
- * @param string $filename the key file to be imported.
- *
- * @return array an associative array containing the following elements:
- * - <kbd>fingerprint</kbd> - the fingerprint of the
- * imported key,
- * - <kbd>public_imported</kbd> - the number of public
- * keys imported,
- * - <kbd>public_unchanged</kbd> - the number of unchanged
- * public keys,
- * - <kbd>private_imported</kbd> - the number of private
- * keys imported,
- * - <kbd>private_unchanged</kbd> - the number of unchanged
- * private keys.
- * private keys.
- *
- * @throws Crypt_GPG_NoDataException if the key data is missing or if the
- * data is is not valid key data.
- *
- * @throws Crypt_GPG_FileException if the key file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function importKeyFile($filename)
- {
- return $this->_importKey($filename, true);
- }
-
- // }}}
- // {{{ exportPublicKey()
-
- /**
- * Exports a public key from the keyring
- *
- * The exported key remains on the keyring. To delete the public key, use
- * {@link Crypt_GPG::deletePublicKey()}.
- *
- * If more than one key fingerprint is available for the specified
- * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
- * first public key is exported.
- *
- * @param string $keyId either the full uid of the public key, the email
- * part of the uid of the public key or the key id of
- * the public key. For example,
- * "Test User (example) <test@example.com>",
- * "test@example.com" or a hexadecimal string.
- * @param boolean $armor optional. If true, ASCII armored data is returned;
- * otherwise, binary data is returned. Defaults to
- * true.
- *
- * @return string the public key data.
- *
- * @throws Crypt_GPG_KeyNotFoundException if a public key with the given
- * <kbd>$keyId</kbd> is not found.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function exportPublicKey($keyId, $armor = true)
- {
- $fingerprint = $this->getFingerprint($keyId);
-
- if ($fingerprint === null) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'Public key not found: ' . $keyId,
- Crypt_GPG::ERROR_KEY_NOT_FOUND, $keyId);
- }
-
- $keyData = '';
- $operation = '--export ' . escapeshellarg($fingerprint);
- $arguments = ($armor) ? array('--armor') : array();
-
- $this->engine->reset();
- $this->engine->setOutput($keyData);
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- if ($code !== Crypt_GPG::ERROR_NONE) {
- throw new Crypt_GPG_Exception(
- 'Unknown error exporting public key. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
-
- return $keyData;
- }
-
- // }}}
- // {{{ deletePublicKey()
-
- /**
- * Deletes a public key from the keyring
- *
- * If more than one key fingerprint is available for the specified
- * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
- * first public key is deleted.
- *
- * The private key must be deleted first or an exception will be thrown.
- * See {@link Crypt_GPG::deletePrivateKey()}.
- *
- * @param string $keyId either the full uid of the public key, the email
- * part of the uid of the public key or the key id of
- * the public key. For example,
- * "Test User (example) <test@example.com>",
- * "test@example.com" or a hexadecimal string.
- *
- * @return void
- *
- * @throws Crypt_GPG_KeyNotFoundException if a public key with the given
- * <kbd>$keyId</kbd> is not found.
- *
- * @throws Crypt_GPG_DeletePrivateKeyException if the specified public key
- * has an associated private key on the keyring. The private key
- * must be deleted first.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function deletePublicKey($keyId)
- {
- $fingerprint = $this->getFingerprint($keyId);
-
- if ($fingerprint === null) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'Public key not found: ' . $keyId,
- Crypt_GPG::ERROR_KEY_NOT_FOUND, $keyId);
- }
-
- $operation = '--delete-key ' . escapeshellarg($fingerprint);
- $arguments = array(
- '--batch',
- '--yes'
- );
-
- $this->engine->reset();
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- break;
- case Crypt_GPG::ERROR_DELETE_PRIVATE_KEY:
- throw new Crypt_GPG_DeletePrivateKeyException(
- 'Private key must be deleted before public key can be ' .
- 'deleted.', $code, $keyId);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error deleting public key. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
- }
-
- // }}}
- // {{{ deletePrivateKey()
-
- /**
- * Deletes a private key from the keyring
- *
- * If more than one key fingerprint is available for the specified
- * <kbd>$keyId</kbd> (for example, if you use a non-unique uid) only the
- * first private key is deleted.
- *
- * Calls GPG with the <kbd>--delete-secret-key</kbd> command.
- *
- * @param string $keyId either the full uid of the private key, the email
- * part of the uid of the private key or the key id of
- * the private key. For example,
- * "Test User (example) <test@example.com>",
- * "test@example.com" or a hexadecimal string.
- *
- * @return void
- *
- * @throws Crypt_GPG_KeyNotFoundException if a private key with the given
- * <kbd>$keyId</kbd> is not found.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function deletePrivateKey($keyId)
- {
- $fingerprint = $this->getFingerprint($keyId);
-
- if ($fingerprint === null) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'Private key not found: ' . $keyId,
- Crypt_GPG::ERROR_KEY_NOT_FOUND, $keyId);
- }
-
- $operation = '--delete-secret-key ' . escapeshellarg($fingerprint);
- $arguments = array(
- '--batch',
- '--yes'
- );
-
- $this->engine->reset();
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- break;
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- throw new Crypt_GPG_KeyNotFoundException(
- 'Private key not found: ' . $keyId,
- $code, $keyId);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error deleting private key. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
- }
-
- // }}}
- // {{{ getKeys()
-
- /**
- * Gets the available keys in the keyring
- *
- * Calls GPG with the <kbd>--list-keys</kbd> command and grabs keys. See
- * the first section of <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG package} for a detailed
- * description of how the GPG command output is parsed.
- *
- * @param string $keyId optional. Only keys with that match the specified
- * pattern are returned. The pattern may be part of
- * a user id, a key id or a key fingerprint. If not
- * specified, all keys are returned.
- *
- * @return array an array of {@link Crypt_GPG_Key} objects. If no keys
- * match the specified <kbd>$keyId</kbd> an empty array is
- * returned.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG_Key
- */
- public function getKeys($keyId = '')
- {
- // get private key fingerprints
- if ($keyId == '') {
- $operation = '--list-secret-keys';
- } else {
- $operation = '--list-secret-keys ' . escapeshellarg($keyId);
- }
-
- // According to The file 'doc/DETAILS' in the GnuPG distribution, using
- // double '--with-fingerprint' also prints the fingerprint for subkeys.
- $arguments = array(
- '--with-colons',
- '--with-fingerprint',
- '--with-fingerprint',
- '--fixed-list-mode'
- );
-
- $output = '';
-
- $this->engine->reset();
- $this->engine->setOutput($output);
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- // ignore not found key errors
- break;
- case Crypt_GPG::ERROR_FILE_PERMISSIONS:
- $filename = $this->engine->getErrorFilename();
- if ($filename) {
- throw new Crypt_GPG_FileException(sprintf(
- 'Error reading GnuPG data file \'%s\'. Check to make ' .
- 'sure it is readable by the current user.', $filename),
- $code, $filename);
- }
- throw new Crypt_GPG_FileException(
- 'Error reading GnuPG data file. Check to make GnuPG data ' .
- 'files are readable by the current user.', $code);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error getting keys. Please use the \'debug\' option ' .
- 'when creating the Crypt_GPG object, and file a bug report ' .
- 'at ' . self::BUG_URI, $code);
- }
-
- $privateKeyFingerprints = array();
-
- $lines = explode(PHP_EOL, $output);
- foreach ($lines as $line) {
- $lineExp = explode(':', $line);
- if ($lineExp[0] == 'fpr') {
- $privateKeyFingerprints[] = $lineExp[9];
- }
- }
-
- // get public keys
- if ($keyId == '') {
- $operation = '--list-public-keys';
- } else {
- $operation = '--list-public-keys ' . escapeshellarg($keyId);
- }
-
- $output = '';
-
- $this->engine->reset();
- $this->engine->setOutput($output);
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- // ignore not found key errors
- break;
- case Crypt_GPG::ERROR_FILE_PERMISSIONS:
- $filename = $this->engine->getErrorFilename();
- if ($filename) {
- throw new Crypt_GPG_FileException(sprintf(
- 'Error reading GnuPG data file \'%s\'. Check to make ' .
- 'sure it is readable by the current user.', $filename),
- $code, $filename);
- }
- throw new Crypt_GPG_FileException(
- 'Error reading GnuPG data file. Check to make GnuPG data ' .
- 'files are readable by the current user.', $code);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error getting keys. Please use the \'debug\' option ' .
- 'when creating the Crypt_GPG object, and file a bug report ' .
- 'at ' . self::BUG_URI, $code);
- }
-
- $keys = array();
-
- $key = null; // current key
- $subKey = null; // current sub-key
-
- $lines = explode(PHP_EOL, $output);
- foreach ($lines as $line) {
- $lineExp = explode(':', $line);
-
- if ($lineExp[0] == 'pub') {
-
- // new primary key means last key should be added to the array
- if ($key !== null) {
- $keys[] = $key;
- }
-
- $key = new Crypt_GPG_Key();
-
- $subKey = Crypt_GPG_SubKey::parse($line);
- $key->addSubKey($subKey);
-
- } elseif ($lineExp[0] == 'sub') {
-
- $subKey = Crypt_GPG_SubKey::parse($line);
- $key->addSubKey($subKey);
-
- } elseif ($lineExp[0] == 'fpr') {
-
- $fingerprint = $lineExp[9];
-
- // set current sub-key fingerprint
- $subKey->setFingerprint($fingerprint);
-
- // if private key exists, set has private to true
- if (in_array($fingerprint, $privateKeyFingerprints)) {
- $subKey->setHasPrivate(true);
- }
-
- } elseif ($lineExp[0] == 'uid') {
-
- $string = stripcslashes($lineExp[9]); // as per documentation
- $userId = new Crypt_GPG_UserId($string);
-
- if ($lineExp[1] == 'r') {
- $userId->setRevoked(true);
- }
-
- $key->addUserId($userId);
-
- }
- }
-
- // add last key
- if ($key !== null) {
- $keys[] = $key;
- }
-
- return $keys;
- }
-
- // }}}
- // {{{ getFingerprint()
-
- /**
- * Gets a key fingerprint from the keyring
- *
- * If more than one key fingerprint is available (for example, if you use
- * a non-unique user id) only the first key fingerprint is returned.
- *
- * Calls the GPG <kbd>--list-keys</kbd> command with the
- * <kbd>--with-fingerprint</kbd> option to retrieve a public key
- * fingerprint.
- *
- * @param string $keyId either the full user id of the key, the email
- * part of the user id of the key, or the key id of
- * the key. For example,
- * "Test User (example) <test@example.com>",
- * "test@example.com" or a hexadecimal string.
- * @param integer $format optional. How the fingerprint should be formatted.
- * Use {@link Crypt_GPG::FORMAT_X509} for X.509
- * certificate format,
- * {@link Crypt_GPG::FORMAT_CANONICAL} for the format
- * used by GnuPG output and
- * {@link Crypt_GPG::FORMAT_NONE} for no formatting.
- * Defaults to <code>Crypt_GPG::FORMAT_NONE</code>.
- *
- * @return string the fingerprint of the key, or null if no fingerprint
- * is found for the given <kbd>$keyId</kbd>.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function getFingerprint($keyId, $format = Crypt_GPG::FORMAT_NONE)
- {
- $output = '';
- $operation = '--list-keys ' . escapeshellarg($keyId);
- $arguments = array(
- '--with-colons',
- '--with-fingerprint'
- );
-
- $this->engine->reset();
- $this->engine->setOutput($output);
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- // ignore not found key errors
- break;
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error getting key fingerprint. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
-
- $fingerprint = null;
-
- $lines = explode(PHP_EOL, $output);
- foreach ($lines as $line) {
- if (substr($line, 0, 3) == 'fpr') {
- $lineExp = explode(':', $line);
- $fingerprint = $lineExp[9];
-
- switch ($format) {
- case Crypt_GPG::FORMAT_CANONICAL:
- $fingerprintExp = str_split($fingerprint, 4);
- $format = '%s %s %s %s %s %s %s %s %s %s';
- $fingerprint = vsprintf($format, $fingerprintExp);
- break;
-
- case Crypt_GPG::FORMAT_X509:
- $fingerprintExp = str_split($fingerprint, 2);
- $fingerprint = implode(':', $fingerprintExp);
- break;
- }
-
- break;
- }
- }
-
- return $fingerprint;
- }
-
- // }}}
- // {{{ encrypt()
-
- /**
- * Encrypts string data
- *
- * Data is ASCII armored by default but may optionally be returned as
- * binary.
- *
- * @param string $data the data to be encrypted.
- * @param boolean $armor optional. If true, ASCII armored data is returned;
- * otherwise, binary data is returned. Defaults to
- * true.
- *
- * @return string the encrypted data.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
- * See {@link Crypt_GPG::addEncryptKey()}.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @sensitive $data
- */
- public function encrypt($data, $armor = true)
- {
- return $this->_encrypt($data, false, null, $armor);
- }
-
- // }}}
- // {{{ encryptFile()
-
- /**
- * Encrypts a file
- *
- * Encrypted data is ASCII armored by default but may optionally be saved
- * as binary.
- *
- * @param string $filename the filename of the file to encrypt.
- * @param string $encryptedFile optional. The filename of the file in
- * which to store the encrypted data. If null
- * or unspecified, the encrypted data is
- * returned as a string.
- * @param boolean $armor optional. If true, ASCII armored data is
- * returned; otherwise, binary data is
- * returned. Defaults to true.
- *
- * @return void|string if the <kbd>$encryptedFile</kbd> parameter is null,
- * a string containing the encrypted data is returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
- * See {@link Crypt_GPG::addEncryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function encryptFile($filename, $encryptedFile = null, $armor = true)
- {
- return $this->_encrypt($filename, true, $encryptedFile, $armor);
- }
-
- // }}}
- // {{{ encryptAndSign()
-
- /**
- * Encrypts and signs data
- *
- * Data is encrypted and signed in a single pass.
- *
- * NOTE: Until GnuPG version 1.4.10, it was not possible to verify
- * encrypted-signed data without decrypting it at the same time. If you try
- * to use {@link Crypt_GPG::verify()} method on encrypted-signed data with
- * earlier GnuPG versions, you will get an error. Please use
- * {@link Crypt_GPG::decryptAndVerify()} to verify encrypted-signed data.
- *
- * @param string $data the data to be encrypted and signed.
- * @param boolean $armor optional. If true, ASCII armored data is returned;
- * otherwise, binary data is returned. Defaults to
- * true.
- *
- * @return string the encrypted signed data.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
- * or if no signing key is specified. See
- * {@link Crypt_GPG::addEncryptKey()} and
- * {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG::decryptAndVerify()
- */
- public function encryptAndSign($data, $armor = true)
- {
- return $this->_encryptAndSign($data, false, null, $armor);
- }
-
- // }}}
- // {{{ encryptAndSignFile()
-
- /**
- * Encrypts and signs a file
- *
- * The file is encrypted and signed in a single pass.
- *
- * NOTE: Until GnuPG version 1.4.10, it was not possible to verify
- * encrypted-signed files without decrypting them at the same time. If you
- * try to use {@link Crypt_GPG::verify()} method on encrypted-signed files
- * with earlier GnuPG versions, you will get an error. Please use
- * {@link Crypt_GPG::decryptAndVerifyFile()} to verify encrypted-signed
- * files.
- *
- * @param string $filename the name of the file containing the data to
- * be encrypted and signed.
- * @param string $signedFile optional. The name of the file in which the
- * encrypted, signed data should be stored. If
- * null or unspecified, the encrypted, signed
- * data is returned as a string.
- * @param boolean $armor optional. If true, ASCII armored data is
- * returned; otherwise, binary data is returned.
- * Defaults to true.
- *
- * @return void|string if the <kbd>$signedFile</kbd> parameter is null, a
- * string containing the encrypted, signed data is
- * returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
- * or if no signing key is specified. See
- * {@link Crypt_GPG::addEncryptKey()} and
- * {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG::decryptAndVerifyFile()
- */
- public function encryptAndSignFile($filename, $signedFile = null,
- $armor = true
- ) {
- return $this->_encryptAndSign($filename, true, $signedFile, $armor);
- }
-
- // }}}
- // {{{ decrypt()
-
- /**
- * Decrypts string data
- *
- * This method assumes the required private key is available in the keyring
- * and throws an exception if the private key is not available. To add a
- * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
- * {@link Crypt_GPG::importKeyFile()} methods.
- *
- * @param string $encryptedData the data to be decrypted.
- *
- * @return string the decrypted data.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function decrypt($encryptedData)
- {
- return $this->_decrypt($encryptedData, false, null);
- }
-
- // }}}
- // {{{ decryptFile()
-
- /**
- * Decrypts a file
- *
- * This method assumes the required private key is available in the keyring
- * and throws an exception if the private key is not available. To add a
- * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
- * {@link Crypt_GPG::importKeyFile()} methods.
- *
- * @param string $encryptedFile the name of the encrypted file data to
- * decrypt.
- * @param string $decryptedFile optional. The name of the file to which the
- * decrypted data should be written. If null
- * or unspecified, the decrypted data is
- * returned as a string.
- *
- * @return void|string if the <kbd>$decryptedFile</kbd> parameter is null,
- * a string containing the decrypted data is returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function decryptFile($encryptedFile, $decryptedFile = null)
- {
- return $this->_decrypt($encryptedFile, true, $decryptedFile);
- }
-
- // }}}
- // {{{ decryptAndVerify()
-
- /**
- * Decrypts and verifies string data
- *
- * This method assumes the required private key is available in the keyring
- * and throws an exception if the private key is not available. To add a
- * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
- * {@link Crypt_GPG::importKeyFile()} methods.
- *
- * @param string $encryptedData the encrypted, signed data to be decrypted
- * and verified.
- *
- * @return array two element array. The array has an element 'data'
- * containing the decrypted data and an element
- * 'signatures' containing an array of
- * {@link Crypt_GPG_Signature} objects for the signed data.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function decryptAndVerify($encryptedData)
- {
- return $this->_decryptAndVerify($encryptedData, false, null);
- }
-
- // }}}
- // {{{ decryptAndVerifyFile()
-
- /**
- * Decrypts and verifies a signed, encrypted file
- *
- * This method assumes the required private key is available in the keyring
- * and throws an exception if the private key is not available. To add a
- * private key to the keyring, use the {@link Crypt_GPG::importKey()} or
- * {@link Crypt_GPG::importKeyFile()} methods.
- *
- * @param string $encryptedFile the name of the signed, encrypted file to
- * to decrypt and verify.
- * @param string $decryptedFile optional. The name of the file to which the
- * decrypted data should be written. If null
- * or unspecified, the decrypted data is
- * returned in the results array.
- *
- * @return array two element array. The array has an element 'data'
- * containing the decrypted data and an element
- * 'signatures' containing an array of
- * {@link Crypt_GPG_Signature} objects for the signed data.
- * If the decrypted data is written to a file, the 'data'
- * element is null.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function decryptAndVerifyFile($encryptedFile, $decryptedFile = null)
- {
- return $this->_decryptAndVerify($encryptedFile, true, $decryptedFile);
- }
-
- // }}}
- // {{{ sign()
-
- /**
- * Signs data
- *
- * Data may be signed using any one of the three available signing modes:
- * - {@link Crypt_GPG::SIGN_MODE_NORMAL}
- * - {@link Crypt_GPG::SIGN_MODE_CLEAR}
- * - {@link Crypt_GPG::SIGN_MODE_DETACHED}
- *
- * @param string $data the data to be signed.
- * @param boolean $mode optional. The data signing mode to use. Should
- * be one of {@link Crypt_GPG::SIGN_MODE_NORMAL},
- * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
- * {@link Crypt_GPG::SIGN_MODE_DETACHED}. If not
- * specified, defaults to
- * <kbd>Crypt_GPG::SIGN_MODE_NORMAL</kbd>.
- * @param boolean $armor optional. If true, ASCII armored data is
- * returned; otherwise, binary data is returned.
- * Defaults to true. This has no effect if the
- * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used.
- * @param boolean $textmode optional. If true, line-breaks in signed data
- * are normalized. Use this option when signing
- * e-mail, or for greater compatibility between
- * systems with different line-break formats.
- * Defaults to false. This has no effect if the
- * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used as clear-signing always uses textmode.
- *
- * @return string the signed data, or the signature data if a detached
- * signature is requested.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
- * See {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function sign($data, $mode = Crypt_GPG::SIGN_MODE_NORMAL,
- $armor = true, $textmode = false
- ) {
- return $this->_sign($data, false, null, $mode, $armor, $textmode);
- }
-
- // }}}
- // {{{ signFile()
-
- /**
- * Signs a file
- *
- * The file may be signed using any one of the three available signing
- * modes:
- * - {@link Crypt_GPG::SIGN_MODE_NORMAL}
- * - {@link Crypt_GPG::SIGN_MODE_CLEAR}
- * - {@link Crypt_GPG::SIGN_MODE_DETACHED}
- *
- * @param string $filename the name of the file containing the data to
- * be signed.
- * @param string $signedFile optional. The name of the file in which the
- * signed data should be stored. If null or
- * unspecified, the signed data is returned as a
- * string.
- * @param boolean $mode optional. The data signing mode to use. Should
- * be one of {@link Crypt_GPG::SIGN_MODE_NORMAL},
- * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
- * {@link Crypt_GPG::SIGN_MODE_DETACHED}. If not
- * specified, defaults to
- * <kbd>Crypt_GPG::SIGN_MODE_NORMAL</kbd>.
- * @param boolean $armor optional. If true, ASCII armored data is
- * returned; otherwise, binary data is returned.
- * Defaults to true. This has no effect if the
- * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used.
- * @param boolean $textmode optional. If true, line-breaks in signed data
- * are normalized. Use this option when signing
- * e-mail, or for greater compatibility between
- * systems with different line-break formats.
- * Defaults to false. This has no effect if the
- * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used as clear-signing always uses textmode.
- *
- * @return void|string if the <kbd>$signedFile</kbd> parameter is null, a
- * string containing the signed data (or the signature
- * data if a detached signature is requested) is
- * returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
- * See {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- public function signFile($filename, $signedFile = null,
- $mode = Crypt_GPG::SIGN_MODE_NORMAL, $armor = true, $textmode = false
- ) {
- return $this->_sign(
- $filename,
- true,
- $signedFile,
- $mode,
- $armor,
- $textmode
- );
- }
-
- // }}}
- // {{{ verify()
-
- /**
- * Verifies signed data
- *
- * The {@link Crypt_GPG::decrypt()} method may be used to get the original
- * message if the signed data is not clearsigned and does not use a
- * detached signature.
- *
- * @param string $signedData the signed data to be verified.
- * @param string $signature optional. If verifying data signed using a
- * detached signature, this must be the detached
- * signature data. The data that was signed is
- * specified in <kbd>$signedData</kbd>.
- *
- * @return array an array of {@link Crypt_GPG_Signature} objects for the
- * signed data. For each signature that is valid, the
- * {@link Crypt_GPG_Signature::isValid()} will return true.
- *
- * @throws Crypt_GPG_NoDataException if the provided data is not signed
- * data.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG_Signature
- */
- public function verify($signedData, $signature = '')
- {
- return $this->_verify($signedData, false, $signature);
- }
-
- // }}}
- // {{{ verifyFile()
-
- /**
- * Verifies a signed file
- *
- * The {@link Crypt_GPG::decryptFile()} method may be used to get the
- * original message if the signed data is not clearsigned and does not use
- * a detached signature.
- *
- * @param string $filename the signed file to be verified.
- * @param string $signature optional. If verifying a file signed using a
- * detached signature, this must be the detached
- * signature data. The file that was signed is
- * specified in <kbd>$filename</kbd>.
- *
- * @return array an array of {@link Crypt_GPG_Signature} objects for the
- * signed data. For each signature that is valid, the
- * {@link Crypt_GPG_Signature::isValid()} will return true.
- *
- * @throws Crypt_GPG_NoDataException if the provided data is not signed
- * data.
- *
- * @throws Crypt_GPG_FileException if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG_Signature
- */
- public function verifyFile($filename, $signature = '')
- {
- return $this->_verify($filename, true, $signature);
- }
-
- // }}}
- // {{{ addDecryptKey()
-
- /**
- * Adds a key to use for decryption
- *
- * @param mixed $key the key to use. This may be a key identifier,
- * user id, fingerprint, {@link Crypt_GPG_Key} or
- * {@link Crypt_GPG_SubKey}. The key must be able
- * to encrypt.
- * @param string $passphrase optional. The passphrase of the key required
- * for decryption.
- *
- * @return void
- *
- * @see Crypt_GPG::decrypt()
- * @see Crypt_GPG::decryptFile()
- * @see Crypt_GPG::clearDecryptKeys()
- * @see Crypt_GPG::_addKey()
- * @see Crypt_GPG_DecryptStatusHandler
- *
- * @sensitive $passphrase
- */
- public function addDecryptKey($key, $passphrase = null)
- {
- $this->_addKey($this->decryptKeys, true, false, $key, $passphrase);
- }
-
- // }}}
- // {{{ addEncryptKey()
-
- /**
- * Adds a key to use for encryption
- *
- * @param mixed $key the key to use. This may be a key identifier, user id
- * user id, fingerprint, {@link Crypt_GPG_Key} or
- * {@link Crypt_GPG_SubKey}. The key must be able to
- * encrypt.
- *
- * @return void
- *
- * @see Crypt_GPG::encrypt()
- * @see Crypt_GPG::encryptFile()
- * @see Crypt_GPG::clearEncryptKeys()
- * @see Crypt_GPG::_addKey()
- */
- public function addEncryptKey($key)
- {
- $this->_addKey($this->encryptKeys, true, false, $key);
- }
-
- // }}}
- // {{{ addSignKey()
-
- /**
- * Adds a key to use for signing
- *
- * @param mixed $key the key to use. This may be a key identifier,
- * user id, fingerprint, {@link Crypt_GPG_Key} or
- * {@link Crypt_GPG_SubKey}. The key must be able
- * to sign.
- * @param string $passphrase optional. The passphrase of the key required
- * for signing.
- *
- * @return void
- *
- * @see Crypt_GPG::sign()
- * @see Crypt_GPG::signFile()
- * @see Crypt_GPG::clearSignKeys()
- * @see Crypt_GPG::handleSignStatus()
- * @see Crypt_GPG::_addKey()
- *
- * @sensitive $passphrase
- */
- public function addSignKey($key, $passphrase = null)
- {
- $this->_addKey($this->signKeys, false, true, $key, $passphrase);
- }
-
- // }}}
- // {{{ clearDecryptKeys()
-
- /**
- * Clears all decryption keys
- *
- * @return void
- *
- * @see Crypt_GPG::decrypt()
- * @see Crypt_GPG::addDecryptKey()
- */
- public function clearDecryptKeys()
- {
- $this->decryptKeys = array();
- }
-
- // }}}
- // {{{ clearEncryptKeys()
-
- /**
- * Clears all encryption keys
- *
- * @return void
- *
- * @see Crypt_GPG::encrypt()
- * @see Crypt_GPG::addEncryptKey()
- */
- public function clearEncryptKeys()
- {
- $this->encryptKeys = array();
- }
-
- // }}}
- // {{{ clearSignKeys()
-
- /**
- * Clears all signing keys
- *
- * @return void
- *
- * @see Crypt_GPG::sign()
- * @see Crypt_GPG::addSignKey()
- */
- public function clearSignKeys()
- {
- $this->signKeys = array();
- }
-
- // }}}
- // {{{ handleSignStatus()
-
- /**
- * Handles the status output from GPG for the sign operation
- *
- * This method is responsible for sending the passphrase commands when
- * required by the {@link Crypt_GPG::sign()} method. See <b>doc/DETAILS</b>
- * in the {@link http://www.gnupg.org/download/ GPG distribution} for
- * detailed information on GPG's status output.
- *
- * @param string $line the status line to handle.
- *
- * @return void
- *
- * @see Crypt_GPG::sign()
- */
- public function handleSignStatus($line)
- {
- $tokens = explode(' ', $line);
- switch ($tokens[0]) {
- case 'NEED_PASSPHRASE':
- $subKeyId = $tokens[1];
- if (array_key_exists($subKeyId, $this->signKeys)) {
- $passphrase = $this->signKeys[$subKeyId]['passphrase'];
- $this->engine->sendCommand($passphrase);
- } else {
- $this->engine->sendCommand('');
- }
- break;
- }
- }
-
- // }}}
- // {{{ handleImportKeyStatus()
-
- /**
- * Handles the status output from GPG for the import operation
- *
- * This method is responsible for building the result array that is
- * returned from the {@link Crypt_GPG::importKey()} method. See
- * <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
- * information on GPG's status output.
- *
- * @param string $line the status line to handle.
- * @param array &$result the current result array being processed.
- *
- * @return void
- *
- * @see Crypt_GPG::importKey()
- * @see Crypt_GPG::importKeyFile()
- * @see Crypt_GPG_Engine::addStatusHandler()
- */
- public function handleImportKeyStatus($line, array &$result)
- {
- $tokens = explode(' ', $line);
- switch ($tokens[0]) {
- case 'IMPORT_OK':
- $result['fingerprint'] = $tokens[2];
- break;
-
- case 'IMPORT_RES':
- $result['public_imported'] = intval($tokens[3]);
- $result['public_unchanged'] = intval($tokens[5]);
- $result['private_imported'] = intval($tokens[11]);
- $result['private_unchanged'] = intval($tokens[12]);
- break;
- }
- }
-
- // }}}
- // {{{ setEngine()
-
- /**
- * Sets the I/O engine to use for GnuPG operations
- *
- * Normally this method does not need to be used. It provides a means for
- * dependency injection.
- *
- * @param Crypt_GPG_Engine $engine the engine to use.
- *
- * @return void
- */
- public function setEngine(Crypt_GPG_Engine $engine)
- {
- $this->engine = $engine;
- }
-
- // }}}
- // {{{ _addKey()
-
- /**
- * Adds a key to one of the internal key arrays
- *
- * This handles resolving full key objects from the provided
- * <kbd>$key</kbd> value.
- *
- * @param array &$array the array to which the key should be added.
- * @param boolean $encrypt whether or not the key must be able to
- * encrypt.
- * @param boolean $sign whether or not the key must be able to sign.
- * @param mixed $key the key to add. This may be a key identifier,
- * user id, fingerprint, {@link Crypt_GPG_Key} or
- * {@link Crypt_GPG_SubKey}.
- * @param string $passphrase optional. The passphrase associated with the
- * key.
- *
- * @return void
- *
- * @sensitive $passphrase
- */
- private function _addKey(array &$array, $encrypt, $sign, $key,
- $passphrase = null
- ) {
- $subKeys = array();
-
- if (is_scalar($key)) {
- $keys = $this->getKeys($key);
- if (count($keys) == 0) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'Key "' . $key . '" not found.', 0, $key);
- }
- $key = $keys[0];
- }
-
- if ($key instanceof Crypt_GPG_Key) {
- if ($encrypt && !$key->canEncrypt()) {
- throw new InvalidArgumentException(
- 'Key "' . $key . '" cannot encrypt.');
- }
-
- if ($sign && !$key->canSign()) {
- throw new InvalidArgumentException(
- 'Key "' . $key . '" cannot sign.');
- }
-
- foreach ($key->getSubKeys() as $subKey) {
- $canEncrypt = $subKey->canEncrypt();
- $canSign = $subKey->canSign();
- if ( ($encrypt && $sign && $canEncrypt && $canSign)
- || ($encrypt && !$sign && $canEncrypt)
- || (!$encrypt && $sign && $canSign)
- ) {
- // We add all subkeys that meet the requirements because we
- // were not told which subkey is required.
- $subKeys[] = $subKey;
- }
- }
- } elseif ($key instanceof Crypt_GPG_SubKey) {
- $subKeys[] = $key;
- }
-
- if (count($subKeys) === 0) {
- throw new InvalidArgumentException(
- 'Key "' . $key . '" is not in a recognized format.');
- }
-
- foreach ($subKeys as $subKey) {
- if ($encrypt && !$subKey->canEncrypt()) {
- throw new InvalidArgumentException(
- 'Key "' . $key . '" cannot encrypt.');
- }
-
- if ($sign && !$subKey->canSign()) {
- throw new InvalidArgumentException(
- 'Key "' . $key . '" cannot sign.');
- }
-
- $array[$subKey->getId()] = array(
- 'fingerprint' => $subKey->getFingerprint(),
- 'passphrase' => $passphrase
- );
- }
- }
-
- // }}}
- // {{{ _importKey()
-
- /**
- * Imports a public or private key into the keyring
- *
- * @param string $key the key to be imported.
- * @param boolean $isFile whether or not the input is a filename.
- *
- * @return array an associative array containing the following elements:
- * - <kbd>fingerprint</kbd> - the fingerprint of the
- * imported key,
- * - <kbd>public_imported</kbd> - the number of public
- * keys imported,
- * - <kbd>public_unchanged</kbd> - the number of unchanged
- * public keys,
- * - <kbd>private_imported</kbd> - the number of private
- * keys imported,
- * - <kbd>private_unchanged</kbd> - the number of unchanged
- * private keys.
- *
- * @throws Crypt_GPG_NoDataException if the key data is missing or if the
- * data is is not valid key data.
- *
- * @throws Crypt_GPG_FileException if the key file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- private function _importKey($key, $isFile)
- {
- $result = array();
-
- if ($isFile) {
- $input = @fopen($key, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open key file "' .
- $key . '" for importing.', 0, $key);
- }
- } else {
- $input = strval($key);
- if ($input == '') {
- throw new Crypt_GPG_NoDataException(
- 'No valid GPG key data found.', Crypt_GPG::ERROR_NO_DATA);
- }
- }
-
- $arguments = array();
- $version = $this->engine->getVersion();
-
- if ( version_compare($version, '1.0.5', 'ge')
- && version_compare($version, '1.0.7', 'lt')
- ) {
- $arguments[] = '--allow-secret-key-import';
- }
-
- $this->engine->reset();
- $this->engine->addStatusHandler(
- array($this, 'handleImportKeyStatus'),
- array(&$result)
- );
-
- $this->engine->setOperation('--import', $arguments);
- $this->engine->setInput($input);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_DUPLICATE_KEY:
- case Crypt_GPG::ERROR_NONE:
- // ignore duplicate key import errors
- break;
- case Crypt_GPG::ERROR_NO_DATA:
- throw new Crypt_GPG_NoDataException(
- 'No valid GPG key data found.', $code);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error importing GPG key. Please use the \'debug\' ' .
- 'option when creating the Crypt_GPG object, and file a bug ' .
- 'report at ' . self::BUG_URI, $code);
- }
-
- return $result;
- }
-
- // }}}
- // {{{ _encrypt()
-
- /**
- * Encrypts data
- *
- * @param string $data the data to encrypt.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $outputFile the filename of the file in which to store
- * the encrypted data. If null, the encrypted
- * data is returned as a string.
- * @param boolean $armor if true, ASCII armored data is returned;
- * otherwise, binary data is returned.
- *
- * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
- * string containing the encrypted data is returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified.
- * See {@link Crypt_GPG::addEncryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- private function _encrypt($data, $isFile, $outputFile, $armor)
- {
- if (count($this->encryptKeys) === 0) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'No encryption keys specified.');
- }
-
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input file "' .
- $data . '" for encryption.', 0, $data);
- }
- } else {
- $input = strval($data);
- }
-
- if ($outputFile === null) {
- $output = '';
- } else {
- $output = @fopen($outputFile, 'wb');
- if ($output === false) {
- if ($isFile) {
- fclose($input);
- }
- throw new Crypt_GPG_FileException('Could not open output ' .
- 'file "' . $outputFile . '" for storing encrypted data.',
- 0, $outputFile);
- }
- }
-
- $arguments = ($armor) ? array('--armor') : array();
- foreach ($this->encryptKeys as $key) {
- $arguments[] = '--recipient ' . escapeshellarg($key['fingerprint']);
- }
-
- $this->engine->reset();
- $this->engine->setInput($input);
- $this->engine->setOutput($output);
- $this->engine->setOperation('--encrypt', $arguments);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- if ($outputFile !== null) {
- fclose($output);
- }
-
- $code = $this->engine->getErrorCode();
-
- if ($code !== Crypt_GPG::ERROR_NONE) {
- throw new Crypt_GPG_Exception(
- 'Unknown error encrypting data. Please use the \'debug\' ' .
- 'option when creating the Crypt_GPG object, and file a bug ' .
- 'report at ' . self::BUG_URI, $code);
- }
-
- if ($outputFile === null) {
- return $output;
- }
- }
-
- // }}}
- // {{{ _decrypt()
-
- /**
- * Decrypts data
- *
- * @param string $data the data to be decrypted.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $outputFile the name of the file to which the decrypted
- * data should be written. If null, the decrypted
- * data is returned as a string.
- *
- * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
- * string containing the decrypted data is returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- private function _decrypt($data, $isFile, $outputFile)
- {
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input file "' .
- $data . '" for decryption.', 0, $data);
- }
- } else {
- $input = strval($data);
- if ($input == '') {
- throw new Crypt_GPG_NoDataException(
- 'Cannot decrypt data. No PGP encrypted data was found in '.
- 'the provided data.', Crypt_GPG::ERROR_NO_DATA);
- }
- }
-
- if ($outputFile === null) {
- $output = '';
- } else {
- $output = @fopen($outputFile, 'wb');
- if ($output === false) {
- if ($isFile) {
- fclose($input);
- }
- throw new Crypt_GPG_FileException('Could not open output ' .
- 'file "' . $outputFile . '" for storing decrypted data.',
- 0, $outputFile);
- }
- }
-
- $handler = new Crypt_GPG_DecryptStatusHandler($this->engine,
- $this->decryptKeys);
-
- $this->engine->reset();
- $this->engine->addStatusHandler(array($handler, 'handle'));
- $this->engine->setOperation('--decrypt');
- $this->engine->setInput($input);
- $this->engine->setOutput($output);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- if ($outputFile !== null) {
- fclose($output);
- }
-
- // if there was any problem decrypting the data, the handler will
- // deal with it here.
- $handler->throwException();
-
- if ($outputFile === null) {
- return $output;
- }
- }
-
- // }}}
- // {{{ _sign()
-
- /**
- * Signs data
- *
- * @param string $data the data to be signed.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $outputFile the name of the file in which the signed data
- * should be stored. If null, the signed data is
- * returned as a string.
- * @param boolean $mode the data signing mode to use. Should be one of
- * {@link Crypt_GPG::SIGN_MODE_NORMAL},
- * {@link Crypt_GPG::SIGN_MODE_CLEAR} or
- * {@link Crypt_GPG::SIGN_MODE_DETACHED}.
- * @param boolean $armor if true, ASCII armored data is returned;
- * otherwise, binary data is returned. This has
- * no effect if the mode
- * <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used.
- * @param boolean $textmode if true, line-breaks in signed data be
- * normalized. Use this option when signing
- * e-mail, or for greater compatibility between
- * systems with different line-break formats.
- * Defaults to false. This has no effect if the
- * mode <kbd>Crypt_GPG::SIGN_MODE_CLEAR</kbd> is
- * used as clear-signing always uses textmode.
- *
- * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
- * string containing the signed data (or the signature
- * data if a detached signature is requested) is
- * returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no signing key is specified.
- * See {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- private function _sign($data, $isFile, $outputFile, $mode, $armor,
- $textmode
- ) {
- if (count($this->signKeys) === 0) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'No signing keys specified.');
- }
-
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input ' .
- 'file "' . $data . '" for signing.', 0, $data);
- }
- } else {
- $input = strval($data);
- }
-
- if ($outputFile === null) {
- $output = '';
- } else {
- $output = @fopen($outputFile, 'wb');
- if ($output === false) {
- if ($isFile) {
- fclose($input);
- }
- throw new Crypt_GPG_FileException('Could not open output ' .
- 'file "' . $outputFile . '" for storing signed ' .
- 'data.', 0, $outputFile);
- }
- }
-
- switch ($mode) {
- case Crypt_GPG::SIGN_MODE_DETACHED:
- $operation = '--detach-sign';
- break;
- case Crypt_GPG::SIGN_MODE_CLEAR:
- $operation = '--clearsign';
- break;
- case Crypt_GPG::SIGN_MODE_NORMAL:
- default:
- $operation = '--sign';
- break;
- }
-
- $arguments = array();
-
- if ($armor) {
- $arguments[] = '--armor';
- }
- if ($textmode) {
- $arguments[] = '--textmode';
- }
-
- foreach ($this->signKeys as $key) {
- $arguments[] = '--local-user ' .
- escapeshellarg($key['fingerprint']);
- }
-
- $this->engine->reset();
- $this->engine->addStatusHandler(array($this, 'handleSignStatus'));
- $this->engine->setInput($input);
- $this->engine->setOutput($output);
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- if ($outputFile !== null) {
- fclose($output);
- }
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- break;
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- throw new Crypt_GPG_KeyNotFoundException(
- 'Cannot sign data. Private key not found. Import the '.
- 'private key before trying to sign data.', $code,
- $this->engine->getErrorKeyId());
- case Crypt_GPG::ERROR_BAD_PASSPHRASE:
- throw new Crypt_GPG_BadPassphraseException(
- 'Cannot sign data. Incorrect passphrase provided.', $code);
- case Crypt_GPG::ERROR_MISSING_PASSPHRASE:
- throw new Crypt_GPG_BadPassphraseException(
- 'Cannot sign data. No passphrase provided.', $code);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error signing data. Please use the \'debug\' option ' .
- 'when creating the Crypt_GPG object, and file a bug report ' .
- 'at ' . self::BUG_URI, $code);
- }
-
- if ($outputFile === null) {
- return $output;
- }
- }
-
- // }}}
- // {{{ _encryptAndSign()
-
- /**
- * Encrypts and signs data
- *
- * @param string $data the data to be encrypted and signed.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $outputFile the name of the file in which the encrypted,
- * signed data should be stored. If null, the
- * encrypted, signed data is returned as a
- * string.
- * @param boolean $armor if true, ASCII armored data is returned;
- * otherwise, binary data is returned.
- *
- * @return void|string if the <kbd>$outputFile</kbd> parameter is null, a
- * string containing the encrypted, signed data is
- * returned.
- *
- * @throws Crypt_GPG_KeyNotFoundException if no encryption key is specified
- * or if no signing key is specified. See
- * {@link Crypt_GPG::addEncryptKey()} and
- * {@link Crypt_GPG::addSignKey()}.
- *
- * @throws Crypt_GPG_BadPassphraseException if a specified passphrase is
- * incorrect or if a required passphrase is not specified.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- */
- private function _encryptAndSign($data, $isFile, $outputFile, $armor)
- {
- if (count($this->signKeys) === 0) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'No signing keys specified.');
- }
-
- if (count($this->encryptKeys) === 0) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'No encryption keys specified.');
- }
-
-
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input ' .
- 'file "' . $data . '" for encrypting and signing.', 0,
- $data);
- }
- } else {
- $input = strval($data);
- }
-
- if ($outputFile === null) {
- $output = '';
- } else {
- $output = @fopen($outputFile, 'wb');
- if ($output === false) {
- if ($isFile) {
- fclose($input);
- }
- throw new Crypt_GPG_FileException('Could not open output ' .
- 'file "' . $outputFile . '" for storing encrypted, ' .
- 'signed data.', 0, $outputFile);
- }
- }
-
- $arguments = ($armor) ? array('--armor') : array();
-
- foreach ($this->signKeys as $key) {
- $arguments[] = '--local-user ' .
- escapeshellarg($key['fingerprint']);
- }
-
- foreach ($this->encryptKeys as $key) {
- $arguments[] = '--recipient ' . escapeshellarg($key['fingerprint']);
- }
-
- $this->engine->reset();
- $this->engine->addStatusHandler(array($this, 'handleSignStatus'));
- $this->engine->setInput($input);
- $this->engine->setOutput($output);
- $this->engine->setOperation('--encrypt --sign', $arguments);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- if ($outputFile !== null) {
- fclose($output);
- }
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- break;
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- throw new Crypt_GPG_KeyNotFoundException(
- 'Cannot sign encrypted data. Private key not found. Import '.
- 'the private key before trying to sign the encrypted data.',
- $code, $this->engine->getErrorKeyId());
- case Crypt_GPG::ERROR_BAD_PASSPHRASE:
- throw new Crypt_GPG_BadPassphraseException(
- 'Cannot sign encrypted data. Incorrect passphrase provided.',
- $code);
- case Crypt_GPG::ERROR_MISSING_PASSPHRASE:
- throw new Crypt_GPG_BadPassphraseException(
- 'Cannot sign encrypted data. No passphrase provided.', $code);
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error encrypting and signing data. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
-
- if ($outputFile === null) {
- return $output;
- }
- }
-
- // }}}
- // {{{ _verify()
-
- /**
- * Verifies data
- *
- * @param string $data the signed data to be verified.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $signature if verifying a file signed using a detached
- * signature, this must be the detached signature
- * data. Otherwise, specify ''.
- *
- * @return array an array of {@link Crypt_GPG_Signature} objects for the
- * signed data.
- *
- * @throws Crypt_GPG_NoDataException if the provided data is not signed
- * data.
- *
- * @throws Crypt_GPG_FileException if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG_Signature
- */
- private function _verify($data, $isFile, $signature)
- {
- if ($signature == '') {
- $operation = '--verify';
- $arguments = array();
- } else {
- // Signed data goes in FD_MESSAGE, detached signature data goes in
- // FD_INPUT.
- $operation = '--verify - "-&' . Crypt_GPG_Engine::FD_MESSAGE. '"';
- $arguments = array('--enable-special-filenames');
- }
-
- $handler = new Crypt_GPG_VerifyStatusHandler();
-
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input ' .
- 'file "' . $data . '" for verifying.', 0, $data);
- }
- } else {
- $input = strval($data);
- if ($input == '') {
- throw new Crypt_GPG_NoDataException(
- 'No valid signature data found.', Crypt_GPG::ERROR_NO_DATA);
- }
- }
-
- $this->engine->reset();
- $this->engine->addStatusHandler(array($handler, 'handle'));
-
- if ($signature == '') {
- // signed or clearsigned data
- $this->engine->setInput($input);
- } else {
- // detached signature
- $this->engine->setInput($signature);
- $this->engine->setMessage($input);
- }
-
- $this->engine->setOperation($operation, $arguments);
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- $code = $this->engine->getErrorCode();
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- case Crypt_GPG::ERROR_BAD_SIGNATURE:
- break;
- case Crypt_GPG::ERROR_NO_DATA:
- throw new Crypt_GPG_NoDataException(
- 'No valid signature data found.', $code);
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- throw new Crypt_GPG_KeyNotFoundException(
- 'Public key required for data verification not in keyring.',
- $code, $this->engine->getErrorKeyId());
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error validating signature details. Please use the ' .
- '\'debug\' option when creating the Crypt_GPG object, and ' .
- 'file a bug report at ' . self::BUG_URI, $code);
- }
-
- return $handler->getSignatures();
- }
-
- // }}}
- // {{{ _decryptAndVerify()
-
- /**
- * Decrypts and verifies encrypted, signed data
- *
- * @param string $data the encrypted signed data to be decrypted and
- * verified.
- * @param boolean $isFile whether or not the data is a filename.
- * @param string $outputFile the name of the file to which the decrypted
- * data should be written. If null, the decrypted
- * data is returned in the results array.
- *
- * @return array two element array. The array has an element 'data'
- * containing the decrypted data and an element
- * 'signatures' containing an array of
- * {@link Crypt_GPG_Signature} objects for the signed data.
- * If the decrypted data is written to a file, the 'data'
- * element is null.
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring or it the public
- * key needed for verification is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG signed, encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_FileException if the output file is not writeable or
- * if the input file is not readable.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @see Crypt_GPG_Signature
- */
- private function _decryptAndVerify($data, $isFile, $outputFile)
- {
- if ($isFile) {
- $input = @fopen($data, 'rb');
- if ($input === false) {
- throw new Crypt_GPG_FileException('Could not open input ' .
- 'file "' . $data . '" for decrypting and verifying.', 0,
- $data);
- }
- } else {
- $input = strval($data);
- if ($input == '') {
- throw new Crypt_GPG_NoDataException(
- 'No valid encrypted signed data found.',
- Crypt_GPG::ERROR_NO_DATA);
- }
- }
-
- if ($outputFile === null) {
- $output = '';
- } else {
- $output = @fopen($outputFile, 'wb');
- if ($output === false) {
- if ($isFile) {
- fclose($input);
- }
- throw new Crypt_GPG_FileException('Could not open output ' .
- 'file "' . $outputFile . '" for storing decrypted data.',
- 0, $outputFile);
- }
- }
-
- $verifyHandler = new Crypt_GPG_VerifyStatusHandler();
-
- $decryptHandler = new Crypt_GPG_DecryptStatusHandler($this->engine,
- $this->decryptKeys);
-
- $this->engine->reset();
- $this->engine->addStatusHandler(array($verifyHandler, 'handle'));
- $this->engine->addStatusHandler(array($decryptHandler, 'handle'));
- $this->engine->setInput($input);
- $this->engine->setOutput($output);
- $this->engine->setOperation('--decrypt');
- $this->engine->run();
-
- if ($isFile) {
- fclose($input);
- }
-
- if ($outputFile !== null) {
- fclose($output);
- }
-
- $return = array(
- 'data' => null,
- 'signatures' => $verifyHandler->getSignatures()
- );
-
- // if there was any problem decrypting the data, the handler will
- // deal with it here.
- try {
- $decryptHandler->throwException();
- } catch (Exception $e) {
- if ($e instanceof Crypt_GPG_KeyNotFoundException) {
- throw new Crypt_GPG_KeyNotFoundException(
- 'Public key required for data verification not in ',
- 'the keyring. Either no suitable private decryption key ' .
- 'is in the keyring or the public key required for data ' .
- 'verification is not in the keyring. Import a suitable ' .
- 'key before trying to decrypt and verify this data.',
- self::ERROR_KEY_NOT_FOUND, $this->engine->getErrorKeyId());
- }
-
- if ($e instanceof Crypt_GPG_NoDataException) {
- throw new Crypt_GPG_NoDataException(
- 'Cannot decrypt and verify data. No PGP encrypted data ' .
- 'was found in the provided data.', self::ERROR_NO_DATA);
- }
-
- throw $e;
- }
-
- if ($outputFile === null) {
- $return['data'] = $output;
- }
-
- return $return;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php b/plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php
deleted file mode 100644
index 40e8d50ed..000000000
--- a/plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php
+++ /dev/null
@@ -1,336 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Crypt_GPG is a package to use GPG from PHP
- *
- * This file contains an object that handles GPG's status output for the
- * decrypt operation.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008-2009 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: DecryptStatusHandler.php 302814 2010-08-26 15:43:07Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-
-/**
- * Crypt_GPG base class
- */
-require_once 'Crypt/GPG.php';
-
-/**
- * GPG exception classes
- */
-require_once 'Crypt/GPG/Exceptions.php';
-
-
-/**
- * Status line handler for the decrypt operation
- *
- * This class is used internally by Crypt_GPG and does not need be used
- * directly. See the {@link Crypt_GPG} class for end-user API.
- *
- * This class is responsible for sending the passphrase commands when required
- * by the {@link Crypt_GPG::decrypt()} method. See <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
- * information on GPG's status output for the decrypt operation.
- *
- * This class is also responsible for parsing error status and throwing a
- * meaningful exception in the event that decryption fails.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-class Crypt_GPG_DecryptStatusHandler
-{
- // {{{ protected properties
-
- /**
- * Keys used to decrypt
- *
- * The array is of the form:
- * <code>
- * array(
- * $key_id => array(
- * 'fingerprint' => $fingerprint,
- * 'passphrase' => $passphrase
- * )
- * );
- * </code>
- *
- * @var array
- */
- protected $keys = array();
-
- /**
- * Engine used to which passphrases are passed
- *
- * @var Crypt_GPG_Engine
- */
- protected $engine = null;
-
- /**
- * The id of the current sub-key used for decryption
- *
- * @var string
- */
- protected $currentSubKey = '';
-
- /**
- * Whether or not decryption succeeded
- *
- * If the message is only signed (compressed) and not encrypted, this is
- * always true. If the message is encrypted, this flag is set to false
- * until we know the decryption succeeded.
- *
- * @var boolean
- */
- protected $decryptionOkay = true;
-
- /**
- * Whether or not there was no data for decryption
- *
- * @var boolean
- */
- protected $noData = false;
-
- /**
- * Keys for which the passhprase is missing
- *
- * This contains primary user ids indexed by sub-key id and is used to
- * create helpful exception messages.
- *
- * @var array
- */
- protected $missingPassphrases = array();
-
- /**
- * Keys for which the passhprase is incorrect
- *
- * This contains primary user ids indexed by sub-key id and is used to
- * create helpful exception messages.
- *
- * @var array
- */
- protected $badPassphrases = array();
-
- /**
- * Keys that can be used to decrypt the data but are missing from the
- * keychain
- *
- * This is an array with both the key and value being the sub-key id of
- * the missing keys.
- *
- * @var array
- */
- protected $missingKeys = array();
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new decryption status handler
- *
- * @param Crypt_GPG_Engine $engine the GPG engine to which passphrases are
- * passed.
- * @param array $keys the decryption keys to use.
- */
- public function __construct(Crypt_GPG_Engine $engine, array $keys)
- {
- $this->engine = $engine;
- $this->keys = $keys;
- }
-
- // }}}
- // {{{ handle()
-
- /**
- * Handles a status line
- *
- * @param string $line the status line to handle.
- *
- * @return void
- */
- public function handle($line)
- {
- $tokens = explode(' ', $line);
- switch ($tokens[0]) {
- case 'ENC_TO':
- // Now we know the message is encrypted. Set flag to check if
- // decryption succeeded.
- $this->decryptionOkay = false;
-
- // this is the new key message
- $this->currentSubKeyId = $tokens[1];
- break;
-
- case 'NEED_PASSPHRASE':
- // send passphrase to the GPG engine
- $subKeyId = $tokens[1];
- if (array_key_exists($subKeyId, $this->keys)) {
- $passphrase = $this->keys[$subKeyId]['passphrase'];
- $this->engine->sendCommand($passphrase);
- } else {
- $this->engine->sendCommand('');
- }
- break;
-
- case 'USERID_HINT':
- // remember the user id for pretty exception messages
- $this->badPassphrases[$tokens[1]]
- = implode(' ', array_splice($tokens, 2));
-
- break;
-
- case 'GOOD_PASSPHRASE':
- // if we got a good passphrase, remove the key from the list of
- // bad passphrases.
- unset($this->badPassphrases[$this->currentSubKeyId]);
- break;
-
- case 'MISSING_PASSPHRASE':
- $this->missingPassphrases[$this->currentSubKeyId]
- = $this->currentSubKeyId;
-
- break;
-
- case 'NO_SECKEY':
- // note: this message is also received if there are multiple
- // recipients and a previous key had a correct passphrase.
- $this->missingKeys[$tokens[1]] = $tokens[1];
- break;
-
- case 'NODATA':
- $this->noData = true;
- break;
-
- case 'DECRYPTION_OKAY':
- // If the message is encrypted, this is the all-clear signal.
- $this->decryptionOkay = true;
- break;
- }
- }
-
- // }}}
- // {{{ throwException()
-
- /**
- * Takes the final status of the decrypt operation and throws an
- * appropriate exception
- *
- * If decryption was successful, no exception is thrown.
- *
- * @return void
- *
- * @throws Crypt_GPG_KeyNotFoundException if the private key needed to
- * decrypt the data is not in the user's keyring.
- *
- * @throws Crypt_GPG_NoDataException if specified data does not contain
- * GPG encrypted data.
- *
- * @throws Crypt_GPG_BadPassphraseException if a required passphrase is
- * incorrect or if a required passphrase is not specified. See
- * {@link Crypt_GPG::addDecryptKey()}.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <i>debug</i> option and file a bug report if these
- * exceptions occur.
- */
- public function throwException()
- {
- $code = Crypt_GPG::ERROR_NONE;
-
- if (!$this->decryptionOkay) {
- if (count($this->badPassphrases) > 0) {
- $code = Crypt_GPG::ERROR_BAD_PASSPHRASE;
- } elseif (count($this->missingKeys) > 0) {
- $code = Crypt_GPG::ERROR_KEY_NOT_FOUND;
- } else {
- $code = Crypt_GPG::ERROR_UNKNOWN;
- }
- } elseif ($this->noData) {
- $code = Crypt_GPG::ERROR_NO_DATA;
- }
-
- switch ($code) {
- case Crypt_GPG::ERROR_NONE:
- break;
-
- case Crypt_GPG::ERROR_KEY_NOT_FOUND:
- if (count($this->missingKeys) > 0) {
- $keyId = reset($this->missingKeys);
- } else {
- $keyId = '';
- }
- throw new Crypt_GPG_KeyNotFoundException(
- 'Cannot decrypt data. No suitable private key is in the ' .
- 'keyring. Import a suitable private key before trying to ' .
- 'decrypt this data.', $code, $keyId);
-
- case Crypt_GPG::ERROR_BAD_PASSPHRASE:
- $badPassphrases = array_diff_key(
- $this->badPassphrases,
- $this->missingPassphrases
- );
-
- $missingPassphrases = array_intersect_key(
- $this->badPassphrases,
- $this->missingPassphrases
- );
-
- $message = 'Cannot decrypt data.';
- if (count($badPassphrases) > 0) {
- $message = ' Incorrect passphrase provided for keys: "' .
- implode('", "', $badPassphrases) . '".';
- }
- if (count($missingPassphrases) > 0) {
- $message = ' No passphrase provided for keys: "' .
- implode('", "', $badPassphrases) . '".';
- }
-
- throw new Crypt_GPG_BadPassphraseException($message, $code,
- $badPassphrases, $missingPassphrases);
-
- case Crypt_GPG::ERROR_NO_DATA:
- throw new Crypt_GPG_NoDataException(
- 'Cannot decrypt data. No PGP encrypted data was found in '.
- 'the provided data.', $code);
-
- default:
- throw new Crypt_GPG_Exception(
- 'Unknown error decrypting data.', $code);
- }
- }
-
- // }}}
-}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/Engine.php b/plugins/enigma/lib/Crypt/GPG/Engine.php
deleted file mode 100644
index 081be8e21..000000000
--- a/plugins/enigma/lib/Crypt/GPG/Engine.php
+++ /dev/null
@@ -1,1758 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Crypt_GPG is a package to use GPG from PHP
- *
- * This file contains an engine that handles GPG subprocess control and I/O.
- * PHP's process manipulation functions are used to handle the GPG subprocess.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: Engine.php 302822 2010-08-26 17:30:57Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-
-/**
- * Crypt_GPG base class.
- */
-require_once 'Crypt/GPG.php';
-
-/**
- * GPG exception classes.
- */
-require_once 'Crypt/GPG/Exceptions.php';
-
-/**
- * Standard PEAR exception is used if GPG binary is not found.
- */
-require_once 'PEAR/Exception.php';
-
-// {{{ class Crypt_GPG_Engine
-
-/**
- * Native PHP Crypt_GPG I/O engine
- *
- * This class is used internally by Crypt_GPG and does not need be used
- * directly. See the {@link Crypt_GPG} class for end-user API.
- *
- * This engine uses PHP's native process control functions to directly control
- * the GPG process. The GPG executable is required to be on the system.
- *
- * All data is passed to the GPG subprocess using file descriptors. This is the
- * most secure method of passing data to the GPG subprocess.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-class Crypt_GPG_Engine
-{
- // {{{ constants
-
- /**
- * Size of data chunks that are sent to and retrieved from the IPC pipes.
- *
- * PHP reads 8192 bytes. If this is set to less than 8192, PHP reads 8192
- * and buffers the rest so we might as well just read 8192.
- *
- * Using values other than 8192 also triggers PHP bugs.
- *
- * @see http://bugs.php.net/bug.php?id=35224
- */
- const CHUNK_SIZE = 8192;
-
- /**
- * Standard input file descriptor. This is used to pass data to the GPG
- * process.
- */
- const FD_INPUT = 0;
-
- /**
- * Standard output file descriptor. This is used to receive normal output
- * from the GPG process.
- */
- const FD_OUTPUT = 1;
-
- /**
- * Standard output file descriptor. This is used to receive error output
- * from the GPG process.
- */
- const FD_ERROR = 2;
-
- /**
- * GPG status output file descriptor. The status file descriptor outputs
- * detailed information for many GPG commands. See the second section of
- * the file <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG package} for a detailed
- * description of GPG's status output.
- */
- const FD_STATUS = 3;
-
- /**
- * Command input file descriptor. This is used for methods requiring
- * passphrases.
- */
- const FD_COMMAND = 4;
-
- /**
- * Extra message input file descriptor. This is used for passing signed
- * data when verifying a detached signature.
- */
- const FD_MESSAGE = 5;
-
- /**
- * Minimum version of GnuPG that is supported.
- */
- const MIN_VERSION = '1.0.2';
-
- // }}}
- // {{{ private class properties
-
- /**
- * Whether or not to use debugging mode
- *
- * When set to true, every GPG command is echoed before it is run. Sensitive
- * data is always handled using pipes and is not specified as part of the
- * command. As a result, sensitive data is never displayed when debug is
- * enabled. Sensitive data includes private key data and passphrases.
- *
- * Debugging is off by default.
- *
- * @var boolean
- * @see Crypt_GPG_Engine::__construct()
- */
- private $_debug = false;
-
- /**
- * Location of GPG binary
- *
- * @var string
- * @see Crypt_GPG_Engine::__construct()
- * @see Crypt_GPG_Engine::_getBinary()
- */
- private $_binary = '';
-
- /**
- * Directory containing the GPG key files
- *
- * This property only contains the path when the <i>homedir</i> option
- * is specified in the constructor.
- *
- * @var string
- * @see Crypt_GPG_Engine::__construct()
- */
- private $_homedir = '';
-
- /**
- * File path of the public keyring
- *
- * This property only contains the file path when the <i>public_keyring</i>
- * option is specified in the constructor.
- *
- * If the specified file path starts with <kbd>~/</kbd>, the path is
- * relative to the <i>homedir</i> if specified, otherwise to
- * <kbd>~/.gnupg</kbd>.
- *
- * @var string
- * @see Crypt_GPG_Engine::__construct()
- */
- private $_publicKeyring = '';
-
- /**
- * File path of the private (secret) keyring
- *
- * This property only contains the file path when the <i>private_keyring</i>
- * option is specified in the constructor.
- *
- * If the specified file path starts with <kbd>~/</kbd>, the path is
- * relative to the <i>homedir</i> if specified, otherwise to
- * <kbd>~/.gnupg</kbd>.
- *
- * @var string
- * @see Crypt_GPG_Engine::__construct()
- */
- private $_privateKeyring = '';
-
- /**
- * File path of the trust database
- *
- * This property only contains the file path when the <i>trust_db</i>
- * option is specified in the constructor.
- *
- * If the specified file path starts with <kbd>~/</kbd>, the path is
- * relative to the <i>homedir</i> if specified, otherwise to
- * <kbd>~/.gnupg</kbd>.
- *
- * @var string
- * @see Crypt_GPG_Engine::__construct()
- */
- private $_trustDb = '';
-
- /**
- * Array of pipes used for communication with the GPG binary
- *
- * This is an array of file descriptor resources.
- *
- * @var array
- */
- private $_pipes = array();
-
- /**
- * Array of currently opened pipes
- *
- * This array is used to keep track of remaining opened pipes so they can
- * be closed when the GPG subprocess is finished. This array is a subset of
- * the {@link Crypt_GPG_Engine::$_pipes} array and contains opened file
- * descriptor resources.
- *
- * @var array
- * @see Crypt_GPG_Engine::_closePipe()
- */
- private $_openPipes = array();
-
- /**
- * A handle for the GPG process
- *
- * @var resource
- */
- private $_process = null;
-
- /**
- * Whether or not the operating system is Darwin (OS X)
- *
- * @var boolean
- */
- private $_isDarwin = false;
-
- /**
- * Commands to be sent to GPG's command input stream
- *
- * @var string
- * @see Crypt_GPG_Engine::sendCommand()
- */
- private $_commandBuffer = '';
-
- /**
- * Array of status line handlers
- *
- * @var array
- * @see Crypt_GPG_Engine::addStatusHandler()
- */
- private $_statusHandlers = array();
-
- /**
- * Array of error line handlers
- *
- * @var array
- * @see Crypt_GPG_Engine::addErrorHandler()
- */
- private $_errorHandlers = array();
-
- /**
- * The error code of the current operation
- *
- * @var integer
- * @see Crypt_GPG_Engine::getErrorCode()
- */
- private $_errorCode = Crypt_GPG::ERROR_NONE;
-
- /**
- * File related to the error code of the current operation
- *
- * @var string
- * @see Crypt_GPG_Engine::getErrorFilename()
- */
- private $_errorFilename = '';
-
- /**
- * Key id related to the error code of the current operation
- *
- * @var string
- * @see Crypt_GPG_Engine::getErrorKeyId()
- */
- private $_errorkeyId = '';
-
- /**
- * The number of currently needed passphrases
- *
- * If this is not zero when the GPG command is completed, the error code is
- * set to {@link Crypt_GPG::ERROR_MISSING_PASSPHRASE}.
- *
- * @var integer
- */
- private $_needPassphrase = 0;
-
- /**
- * The input source
- *
- * This is data to send to GPG. Either a string or a stream resource.
- *
- * @var string|resource
- * @see Crypt_GPG_Engine::setInput()
- */
- private $_input = null;
-
- /**
- * The extra message input source
- *
- * Either a string or a stream resource.
- *
- * @var string|resource
- * @see Crypt_GPG_Engine::setMessage()
- */
- private $_message = null;
-
- /**
- * The output location
- *
- * This is where the output from GPG is sent. Either a string or a stream
- * resource.
- *
- * @var string|resource
- * @see Crypt_GPG_Engine::setOutput()
- */
- private $_output = '';
-
- /**
- * The GPG operation to execute
- *
- * @var string
- * @see Crypt_GPG_Engine::setOperation()
- */
- private $_operation;
-
- /**
- * Arguments for the current operation
- *
- * @var array
- * @see Crypt_GPG_Engine::setOperation()
- */
- private $_arguments = array();
-
- /**
- * The version number of the GPG binary
- *
- * @var string
- * @see Crypt_GPG_Engine::getVersion()
- */
- private $_version = '';
-
- /**
- * Cached value indicating whether or not mbstring function overloading is
- * on for strlen
- *
- * This is cached for optimal performance inside the I/O loop.
- *
- * @var boolean
- * @see Crypt_GPG_Engine::_byteLength()
- * @see Crypt_GPG_Engine::_byteSubstring()
- */
- private static $_mbStringOverload = null;
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new GPG engine
- *
- * Available options are:
- *
- * - <kbd>string homedir</kbd> - the directory where the GPG
- * keyring files are stored. If not
- * specified, Crypt_GPG uses the
- * default of <kbd>~/.gnupg</kbd>.
- * - <kbd>string publicKeyring</kbd> - the file path of the public
- * keyring. Use this if the public
- * keyring is not in the homedir, or
- * if the keyring is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * keyring with this option
- * (/foo/bar/pubring.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string privateKeyring</kbd> - the file path of the private
- * keyring. Use this if the private
- * keyring is not in the homedir, or
- * if the keyring is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * keyring with this option
- * (/foo/bar/secring.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string trustDb</kbd> - the file path of the web-of-trust
- * database. Use this if the trust
- * database is not in the homedir, or
- * if the database is in a directory
- * not writable by the process
- * invoking GPG (like Apache). Then
- * you can specify the path to the
- * trust database with this option
- * (/foo/bar/trustdb.gpg), and specify
- * a writable directory (like /tmp)
- * using the <i>homedir</i> option.
- * - <kbd>string binary</kbd> - the location of the GPG binary. If
- * not specified, the driver attempts
- * to auto-detect the GPG binary
- * location using a list of known
- * default locations for the current
- * operating system. The option
- * <kbd>gpgBinary</kbd> is a
- * deprecated alias for this option.
- * - <kbd>boolean debug</kbd> - whether or not to use debug mode.
- * When debug mode is on, all
- * communication to and from the GPG
- * subprocess is logged. This can be
- * useful to diagnose errors when
- * using Crypt_GPG.
- *
- * @param array $options optional. An array of options used to create the
- * GPG object. All options are optional and are
- * represented as key-value pairs.
- *
- * @throws Crypt_GPG_FileException if the <kbd>homedir</kbd> does not exist
- * and cannot be created. This can happen if <kbd>homedir</kbd> is
- * not specified, Crypt_GPG is run as the web user, and the web
- * user has no home directory. This exception is also thrown if any
- * of the options <kbd>publicKeyring</kbd>,
- * <kbd>privateKeyring</kbd> or <kbd>trustDb</kbd> options are
- * specified but the files do not exist or are are not readable.
- * This can happen if the user running the Crypt_GPG process (for
- * example, the Apache user) does not have permission to read the
- * files.
- *
- * @throws PEAR_Exception if the provided <kbd>binary</kbd> is invalid, or
- * if no <kbd>binary</kbd> is provided and no suitable binary could
- * be found.
- */
- public function __construct(array $options = array())
- {
- $this->_isDarwin = (strncmp(strtoupper(PHP_OS), 'DARWIN', 6) === 0);
-
- // populate mbstring overloading cache if not set
- if (self::$_mbStringOverload === null) {
- self::$_mbStringOverload = (extension_loaded('mbstring')
- && (ini_get('mbstring.func_overload') & 0x02) === 0x02);
- }
-
- // get homedir
- if (array_key_exists('homedir', $options)) {
- $this->_homedir = (string)$options['homedir'];
- } else {
- // note: this requires the package OS dep exclude 'windows'
- $info = posix_getpwuid(posix_getuid());
- $this->_homedir = $info['dir'].'/.gnupg';
- }
-
- // attempt to create homedir if it does not exist
- if (!is_dir($this->_homedir)) {
- if (@mkdir($this->_homedir, 0777, true)) {
- // Set permissions on homedir. Parent directories are created
- // with 0777, homedir is set to 0700.
- chmod($this->_homedir, 0700);
- } else {
- throw new Crypt_GPG_FileException('The \'homedir\' "' .
- $this->_homedir . '" is not readable or does not exist '.
- 'and cannot be created. This can happen if \'homedir\' '.
- 'is not specified in the Crypt_GPG options, Crypt_GPG is '.
- 'run as the web user, and the web user has no home '.
- 'directory.',
- 0, $this->_homedir);
- }
- }
-
- // get binary
- if (array_key_exists('binary', $options)) {
- $this->_binary = (string)$options['binary'];
- } elseif (array_key_exists('gpgBinary', $options)) {
- // deprecated alias
- $this->_binary = (string)$options['gpgBinary'];
- } else {
- $this->_binary = $this->_getBinary();
- }
-
- if ($this->_binary == '' || !is_executable($this->_binary)) {
- throw new PEAR_Exception('GPG binary not found. If you are sure '.
- 'the GPG binary is installed, please specify the location of '.
- 'the GPG binary using the \'binary\' driver option.');
- }
-
- /*
- * Note:
- *
- * Normally, GnuPG expects keyrings to be in the homedir and expects
- * to be able to write temporary files in the homedir. Sometimes,
- * keyrings are not in the homedir, or location of the keyrings does
- * not allow writing temporary files. In this case, the <i>homedir</i>
- * option by itself is not enough to specify the keyrings because GnuPG
- * can not write required temporary files. Additional options are
- * provided so you can specify the location of the keyrings separately
- * from the homedir.
- */
-
- // get public keyring
- if (array_key_exists('publicKeyring', $options)) {
- $this->_publicKeyring = (string)$options['publicKeyring'];
- if (!is_readable($this->_publicKeyring)) {
- throw new Crypt_GPG_FileException('The \'publicKeyring\' "' .
- $this->_publicKeyring . '" does not exist or is ' .
- 'not readable. Check the location and ensure the file ' .
- 'permissions are correct.', 0, $this->_publicKeyring);
- }
- }
-
- // get private keyring
- if (array_key_exists('privateKeyring', $options)) {
- $this->_privateKeyring = (string)$options['privateKeyring'];
- if (!is_readable($this->_privateKeyring)) {
- throw new Crypt_GPG_FileException('The \'privateKeyring\' "' .
- $this->_privateKeyring . '" does not exist or is ' .
- 'not readable. Check the location and ensure the file ' .
- 'permissions are correct.', 0, $this->_privateKeyring);
- }
- }
-
- // get trust database
- if (array_key_exists('trustDb', $options)) {
- $this->_trustDb = (string)$options['trustDb'];
- if (!is_readable($this->_trustDb)) {
- throw new Crypt_GPG_FileException('The \'trustDb\' "' .
- $this->_trustDb . '" does not exist or is not readable. ' .
- 'Check the location and ensure the file permissions are ' .
- 'correct.', 0, $this->_trustDb);
- }
- }
-
- if (array_key_exists('debug', $options)) {
- $this->_debug = (boolean)$options['debug'];
- }
- }
-
- // }}}
- // {{{ __destruct()
-
- /**
- * Closes open GPG subprocesses when this object is destroyed
- *
- * Subprocesses should never be left open by this class unless there is
- * an unknown error and unexpected script termination occurs.
- */
- public function __destruct()
- {
- $this->_closeSubprocess();
- }
-
- // }}}
- // {{{ addErrorHandler()
-
- /**
- * Adds an error handler method
- *
- * The method is run every time a new error line is received from the GPG
- * subprocess. The handler method must accept the error line to be handled
- * as its first parameter.
- *
- * @param callback $callback the callback method to use.
- * @param array $args optional. Additional arguments to pass as
- * parameters to the callback method.
- *
- * @return void
- */
- public function addErrorHandler($callback, array $args = array())
- {
- $this->_errorHandlers[] = array(
- 'callback' => $callback,
- 'args' => $args
- );
- }
-
- // }}}
- // {{{ addStatusHandler()
-
- /**
- * Adds a status handler method
- *
- * The method is run every time a new status line is received from the
- * GPG subprocess. The handler method must accept the status line to be
- * handled as its first parameter.
- *
- * @param callback $callback the callback method to use.
- * @param array $args optional. Additional arguments to pass as
- * parameters to the callback method.
- *
- * @return void
- */
- public function addStatusHandler($callback, array $args = array())
- {
- $this->_statusHandlers[] = array(
- 'callback' => $callback,
- 'args' => $args
- );
- }
-
- // }}}
- // {{{ sendCommand()
-
- /**
- * Sends a command to the GPG subprocess over the command file-descriptor
- * pipe
- *
- * @param string $command the command to send.
- *
- * @return void
- *
- * @sensitive $command
- */
- public function sendCommand($command)
- {
- if (array_key_exists(self::FD_COMMAND, $this->_openPipes)) {
- $this->_commandBuffer .= $command . PHP_EOL;
- }
- }
-
- // }}}
- // {{{ reset()
-
- /**
- * Resets the GPG engine, preparing it for a new operation
- *
- * @return void
- *
- * @see Crypt_GPG_Engine::run()
- * @see Crypt_GPG_Engine::setOperation()
- */
- public function reset()
- {
- $this->_operation = '';
- $this->_arguments = array();
- $this->_input = null;
- $this->_message = null;
- $this->_output = '';
- $this->_errorCode = Crypt_GPG::ERROR_NONE;
- $this->_needPassphrase = 0;
- $this->_commandBuffer = '';
-
- $this->_statusHandlers = array();
- $this->_errorHandlers = array();
-
- $this->addStatusHandler(array($this, '_handleErrorStatus'));
- $this->addErrorHandler(array($this, '_handleErrorError'));
-
- if ($this->_debug) {
- $this->addStatusHandler(array($this, '_handleDebugStatus'));
- $this->addErrorHandler(array($this, '_handleDebugError'));
- }
- }
-
- // }}}
- // {{{ run()
-
- /**
- * Runs the current GPG operation
- *
- * This creates and manages the GPG subprocess.
- *
- * The operation must be set with {@link Crypt_GPG_Engine::setOperation()}
- * before this method is called.
- *
- * @return void
- *
- * @throws Crypt_GPG_InvalidOperationException if no operation is specified.
- *
- * @see Crypt_GPG_Engine::reset()
- * @see Crypt_GPG_Engine::setOperation()
- */
- public function run()
- {
- if ($this->_operation === '') {
- throw new Crypt_GPG_InvalidOperationException('No GPG operation ' .
- 'specified. Use Crypt_GPG_Engine::setOperation() before ' .
- 'calling Crypt_GPG_Engine::run().');
- }
-
- $this->_openSubprocess();
- $this->_process();
- $this->_closeSubprocess();
- }
-
- // }}}
- // {{{ getErrorCode()
-
- /**
- * Gets the error code of the last executed operation
- *
- * This value is only meaningful after {@link Crypt_GPG_Engine::run()} has
- * been executed.
- *
- * @return integer the error code of the last executed operation.
- */
- public function getErrorCode()
- {
- return $this->_errorCode;
- }
-
- // }}}
- // {{{ getErrorFilename()
-
- /**
- * Gets the file related to the error code of the last executed operation
- *
- * This value is only meaningful after {@link Crypt_GPG_Engine::run()} has
- * been executed. If there is no file related to the error, an empty string
- * is returned.
- *
- * @return string the file related to the error code of the last executed
- * operation.
- */
- public function getErrorFilename()
- {
- return $this->_errorFilename;
- }
-
- // }}}
- // {{{ getErrorKeyId()
-
- /**
- * Gets the key id related to the error code of the last executed operation
- *
- * This value is only meaningful after {@link Crypt_GPG_Engine::run()} has
- * been executed. If there is no key id related to the error, an empty
- * string is returned.
- *
- * @return string the key id related to the error code of the last executed
- * operation.
- */
- public function getErrorKeyId()
- {
- return $this->_errorKeyId;
- }
-
- // }}}
- // {{{ setInput()
-
- /**
- * Sets the input source for the current GPG operation
- *
- * @param string|resource &$input either a reference to the string
- * containing the input data or an open
- * stream resource containing the input
- * data.
- *
- * @return void
- */
- public function setInput(&$input)
- {
- $this->_input =& $input;
- }
-
- // }}}
- // {{{ setMessage()
-
- /**
- * Sets the message source for the current GPG operation
- *
- * Detached signature data should be specified here.
- *
- * @param string|resource &$message either a reference to the string
- * containing the message data or an open
- * stream resource containing the message
- * data.
- *
- * @return void
- */
- public function setMessage(&$message)
- {
- $this->_message =& $message;
- }
-
- // }}}
- // {{{ setOutput()
-
- /**
- * Sets the output destination for the current GPG operation
- *
- * @param string|resource &$output either a reference to the string in
- * which to store GPG output or an open
- * stream resource to which the output data
- * should be written.
- *
- * @return void
- */
- public function setOutput(&$output)
- {
- $this->_output =& $output;
- }
-
- // }}}
- // {{{ setOperation()
-
- /**
- * Sets the operation to perform
- *
- * @param string $operation the operation to perform. This should be one
- * of GPG's operations. For example,
- * <kbd>--encrypt</kbd>, <kbd>--decrypt</kbd>,
- * <kbd>--sign</kbd>, etc.
- * @param array $arguments optional. Additional arguments for the GPG
- * subprocess. See the GPG manual for specific
- * values.
- *
- * @return void
- *
- * @see Crypt_GPG_Engine::reset()
- * @see Crypt_GPG_Engine::run()
- */
- public function setOperation($operation, array $arguments = array())
- {
- $this->_operation = $operation;
- $this->_arguments = $arguments;
- }
-
- // }}}
- // {{{ getVersion()
-
- /**
- * Gets the version of the GnuPG binary
- *
- * @return string a version number string containing the version of GnuPG
- * being used. This value is suitable to use with PHP's
- * version_compare() function.
- *
- * @throws Crypt_GPG_Exception if an unknown or unexpected error occurs.
- * Use the <kbd>debug</kbd> option and file a bug report if these
- * exceptions occur.
- *
- * @throws Crypt_GPG_UnsupportedException if the provided binary is not
- * GnuPG or if the GnuPG version is less than 1.0.2.
- */
- public function getVersion()
- {
- if ($this->_version == '') {
-
- $options = array(
- 'homedir' => $this->_homedir,
- 'binary' => $this->_binary,
- 'debug' => $this->_debug
- );
-
- $engine = new self($options);
- $info = '';
-
- // Set a garbage version so we do not end up looking up the version
- // recursively.
- $engine->_version = '1.0.0';
-
- $engine->reset();
- $engine->setOutput($info);
- $engine->setOperation('--version');
- $engine->run();
-
- $code = $this->getErrorCode();
-
- if ($code !== Crypt_GPG::ERROR_NONE) {
- throw new Crypt_GPG_Exception(
- 'Unknown error getting GnuPG version information. Please ' .
- 'use the \'debug\' option when creating the Crypt_GPG ' .
- 'object, and file a bug report at ' . Crypt_GPG::BUG_URI,
- $code);
- }
-
- $matches = array();
- $expression = '/gpg \(GnuPG\) (\S+)/';
-
- if (preg_match($expression, $info, $matches) === 1) {
- $this->_version = $matches[1];
- } else {
- throw new Crypt_GPG_Exception(
- 'No GnuPG version information provided by the binary "' .
- $this->_binary . '". Are you sure it is GnuPG?');
- }
-
- if (version_compare($this->_version, self::MIN_VERSION, 'lt')) {
- throw new Crypt_GPG_Exception(
- 'The version of GnuPG being used (' . $this->_version .
- ') is not supported by Crypt_GPG. The minimum version ' .
- 'required by Crypt_GPG is ' . self::MIN_VERSION);
- }
- }
-
-
- return $this->_version;
- }
-
- // }}}
- // {{{ _handleErrorStatus()
-
- /**
- * Handles error values in the status output from GPG
- *
- * This method is responsible for setting the
- * {@link Crypt_GPG_Engine::$_errorCode}. See <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
- * information on GPG's status output.
- *
- * @param string $line the status line to handle.
- *
- * @return void
- */
- private function _handleErrorStatus($line)
- {
- $tokens = explode(' ', $line);
- switch ($tokens[0]) {
- case 'BAD_PASSPHRASE':
- $this->_errorCode = Crypt_GPG::ERROR_BAD_PASSPHRASE;
- break;
-
- case 'MISSING_PASSPHRASE':
- $this->_errorCode = Crypt_GPG::ERROR_MISSING_PASSPHRASE;
- break;
-
- case 'NODATA':
- $this->_errorCode = Crypt_GPG::ERROR_NO_DATA;
- break;
-
- case 'DELETE_PROBLEM':
- if ($tokens[1] == '1') {
- $this->_errorCode = Crypt_GPG::ERROR_KEY_NOT_FOUND;
- break;
- } elseif ($tokens[1] == '2') {
- $this->_errorCode = Crypt_GPG::ERROR_DELETE_PRIVATE_KEY;
- break;
- }
- break;
-
- case 'IMPORT_RES':
- if ($tokens[12] > 0) {
- $this->_errorCode = Crypt_GPG::ERROR_DUPLICATE_KEY;
- }
- break;
-
- case 'NO_PUBKEY':
- case 'NO_SECKEY':
- $this->_errorKeyId = $tokens[1];
- $this->_errorCode = Crypt_GPG::ERROR_KEY_NOT_FOUND;
- break;
-
- case 'NEED_PASSPHRASE':
- $this->_needPassphrase++;
- break;
-
- case 'GOOD_PASSPHRASE':
- $this->_needPassphrase--;
- break;
-
- case 'EXPSIG':
- case 'EXPKEYSIG':
- case 'REVKEYSIG':
- case 'BADSIG':
- $this->_errorCode = Crypt_GPG::ERROR_BAD_SIGNATURE;
- break;
-
- }
- }
-
- // }}}
- // {{{ _handleErrorError()
-
- /**
- * Handles error values in the error output from GPG
- *
- * This method is responsible for setting the
- * {@link Crypt_GPG_Engine::$_errorCode}.
- *
- * @param string $line the error line to handle.
- *
- * @return void
- */
- private function _handleErrorError($line)
- {
- if ($this->_errorCode === Crypt_GPG::ERROR_NONE) {
- $pattern = '/no valid OpenPGP data found/';
- if (preg_match($pattern, $line) === 1) {
- $this->_errorCode = Crypt_GPG::ERROR_NO_DATA;
- }
- }
-
- if ($this->_errorCode === Crypt_GPG::ERROR_NONE) {
- $pattern = '/No secret key|secret key not available/';
- if (preg_match($pattern, $line) === 1) {
- $this->_errorCode = Crypt_GPG::ERROR_KEY_NOT_FOUND;
- }
- }
-
- if ($this->_errorCode === Crypt_GPG::ERROR_NONE) {
- $pattern = '/No public key|public key not found/';
- if (preg_match($pattern, $line) === 1) {
- $this->_errorCode = Crypt_GPG::ERROR_KEY_NOT_FOUND;
- }
- }
-
- if ($this->_errorCode === Crypt_GPG::ERROR_NONE) {
- $matches = array();
- $pattern = '/can\'t (?:access|open) `(.*?)\'/';
- if (preg_match($pattern, $line, $matches) === 1) {
- $this->_errorFilename = $matches[1];
- $this->_errorCode = Crypt_GPG::ERROR_FILE_PERMISSIONS;
- }
- }
- }
-
- // }}}
- // {{{ _handleDebugStatus()
-
- /**
- * Displays debug output for status lines
- *
- * @param string $line the status line to handle.
- *
- * @return void
- */
- private function _handleDebugStatus($line)
- {
- $this->_debug('STATUS: ' . $line);
- }
-
- // }}}
- // {{{ _handleDebugError()
-
- /**
- * Displays debug output for error lines
- *
- * @param string $line the error line to handle.
- *
- * @return void
- */
- private function _handleDebugError($line)
- {
- $this->_debug('ERROR: ' . $line);
- }
-
- // }}}
- // {{{ _process()
-
- /**
- * Performs internal streaming operations for the subprocess using either
- * strings or streams as input / output points
- *
- * This is the main I/O loop for streaming to and from the GPG subprocess.
- *
- * The implementation of this method is verbose mainly for performance
- * reasons. Adding streams to a lookup array and looping the array inside
- * the main I/O loop would be siginficantly slower for large streams.
- *
- * @return void
- *
- * @throws Crypt_GPG_Exception if there is an error selecting streams for
- * reading or writing. If this occurs, please file a bug report at
- * http://pear.php.net/bugs/report.php?package=Crypt_GPG.
- */
- private function _process()
- {
- $this->_debug('BEGIN PROCESSING');
-
- $this->_commandBuffer = ''; // buffers input to GPG
- $messageBuffer = ''; // buffers input to GPG
- $inputBuffer = ''; // buffers input to GPG
- $outputBuffer = ''; // buffers output from GPG
- $statusBuffer = ''; // buffers output from GPG
- $errorBuffer = ''; // buffers output from GPG
- $inputComplete = false; // input stream is completely buffered
- $messageComplete = false; // message stream is completely buffered
-
- if (is_string($this->_input)) {
- $inputBuffer = $this->_input;
- $inputComplete = true;
- }
-
- if (is_string($this->_message)) {
- $messageBuffer = $this->_message;
- $messageComplete = true;
- }
-
- if (is_string($this->_output)) {
- $outputBuffer =& $this->_output;
- }
-
- // convenience variables
- $fdInput = $this->_pipes[self::FD_INPUT];
- $fdOutput = $this->_pipes[self::FD_OUTPUT];
- $fdError = $this->_pipes[self::FD_ERROR];
- $fdStatus = $this->_pipes[self::FD_STATUS];
- $fdCommand = $this->_pipes[self::FD_COMMAND];
- $fdMessage = $this->_pipes[self::FD_MESSAGE];
-
- while (true) {
-
- $inputStreams = array();
- $outputStreams = array();
- $exceptionStreams = array();
-
- // set up input streams
- if (is_resource($this->_input) && !$inputComplete) {
- if (feof($this->_input)) {
- $inputComplete = true;
- } else {
- $inputStreams[] = $this->_input;
- }
- }
-
- // close GPG input pipe if there is no more data
- if ($inputBuffer == '' && $inputComplete) {
- $this->_debug('=> closing GPG input pipe');
- $this->_closePipe(self::FD_INPUT);
- }
-
- if (is_resource($this->_message) && !$messageComplete) {
- if (feof($this->_message)) {
- $messageComplete = true;
- } else {
- $inputStreams[] = $this->_message;
- }
- }
-
- // close GPG message pipe if there is no more data
- if ($messageBuffer == '' && $messageComplete) {
- $this->_debug('=> closing GPG message pipe');
- $this->_closePipe(self::FD_MESSAGE);
- }
-
- if (!feof($fdOutput)) {
- $inputStreams[] = $fdOutput;
- }
-
- if (!feof($fdStatus)) {
- $inputStreams[] = $fdStatus;
- }
-
- if (!feof($fdError)) {
- $inputStreams[] = $fdError;
- }
-
- // set up output streams
- if ($outputBuffer != '' && is_resource($this->_output)) {
- $outputStreams[] = $this->_output;
- }
-
- if ($this->_commandBuffer != '') {
- $outputStreams[] = $fdCommand;
- }
-
- if ($messageBuffer != '') {
- $outputStreams[] = $fdMessage;
- }
-
- if ($inputBuffer != '') {
- $outputStreams[] = $fdInput;
- }
-
- // no streams left to read or write, we're all done
- if (count($inputStreams) === 0 && count($outputStreams) === 0) {
- break;
- }
-
- $this->_debug('selecting streams');
-
- $ready = stream_select(
- $inputStreams,
- $outputStreams,
- $exceptionStreams,
- null
- );
-
- $this->_debug('=> got ' . $ready);
-
- if ($ready === false) {
- throw new Crypt_GPG_Exception(
- 'Error selecting stream for communication with GPG ' .
- 'subprocess. Please file a bug report at: ' .
- 'http://pear.php.net/bugs/report.php?package=Crypt_GPG');
- }
-
- if ($ready === 0) {
- throw new Crypt_GPG_Exception(
- 'stream_select() returned 0. This can not happen! Please ' .
- 'file a bug report at: ' .
- 'http://pear.php.net/bugs/report.php?package=Crypt_GPG');
- }
-
- // write input (to GPG)
- if (in_array($fdInput, $outputStreams)) {
- $this->_debug('GPG is ready for input');
-
- $chunk = self::_byteSubstring(
- $inputBuffer,
- 0,
- self::CHUNK_SIZE
- );
-
- $length = self::_byteLength($chunk);
-
- $this->_debug(
- '=> about to write ' . $length . ' bytes to GPG input'
- );
-
- $length = fwrite($fdInput, $chunk, $length);
-
- $this->_debug('=> wrote ' . $length . ' bytes');
-
- $inputBuffer = self::_byteSubstring(
- $inputBuffer,
- $length
- );
- }
-
- // read input (from PHP stream)
- if (in_array($this->_input, $inputStreams)) {
- $this->_debug('input stream is ready for reading');
- $this->_debug(
- '=> about to read ' . self::CHUNK_SIZE .
- ' bytes from input stream'
- );
-
- $chunk = fread($this->_input, self::CHUNK_SIZE);
- $length = self::_byteLength($chunk);
- $inputBuffer .= $chunk;
-
- $this->_debug('=> read ' . $length . ' bytes');
- }
-
- // write message (to GPG)
- if (in_array($fdMessage, $outputStreams)) {
- $this->_debug('GPG is ready for message data');
-
- $chunk = self::_byteSubstring(
- $messageBuffer,
- 0,
- self::CHUNK_SIZE
- );
-
- $length = self::_byteLength($chunk);
-
- $this->_debug(
- '=> about to write ' . $length . ' bytes to GPG message'
- );
-
- $length = fwrite($fdMessage, $chunk, $length);
- $this->_debug('=> wrote ' . $length . ' bytes');
-
- $messageBuffer = self::_byteSubstring($messageBuffer, $length);
- }
-
- // read message (from PHP stream)
- if (in_array($this->_message, $inputStreams)) {
- $this->_debug('message stream is ready for reading');
- $this->_debug(
- '=> about to read ' . self::CHUNK_SIZE .
- ' bytes from message stream'
- );
-
- $chunk = fread($this->_message, self::CHUNK_SIZE);
- $length = self::_byteLength($chunk);
- $messageBuffer .= $chunk;
-
- $this->_debug('=> read ' . $length . ' bytes');
- }
-
- // read output (from GPG)
- if (in_array($fdOutput, $inputStreams)) {
- $this->_debug('GPG output stream ready for reading');
- $this->_debug(
- '=> about to read ' . self::CHUNK_SIZE .
- ' bytes from GPG output'
- );
-
- $chunk = fread($fdOutput, self::CHUNK_SIZE);
- $length = self::_byteLength($chunk);
- $outputBuffer .= $chunk;
-
- $this->_debug('=> read ' . $length . ' bytes');
- }
-
- // write output (to PHP stream)
- if (in_array($this->_output, $outputStreams)) {
- $this->_debug('output stream is ready for data');
-
- $chunk = self::_byteSubstring(
- $outputBuffer,
- 0,
- self::CHUNK_SIZE
- );
-
- $length = self::_byteLength($chunk);
-
- $this->_debug(
- '=> about to write ' . $length . ' bytes to output stream'
- );
-
- $length = fwrite($this->_output, $chunk, $length);
-
- $this->_debug('=> wrote ' . $length . ' bytes');
-
- $outputBuffer = self::_byteSubstring($outputBuffer, $length);
- }
-
- // read error (from GPG)
- if (in_array($fdError, $inputStreams)) {
- $this->_debug('GPG error stream ready for reading');
- $this->_debug(
- '=> about to read ' . self::CHUNK_SIZE .
- ' bytes from GPG error'
- );
-
- $chunk = fread($fdError, self::CHUNK_SIZE);
- $length = self::_byteLength($chunk);
- $errorBuffer .= $chunk;
-
- $this->_debug('=> read ' . $length . ' bytes');
-
- // pass lines to error handlers
- while (($pos = strpos($errorBuffer, PHP_EOL)) !== false) {
- $line = self::_byteSubstring($errorBuffer, 0, $pos);
- foreach ($this->_errorHandlers as $handler) {
- array_unshift($handler['args'], $line);
- call_user_func_array(
- $handler['callback'],
- $handler['args']
- );
-
- array_shift($handler['args']);
- }
- $errorBuffer = self::_byteSubString(
- $errorBuffer,
- $pos + self::_byteLength(PHP_EOL)
- );
- }
- }
-
- // read status (from GPG)
- if (in_array($fdStatus, $inputStreams)) {
- $this->_debug('GPG status stream ready for reading');
- $this->_debug(
- '=> about to read ' . self::CHUNK_SIZE .
- ' bytes from GPG status'
- );
-
- $chunk = fread($fdStatus, self::CHUNK_SIZE);
- $length = self::_byteLength($chunk);
- $statusBuffer .= $chunk;
-
- $this->_debug('=> read ' . $length . ' bytes');
-
- // pass lines to status handlers
- while (($pos = strpos($statusBuffer, PHP_EOL)) !== false) {
- $line = self::_byteSubstring($statusBuffer, 0, $pos);
- // only pass lines beginning with magic prefix
- if (self::_byteSubstring($line, 0, 9) == '[GNUPG:] ') {
- $line = self::_byteSubstring($line, 9);
- foreach ($this->_statusHandlers as $handler) {
- array_unshift($handler['args'], $line);
- call_user_func_array(
- $handler['callback'],
- $handler['args']
- );
-
- array_shift($handler['args']);
- }
- }
- $statusBuffer = self::_byteSubString(
- $statusBuffer,
- $pos + self::_byteLength(PHP_EOL)
- );
- }
- }
-
- // write command (to GPG)
- if (in_array($fdCommand, $outputStreams)) {
- $this->_debug('GPG is ready for command data');
-
- // send commands
- $chunk = self::_byteSubstring(
- $this->_commandBuffer,
- 0,
- self::CHUNK_SIZE
- );
-
- $length = self::_byteLength($chunk);
-
- $this->_debug(
- '=> about to write ' . $length . ' bytes to GPG command'
- );
-
- $length = fwrite($fdCommand, $chunk, $length);
-
- $this->_debug('=> wrote ' . $length);
-
- $this->_commandBuffer = self::_byteSubstring(
- $this->_commandBuffer,
- $length
- );
- }
-
- } // end loop while streams are open
-
- $this->_debug('END PROCESSING');
- }
-
- // }}}
- // {{{ _openSubprocess()
-
- /**
- * Opens an internal GPG subprocess for the current operation
- *
- * Opens a GPG subprocess, then connects the subprocess to some pipes. Sets
- * the private class property {@link Crypt_GPG_Engine::$_process} to
- * the new subprocess.
- *
- * @return void
- *
- * @throws Crypt_GPG_OpenSubprocessException if the subprocess could not be
- * opened.
- *
- * @see Crypt_GPG_Engine::setOperation()
- * @see Crypt_GPG_Engine::_closeSubprocess()
- * @see Crypt_GPG_Engine::$_process
- */
- private function _openSubprocess()
- {
- $version = $this->getVersion();
-
- $env = $_ENV;
-
- // Newer versions of GnuPG return localized results. Crypt_GPG only
- // works with English, so set the locale to 'C' for the subprocess.
- $env['LC_ALL'] = 'C';
-
- $commandLine = $this->_binary;
-
- $defaultArguments = array(
- '--status-fd ' . escapeshellarg(self::FD_STATUS),
- '--command-fd ' . escapeshellarg(self::FD_COMMAND),
- '--no-secmem-warning',
- '--no-tty',
- '--no-default-keyring', // ignored if keying files are not specified
- '--no-options' // prevent creation of ~/.gnupg directory
- );
-
- if (version_compare($version, '1.0.7', 'ge')) {
- if (version_compare($version, '2.0.0', 'lt')) {
- $defaultArguments[] = '--no-use-agent';
- }
- $defaultArguments[] = '--no-permission-warning';
- }
-
- if (version_compare($version, '1.4.2', 'ge')) {
- $defaultArguments[] = '--exit-on-status-write-error';
- }
-
- if (version_compare($version, '1.3.2', 'ge')) {
- $defaultArguments[] = '--trust-model always';
- } else {
- $defaultArguments[] = '--always-trust';
- }
-
- $arguments = array_merge($defaultArguments, $this->_arguments);
-
- if ($this->_homedir) {
- $arguments[] = '--homedir ' . escapeshellarg($this->_homedir);
-
- // the random seed file makes subsequent actions faster so only
- // disable it if we have to.
- if (!is_writeable($this->_homedir)) {
- $arguments[] = '--no-random-seed-file';
- }
- }
-
- if ($this->_publicKeyring) {
- $arguments[] = '--keyring ' . escapeshellarg($this->_publicKeyring);
- }
-
- if ($this->_privateKeyring) {
- $arguments[] = '--secret-keyring ' .
- escapeshellarg($this->_privateKeyring);
- }
-
- if ($this->_trustDb) {
- $arguments[] = '--trustdb-name ' . escapeshellarg($this->_trustDb);
- }
-
- $commandLine .= ' ' . implode(' ', $arguments) . ' ' .
- $this->_operation;
-
- // Binary operations will not work on Windows with PHP < 5.2.6. This is
- // in case stream_select() ever works on Windows.
- $rb = (version_compare(PHP_VERSION, '5.2.6') < 0) ? 'r' : 'rb';
- $wb = (version_compare(PHP_VERSION, '5.2.6') < 0) ? 'w' : 'wb';
-
- $descriptorSpec = array(
- self::FD_INPUT => array('pipe', $rb), // stdin
- self::FD_OUTPUT => array('pipe', $wb), // stdout
- self::FD_ERROR => array('pipe', $wb), // stderr
- self::FD_STATUS => array('pipe', $wb), // status
- self::FD_COMMAND => array('pipe', $rb), // command
- self::FD_MESSAGE => array('pipe', $rb) // message
- );
-
- $this->_debug('OPENING SUBPROCESS WITH THE FOLLOWING COMMAND:');
- $this->_debug($commandLine);
-
- $this->_process = proc_open(
- $commandLine,
- $descriptorSpec,
- $this->_pipes,
- null,
- $env,
- array('binary_pipes' => true)
- );
-
- if (!is_resource($this->_process)) {
- throw new Crypt_GPG_OpenSubprocessException(
- 'Unable to open GPG subprocess.', 0, $commandLine);
- }
-
- $this->_openPipes = $this->_pipes;
- $this->_errorCode = Crypt_GPG::ERROR_NONE;
- }
-
- // }}}
- // {{{ _closeSubprocess()
-
- /**
- * Closes a the internal GPG subprocess
- *
- * Closes the internal GPG subprocess. Sets the private class property
- * {@link Crypt_GPG_Engine::$_process} to null.
- *
- * @return void
- *
- * @see Crypt_GPG_Engine::_openSubprocess()
- * @see Crypt_GPG_Engine::$_process
- */
- private function _closeSubprocess()
- {
- if (is_resource($this->_process)) {
- $this->_debug('CLOSING SUBPROCESS');
-
- // close remaining open pipes
- foreach (array_keys($this->_openPipes) as $pipeNumber) {
- $this->_closePipe($pipeNumber);
- }
-
- $exitCode = proc_close($this->_process);
-
- if ($exitCode != 0) {
- $this->_debug(
- '=> subprocess returned an unexpected exit code: ' .
- $exitCode
- );
-
- if ($this->_errorCode === Crypt_GPG::ERROR_NONE) {
- if ($this->_needPassphrase > 0) {
- $this->_errorCode = Crypt_GPG::ERROR_MISSING_PASSPHRASE;
- } else {
- $this->_errorCode = Crypt_GPG::ERROR_UNKNOWN;
- }
- }
- }
-
- $this->_process = null;
- $this->_pipes = array();
- }
- }
-
- // }}}
- // {{{ _closePipe()
-
- /**
- * Closes an opened pipe used to communicate with the GPG subprocess
- *
- * If the pipe is already closed, it is ignored. If the pipe is open, it
- * is flushed and then closed.
- *
- * @param integer $pipeNumber the file descriptor number of the pipe to
- * close.
- *
- * @return void
- */
- private function _closePipe($pipeNumber)
- {
- $pipeNumber = intval($pipeNumber);
- if (array_key_exists($pipeNumber, $this->_openPipes)) {
- fflush($this->_openPipes[$pipeNumber]);
- fclose($this->_openPipes[$pipeNumber]);
- unset($this->_openPipes[$pipeNumber]);
- }
- }
-
- // }}}
- // {{{ _getBinary()
-
- /**
- * Gets the name of the GPG binary for the current operating system
- *
- * This method is called if the '<kbd>binary</kbd>' option is <i>not</i>
- * specified when creating this driver.
- *
- * @return string the name of the GPG binary for the current operating
- * system. If no suitable binary could be found, an empty
- * string is returned.
- */
- private function _getBinary()
- {
- $binary = '';
-
- if ($this->_isDarwin) {
- $binaryFiles = array(
- '/opt/local/bin/gpg', // MacPorts
- '/usr/local/bin/gpg', // Mac GPG
- '/sw/bin/gpg', // Fink
- '/usr/bin/gpg'
- );
- } else {
- $binaryFiles = array(
- '/usr/bin/gpg',
- '/usr/local/bin/gpg'
- );
- }
-
- foreach ($binaryFiles as $binaryFile) {
- if (is_executable($binaryFile)) {
- $binary = $binaryFile;
- break;
- }
- }
-
- return $binary;
- }
-
- // }}}
- // {{{ _debug()
-
- /**
- * Displays debug text if debugging is turned on
- *
- * Debugging text is prepended with a debug identifier and echoed to stdout.
- *
- * @param string $text the debugging text to display.
- *
- * @return void
- */
- private function _debug($text)
- {
- if ($this->_debug) {
- if (array_key_exists('SHELL', $_ENV)) {
- foreach (explode(PHP_EOL, $text) as $line) {
- echo "Crypt_GPG DEBUG: ", $line, PHP_EOL;
- }
- } else {
- // running on a web server, format debug output nicely
- foreach (explode(PHP_EOL, $text) as $line) {
- echo "Crypt_GPG DEBUG: <strong>", $line,
- '</strong><br />', PHP_EOL;
- }
- }
- }
- }
-
- // }}}
- // {{{ _byteLength()
-
- /**
- * Gets the length of a string in bytes even if mbstring function
- * overloading is turned on
- *
- * This is used for stream-based communication with the GPG subprocess.
- *
- * @param string $string the string for which to get the length.
- *
- * @return integer the length of the string in bytes.
- *
- * @see Crypt_GPG_Engine::$_mbStringOverload
- */
- private static function _byteLength($string)
- {
- if (self::$_mbStringOverload) {
- return mb_strlen($string, '8bit');
- }
-
- return strlen((binary)$string);
- }
-
- // }}}
- // {{{ _byteSubstring()
-
- /**
- * Gets the substring of a string in bytes even if mbstring function
- * overloading is turned on
- *
- * This is used for stream-based communication with the GPG subprocess.
- *
- * @param string $string the input string.
- * @param integer $start the starting point at which to get the substring.
- * @param integer $length optional. The length of the substring.
- *
- * @return string the extracted part of the string. Unlike the default PHP
- * <kbd>substr()</kbd> function, the returned value is
- * always a string and never false.
- *
- * @see Crypt_GPG_Engine::$_mbStringOverload
- */
- private static function _byteSubstring($string, $start, $length = null)
- {
- if (self::$_mbStringOverload) {
- if ($length === null) {
- return mb_substr(
- $string,
- $start,
- self::_byteLength($string) - $start, '8bit'
- );
- }
-
- return mb_substr($string, $start, $length, '8bit');
- }
-
- if ($length === null) {
- return (string)substr((binary)$string, $start);
- }
-
- return (string)substr((binary)$string, $start, $length);
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/Exceptions.php b/plugins/enigma/lib/Crypt/GPG/Exceptions.php
deleted file mode 100644
index 744acf5d4..000000000
--- a/plugins/enigma/lib/Crypt/GPG/Exceptions.php
+++ /dev/null
@@ -1,473 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Various exception handling classes for Crypt_GPG
- *
- * Crypt_GPG provides an object oriented interface to GNU Privacy
- * Guard (GPG). It requires the GPG executable to be on the system.
- *
- * This file contains various exception classes used by the Crypt_GPG package.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: Exceptions.php 273745 2009-01-18 05:24:25Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- */
-
-/**
- * PEAR Exception handler and base class
- */
-require_once 'PEAR/Exception.php';
-
-// {{{ class Crypt_GPG_Exception
-
-/**
- * An exception thrown by the Crypt_GPG package
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_Exception extends PEAR_Exception
-{
-}
-
-// }}}
-// {{{ class Crypt_GPG_FileException
-
-/**
- * An exception thrown when a file is used in ways it cannot be used
- *
- * For example, if an output file is specified and the file is not writeable, or
- * if an input file is specified and the file is not readable, this exception
- * is thrown.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2007-2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_FileException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * The name of the file that caused this exception
- *
- * @var string
- */
- private $_filename = '';
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_FileException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $filename the name of the file that caused this exception.
- */
- public function __construct($message, $code = 0, $filename = '')
- {
- $this->_filename = $filename;
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getFilename()
-
- /**
- * Returns the filename of the file that caused this exception
- *
- * @return string the filename of the file that caused this exception.
- *
- * @see Crypt_GPG_FileException::$_filename
- */
- public function getFilename()
- {
- return $this->_filename;
- }
-
- // }}}
-}
-
-// }}}
-// {{{ class Crypt_GPG_OpenSubprocessException
-
-/**
- * An exception thrown when the GPG subprocess cannot be opened
- *
- * This exception is thrown when the {@link Crypt_GPG_Engine} tries to open a
- * new subprocess and fails.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_OpenSubprocessException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * The command used to try to open the subprocess
- *
- * @var string
- */
- private $_command = '';
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_OpenSubprocessException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $command the command that was called to open the
- * new subprocess.
- *
- * @see Crypt_GPG::_openSubprocess()
- */
- public function __construct($message, $code = 0, $command = '')
- {
- $this->_command = $command;
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getCommand()
-
- /**
- * Returns the contents of the internal _command property
- *
- * @return string the command used to open the subprocess.
- *
- * @see Crypt_GPG_OpenSubprocessException::$_command
- */
- public function getCommand()
- {
- return $this->_command;
- }
-
- // }}}
-}
-
-// }}}
-// {{{ class Crypt_GPG_InvalidOperationException
-
-/**
- * An exception thrown when an invalid GPG operation is attempted
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_InvalidOperationException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * The attempted operation
- *
- * @var string
- */
- private $_operation = '';
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_OpenSubprocessException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $operation the operation.
- */
- public function __construct($message, $code = 0, $operation = '')
- {
- $this->_operation = $operation;
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getOperation()
-
- /**
- * Returns the contents of the internal _operation property
- *
- * @return string the attempted operation.
- *
- * @see Crypt_GPG_InvalidOperationException::$_operation
- */
- public function getOperation()
- {
- return $this->_operation;
- }
-
- // }}}
-}
-
-// }}}
-// {{{ class Crypt_GPG_KeyNotFoundException
-
-/**
- * An exception thrown when Crypt_GPG fails to find the key for various
- * operations
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_KeyNotFoundException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * The key identifier that was searched for
- *
- * @var string
- */
- private $_keyId = '';
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_KeyNotFoundException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $keyId the key identifier of the key.
- */
- public function __construct($message, $code = 0, $keyId= '')
- {
- $this->_keyId = $keyId;
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getKeyId()
-
- /**
- * Gets the key identifier of the key that was not found
- *
- * @return string the key identifier of the key that was not found.
- */
- public function getKeyId()
- {
- return $this->_keyId;
- }
-
- // }}}
-}
-
-// }}}
-// {{{ class Crypt_GPG_NoDataException
-
-/**
- * An exception thrown when Crypt_GPG cannot find valid data for various
- * operations
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2006 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_NoDataException extends Crypt_GPG_Exception
-{
-}
-
-// }}}
-// {{{ class Crypt_GPG_BadPassphraseException
-
-/**
- * An exception thrown when a required passphrase is incorrect or missing
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2006-2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_BadPassphraseException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * Keys for which the passhprase is missing
- *
- * This contains primary user ids indexed by sub-key id.
- *
- * @var array
- */
- private $_missingPassphrases = array();
-
- /**
- * Keys for which the passhprase is incorrect
- *
- * This contains primary user ids indexed by sub-key id.
- *
- * @var array
- */
- private $_badPassphrases = array();
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_BadPassphraseException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $badPassphrases an array containing user ids of keys
- * for which the passphrase is incorrect.
- * @param string $missingPassphrases an array containing user ids of keys
- * for which the passphrase is missing.
- */
- public function __construct($message, $code = 0,
- array $badPassphrases = array(), array $missingPassphrases = array()
- ) {
- $this->_badPassphrases = $badPassphrases;
- $this->_missingPassphrases = $missingPassphrases;
-
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getBadPassphrases()
-
- /**
- * Gets keys for which the passhprase is incorrect
- *
- * @return array an array of keys for which the passphrase is incorrect.
- * The array contains primary user ids indexed by the sub-key
- * id.
- */
- public function getBadPassphrases()
- {
- return $this->_badPassphrases;
- }
-
- // }}}
- // {{{ getMissingPassphrases()
-
- /**
- * Gets keys for which the passhprase is missing
- *
- * @return array an array of keys for which the passphrase is missing.
- * The array contains primary user ids indexed by the sub-key
- * id.
- */
- public function getMissingPassphrases()
- {
- return $this->_missingPassphrases;
- }
-
- // }}}
-}
-
-// }}}
-// {{{ class Crypt_GPG_DeletePrivateKeyException
-
-/**
- * An exception thrown when an attempt is made to delete public key that has an
- * associated private key on the keyring
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- */
-class Crypt_GPG_DeletePrivateKeyException extends Crypt_GPG_Exception
-{
- // {{{ private class properties
-
- /**
- * The key identifier the deletion attempt was made upon
- *
- * @var string
- */
- private $_keyId = '';
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new Crypt_GPG_DeletePrivateKeyException
- *
- * @param string $message an error message.
- * @param integer $code a user defined error code.
- * @param string $keyId the key identifier of the public key that was
- * attempted to delete.
- *
- * @see Crypt_GPG::deletePublicKey()
- */
- public function __construct($message, $code = 0, $keyId = '')
- {
- $this->_keyId = $keyId;
- parent::__construct($message, $code);
- }
-
- // }}}
- // {{{ getKeyId()
-
- /**
- * Gets the key identifier of the key that was not found
- *
- * @return string the key identifier of the key that was not found.
- */
- public function getKeyId()
- {
- return $this->_keyId;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/Key.php b/plugins/enigma/lib/Crypt/GPG/Key.php
deleted file mode 100644
index 67a4b9c7d..000000000
--- a/plugins/enigma/lib/Crypt/GPG/Key.php
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Contains a class representing GPG keys
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: Key.php 295621 2010-03-01 04:18:54Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- */
-
-/**
- * Sub-key class definition
- */
-require_once 'Crypt/GPG/SubKey.php';
-
-/**
- * User id class definition
- */
-require_once 'Crypt/GPG/UserId.php';
-
-// {{{ class Crypt_GPG_Key
-
-/**
- * A data class for GPG key information
- *
- * This class is used to store the results of the {@link Crypt_GPG::getKeys()}
- * method.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @see Crypt_GPG::getKeys()
- */
-class Crypt_GPG_Key
-{
- // {{{ class properties
-
- /**
- * The user ids associated with this key
- *
- * This is an array of {@link Crypt_GPG_UserId} objects.
- *
- * @var array
- *
- * @see Crypt_GPG_Key::addUserId()
- * @see Crypt_GPG_Key::getUserIds()
- */
- private $_userIds = array();
-
- /**
- * The subkeys of this key
- *
- * This is an array of {@link Crypt_GPG_SubKey} objects.
- *
- * @var array
- *
- * @see Crypt_GPG_Key::addSubKey()
- * @see Crypt_GPG_Key::getSubKeys()
- */
- private $_subKeys = array();
-
- // }}}
- // {{{ getSubKeys()
-
- /**
- * Gets the sub-keys of this key
- *
- * @return array the sub-keys of this key.
- *
- * @see Crypt_GPG_Key::addSubKey()
- */
- public function getSubKeys()
- {
- return $this->_subKeys;
- }
-
- // }}}
- // {{{ getUserIds()
-
- /**
- * Gets the user ids of this key
- *
- * @return array the user ids of this key.
- *
- * @see Crypt_GPG_Key::addUserId()
- */
- public function getUserIds()
- {
- return $this->_userIds;
- }
-
- // }}}
- // {{{ getPrimaryKey()
-
- /**
- * Gets the primary sub-key of this key
- *
- * The primary key is the first added sub-key.
- *
- * @return Crypt_GPG_SubKey the primary sub-key of this key.
- */
- public function getPrimaryKey()
- {
- $primary_key = null;
- if (count($this->_subKeys) > 0) {
- $primary_key = $this->_subKeys[0];
- }
- return $primary_key;
- }
-
- // }}}
- // {{{ canSign()
-
- /**
- * Gets whether or not this key can sign data
- *
- * This key can sign data if any sub-key of this key can sign data.
- *
- * @return boolean true if this key can sign data and false if this key
- * cannot sign data.
- */
- public function canSign()
- {
- $canSign = false;
- foreach ($this->_subKeys as $subKey) {
- if ($subKey->canSign()) {
- $canSign = true;
- break;
- }
- }
- return $canSign;
- }
-
- // }}}
- // {{{ canEncrypt()
-
- /**
- * Gets whether or not this key can encrypt data
- *
- * This key can encrypt data if any sub-key of this key can encrypt data.
- *
- * @return boolean true if this key can encrypt data and false if this
- * key cannot encrypt data.
- */
- public function canEncrypt()
- {
- $canEncrypt = false;
- foreach ($this->_subKeys as $subKey) {
- if ($subKey->canEncrypt()) {
- $canEncrypt = true;
- break;
- }
- }
- return $canEncrypt;
- }
-
- // }}}
- // {{{ addSubKey()
-
- /**
- * Adds a sub-key to this key
- *
- * The first added sub-key will be the primary key of this key.
- *
- * @param Crypt_GPG_SubKey $subKey the sub-key to add.
- *
- * @return Crypt_GPG_Key the current object, for fluent interface.
- */
- public function addSubKey(Crypt_GPG_SubKey $subKey)
- {
- $this->_subKeys[] = $subKey;
- return $this;
- }
-
- // }}}
- // {{{ addUserId()
-
- /**
- * Adds a user id to this key
- *
- * @param Crypt_GPG_UserId $userId the user id to add.
- *
- * @return Crypt_GPG_Key the current object, for fluent interface.
- */
- public function addUserId(Crypt_GPG_UserId $userId)
- {
- $this->_userIds[] = $userId;
- return $this;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/Signature.php b/plugins/enigma/lib/Crypt/GPG/Signature.php
deleted file mode 100644
index 03ab44c53..000000000
--- a/plugins/enigma/lib/Crypt/GPG/Signature.php
+++ /dev/null
@@ -1,428 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * A class representing GPG signatures
- *
- * This file contains a data class representing a GPG signature.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: Signature.php 302773 2010-08-25 14:16:28Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- */
-
-/**
- * User id class definition
- */
-require_once 'Crypt/GPG/UserId.php';
-
-// {{{ class Crypt_GPG_Signature
-
-/**
- * A class for GPG signature information
- *
- * This class is used to store the results of the Crypt_GPG::verify() method.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @see Crypt_GPG::verify()
- */
-class Crypt_GPG_Signature
-{
- // {{{ class properties
-
- /**
- * A base64-encoded string containing a unique id for this signature if
- * this signature has been verified as ok
- *
- * This id is used to prevent replay attacks and is not present for all
- * types of signatures.
- *
- * @var string
- */
- private $_id = '';
-
- /**
- * The fingerprint of the key used to create the signature
- *
- * @var string
- */
- private $_keyFingerprint = '';
-
- /**
- * The id of the key used to create the signature
- *
- * @var string
- */
- private $_keyId = '';
-
- /**
- * The creation date of this signature
- *
- * This is a Unix timestamp.
- *
- * @var integer
- */
- private $_creationDate = 0;
-
- /**
- * The expiration date of the signature
- *
- * This is a Unix timestamp. If this signature does not expire, this will
- * be zero.
- *
- * @var integer
- */
- private $_expirationDate = 0;
-
- /**
- * The user id associated with this signature
- *
- * @var Crypt_GPG_UserId
- */
- private $_userId = null;
-
- /**
- * Whether or not this signature is valid
- *
- * @var boolean
- */
- private $_isValid = false;
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new signature
- *
- * Signatures can be initialized from an array of named values. Available
- * names are:
- *
- * - <kbd>string id</kbd> - the unique id of this signature.
- * - <kbd>string fingerprint</kbd> - the fingerprint of the key used to
- * create the signature. The fingerprint
- * should not contain formatting
- * characters.
- * - <kbd>string keyId</kbd> - the id of the key used to create the
- * the signature.
- * - <kbd>integer creation</kbd> - the date the signature was created.
- * This is a UNIX timestamp.
- * - <kbd>integer expiration</kbd> - the date the signature expired. This
- * is a UNIX timestamp. If the signature
- * does not expire, use 0.
- * - <kbd>boolean valid</kbd> - whether or not the signature is valid.
- * - <kbd>string userId</kbd> - the user id associated with the
- * signature. This may also be a
- * {@link Crypt_GPG_UserId} object.
- *
- * @param Crypt_GPG_Signature|array $signature optional. Either an existing
- * signature object, which is copied; or an array of initial values.
- */
- public function __construct($signature = null)
- {
- // copy from object
- if ($signature instanceof Crypt_GPG_Signature) {
- $this->_id = $signature->_id;
- $this->_keyFingerprint = $signature->_keyFingerprint;
- $this->_keyId = $signature->_keyId;
- $this->_creationDate = $signature->_creationDate;
- $this->_expirationDate = $signature->_expirationDate;
- $this->_isValid = $signature->_isValid;
-
- if ($signature->_userId instanceof Crypt_GPG_UserId) {
- $this->_userId = clone $signature->_userId;
- } else {
- $this->_userId = $signature->_userId;
- }
- }
-
- // initialize from array
- if (is_array($signature)) {
- if (array_key_exists('id', $signature)) {
- $this->setId($signature['id']);
- }
-
- if (array_key_exists('fingerprint', $signature)) {
- $this->setKeyFingerprint($signature['fingerprint']);
- }
-
- if (array_key_exists('keyId', $signature)) {
- $this->setKeyId($signature['keyId']);
- }
-
- if (array_key_exists('creation', $signature)) {
- $this->setCreationDate($signature['creation']);
- }
-
- if (array_key_exists('expiration', $signature)) {
- $this->setExpirationDate($signature['expiration']);
- }
-
- if (array_key_exists('valid', $signature)) {
- $this->setValid($signature['valid']);
- }
-
- if (array_key_exists('userId', $signature)) {
- $userId = new Crypt_GPG_UserId($signature['userId']);
- $this->setUserId($userId);
- }
- }
- }
-
- // }}}
- // {{{ getId()
-
- /**
- * Gets the id of this signature
- *
- * @return string a base64-encoded string containing a unique id for this
- * signature. This id is used to prevent replay attacks and
- * is not present for all types of signatures.
- */
- public function getId()
- {
- return $this->_id;
- }
-
- // }}}
- // {{{ getKeyFingerprint()
-
- /**
- * Gets the fingerprint of the key used to create this signature
- *
- * @return string the fingerprint of the key used to create this signature.
- */
- public function getKeyFingerprint()
- {
- return $this->_keyFingerprint;
- }
-
- // }}}
- // {{{ getKeyId()
-
- /**
- * Gets the id of the key used to create this signature
- *
- * Whereas the fingerprint of the signing key may not always be available
- * (for example if the signature is bad), the id should always be
- * available.
- *
- * @return string the id of the key used to create this signature.
- */
- public function getKeyId()
- {
- return $this->_keyId;
- }
-
- // }}}
- // {{{ getCreationDate()
-
- /**
- * Gets the creation date of this signature
- *
- * @return integer the creation date of this signature. This is a Unix
- * timestamp.
- */
- public function getCreationDate()
- {
- return $this->_creationDate;
- }
-
- // }}}
- // {{{ getExpirationDate()
-
- /**
- * Gets the expiration date of the signature
- *
- * @return integer the expiration date of this signature. This is a Unix
- * timestamp. If this signature does not expire, this will
- * be zero.
- */
- public function getExpirationDate()
- {
- return $this->_expirationDate;
- }
-
- // }}}
- // {{{ getUserId()
-
- /**
- * Gets the user id associated with this signature
- *
- * @return Crypt_GPG_UserId the user id associated with this signature.
- */
- public function getUserId()
- {
- return $this->_userId;
- }
-
- // }}}
- // {{{ isValid()
-
- /**
- * Gets whether or no this signature is valid
- *
- * @return boolean true if this signature is valid and false if it is not.
- */
- public function isValid()
- {
- return $this->_isValid;
- }
-
- // }}}
- // {{{ setId()
-
- /**
- * Sets the id of this signature
- *
- * @param string $id a base64-encoded string containing a unique id for
- * this signature.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- *
- * @see Crypt_GPG_Signature::getId()
- */
- public function setId($id)
- {
- $this->_id = strval($id);
- return $this;
- }
-
- // }}}
- // {{{ setKeyFingerprint()
-
- /**
- * Sets the key fingerprint of this signature
- *
- * @param string $fingerprint the key fingerprint of this signature. This
- * is the fingerprint of the primary key used to
- * create this signature.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setKeyFingerprint($fingerprint)
- {
- $this->_keyFingerprint = strval($fingerprint);
- return $this;
- }
-
- // }}}
- // {{{ setKeyId()
-
- /**
- * Sets the key id of this signature
- *
- * @param string $id the key id of this signature. This is the id of the
- * primary key used to create this signature.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setKeyId($id)
- {
- $this->_keyId = strval($id);
- return $this;
- }
-
- // }}}
- // {{{ setCreationDate()
-
- /**
- * Sets the creation date of this signature
- *
- * @param integer $creationDate the creation date of this signature. This
- * is a Unix timestamp.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setCreationDate($creationDate)
- {
- $this->_creationDate = intval($creationDate);
- return $this;
- }
-
- // }}}
- // {{{ setExpirationDate()
-
- /**
- * Sets the expiration date of this signature
- *
- * @param integer $expirationDate the expiration date of this signature.
- * This is a Unix timestamp. Specify zero if
- * this signature does not expire.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setExpirationDate($expirationDate)
- {
- $this->_expirationDate = intval($expirationDate);
- return $this;
- }
-
- // }}}
- // {{{ setUserId()
-
- /**
- * Sets the user id associated with this signature
- *
- * @param Crypt_GPG_UserId $userId the user id associated with this
- * signature.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setUserId(Crypt_GPG_UserId $userId)
- {
- $this->_userId = $userId;
- return $this;
- }
-
- // }}}
- // {{{ setValid()
-
- /**
- * Sets whether or not this signature is valid
- *
- * @param boolean $isValid true if this signature is valid and false if it
- * is not.
- *
- * @return Crypt_GPG_Signature the current object, for fluent interface.
- */
- public function setValid($isValid)
- {
- $this->_isValid = ($isValid) ? true : false;
- return $this;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/SubKey.php b/plugins/enigma/lib/Crypt/GPG/SubKey.php
deleted file mode 100644
index b6316e99f..000000000
--- a/plugins/enigma/lib/Crypt/GPG/SubKey.php
+++ /dev/null
@@ -1,649 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Contains a class representing GPG sub-keys and constants for GPG algorithms
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: SubKey.php 302768 2010-08-25 13:45:52Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- */
-
-// {{{ class Crypt_GPG_SubKey
-
-/**
- * A class for GPG sub-key information
- *
- * This class is used to store the results of the {@link Crypt_GPG::getKeys()}
- * method. Sub-key objects are members of a {@link Crypt_GPG_Key} object.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @author Nathan Fredrickson <nathan@silverorange.com>
- * @copyright 2005-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @see Crypt_GPG::getKeys()
- * @see Crypt_GPG_Key::getSubKeys()
- */
-class Crypt_GPG_SubKey
-{
- // {{{ class constants
-
- /**
- * RSA encryption algorithm.
- */
- const ALGORITHM_RSA = 1;
-
- /**
- * Elgamal encryption algorithm (encryption only).
- */
- const ALGORITHM_ELGAMAL_ENC = 16;
-
- /**
- * DSA encryption algorithm (sometimes called DH, sign only).
- */
- const ALGORITHM_DSA = 17;
-
- /**
- * Elgamal encryption algorithm (signage and encryption - should not be
- * used).
- */
- const ALGORITHM_ELGAMAL_ENC_SGN = 20;
-
- // }}}
- // {{{ class properties
-
- /**
- * The id of this sub-key
- *
- * @var string
- */
- private $_id = '';
-
- /**
- * The algorithm used to create this sub-key
- *
- * The value is one of the Crypt_GPG_SubKey::ALGORITHM_* constants.
- *
- * @var integer
- */
- private $_algorithm = 0;
-
- /**
- * The fingerprint of this sub-key
- *
- * @var string
- */
- private $_fingerprint = '';
-
- /**
- * Length of this sub-key in bits
- *
- * @var integer
- */
- private $_length = 0;
-
- /**
- * Date this sub-key was created
- *
- * This is a Unix timestamp.
- *
- * @var integer
- */
- private $_creationDate = 0;
-
- /**
- * Date this sub-key expires
- *
- * This is a Unix timestamp. If this sub-key does not expire, this will be
- * zero.
- *
- * @var integer
- */
- private $_expirationDate = 0;
-
- /**
- * Whether or not this sub-key can sign data
- *
- * @var boolean
- */
- private $_canSign = false;
-
- /**
- * Whether or not this sub-key can encrypt data
- *
- * @var boolean
- */
- private $_canEncrypt = false;
-
- /**
- * Whether or not the private key for this sub-key exists in the keyring
- *
- * @var boolean
- */
- private $_hasPrivate = false;
-
- /**
- * Whether or not this sub-key is revoked
- *
- * @var boolean
- */
- private $_isRevoked = false;
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new sub-key object
- *
- * Sub-keys can be initialized from an array of named values. Available
- * names are:
- *
- * - <kbd>string id</kbd> - the key id of the sub-key.
- * - <kbd>integer algorithm</kbd> - the encryption algorithm of the
- * sub-key.
- * - <kbd>string fingerprint</kbd> - the fingerprint of the sub-key. The
- * fingerprint should not contain
- * formatting characters.
- * - <kbd>integer length</kbd> - the length of the sub-key in bits.
- * - <kbd>integer creation</kbd> - the date the sub-key was created.
- * This is a UNIX timestamp.
- * - <kbd>integer expiration</kbd> - the date the sub-key expires. This
- * is a UNIX timestamp. If the sub-key
- * does not expire, use 0.
- * - <kbd>boolean canSign</kbd> - whether or not the sub-key can be
- * used to sign data.
- * - <kbd>boolean canEncrypt</kbd> - whether or not the sub-key can be
- * used to encrypt data.
- * - <kbd>boolean hasPrivate</kbd> - whether or not the private key for
- * the sub-key exists in the keyring.
- * - <kbd>boolean isRevoked</kbd> - whether or not this sub-key is
- * revoked.
- *
- * @param Crypt_GPG_SubKey|string|array $key optional. Either an existing
- * sub-key object, which is copied; a sub-key string, which is
- * parsed; or an array of initial values.
- */
- public function __construct($key = null)
- {
- // parse from string
- if (is_string($key)) {
- $key = self::parse($key);
- }
-
- // copy from object
- if ($key instanceof Crypt_GPG_SubKey) {
- $this->_id = $key->_id;
- $this->_algorithm = $key->_algorithm;
- $this->_fingerprint = $key->_fingerprint;
- $this->_length = $key->_length;
- $this->_creationDate = $key->_creationDate;
- $this->_expirationDate = $key->_expirationDate;
- $this->_canSign = $key->_canSign;
- $this->_canEncrypt = $key->_canEncrypt;
- $this->_hasPrivate = $key->_hasPrivate;
- $this->_isRevoked = $key->_isRevoked;
- }
-
- // initialize from array
- if (is_array($key)) {
- if (array_key_exists('id', $key)) {
- $this->setId($key['id']);
- }
-
- if (array_key_exists('algorithm', $key)) {
- $this->setAlgorithm($key['algorithm']);
- }
-
- if (array_key_exists('fingerprint', $key)) {
- $this->setFingerprint($key['fingerprint']);
- }
-
- if (array_key_exists('length', $key)) {
- $this->setLength($key['length']);
- }
-
- if (array_key_exists('creation', $key)) {
- $this->setCreationDate($key['creation']);
- }
-
- if (array_key_exists('expiration', $key)) {
- $this->setExpirationDate($key['expiration']);
- }
-
- if (array_key_exists('canSign', $key)) {
- $this->setCanSign($key['canSign']);
- }
-
- if (array_key_exists('canEncrypt', $key)) {
- $this->setCanEncrypt($key['canEncrypt']);
- }
-
- if (array_key_exists('hasPrivate', $key)) {
- $this->setHasPrivate($key['hasPrivate']);
- }
-
- if (array_key_exists('isRevoked', $key)) {
- $this->setRevoked($key['isRevoked']);
- }
- }
- }
-
- // }}}
- // {{{ getId()
-
- /**
- * Gets the id of this sub-key
- *
- * @return string the id of this sub-key.
- */
- public function getId()
- {
- return $this->_id;
- }
-
- // }}}
- // {{{ getAlgorithm()
-
- /**
- * Gets the algorithm used by this sub-key
- *
- * The algorithm should be one of the Crypt_GPG_SubKey::ALGORITHM_*
- * constants.
- *
- * @return integer the algorithm used by this sub-key.
- */
- public function getAlgorithm()
- {
- return $this->_algorithm;
- }
-
- // }}}
- // {{{ getCreationDate()
-
- /**
- * Gets the creation date of this sub-key
- *
- * This is a Unix timestamp.
- *
- * @return integer the creation date of this sub-key.
- */
- public function getCreationDate()
- {
- return $this->_creationDate;
- }
-
- // }}}
- // {{{ getExpirationDate()
-
- /**
- * Gets the date this sub-key expires
- *
- * This is a Unix timestamp. If this sub-key does not expire, this will be
- * zero.
- *
- * @return integer the date this sub-key expires.
- */
- public function getExpirationDate()
- {
- return $this->_expirationDate;
- }
-
- // }}}
- // {{{ getFingerprint()
-
- /**
- * Gets the fingerprint of this sub-key
- *
- * @return string the fingerprint of this sub-key.
- */
- public function getFingerprint()
- {
- return $this->_fingerprint;
- }
-
- // }}}
- // {{{ getLength()
-
- /**
- * Gets the length of this sub-key in bits
- *
- * @return integer the length of this sub-key in bits.
- */
- public function getLength()
- {
- return $this->_length;
- }
-
- // }}}
- // {{{ canSign()
-
- /**
- * Gets whether or not this sub-key can sign data
- *
- * @return boolean true if this sub-key can sign data and false if this
- * sub-key can not sign data.
- */
- public function canSign()
- {
- return $this->_canSign;
- }
-
- // }}}
- // {{{ canEncrypt()
-
- /**
- * Gets whether or not this sub-key can encrypt data
- *
- * @return boolean true if this sub-key can encrypt data and false if this
- * sub-key can not encrypt data.
- */
- public function canEncrypt()
- {
- return $this->_canEncrypt;
- }
-
- // }}}
- // {{{ hasPrivate()
-
- /**
- * Gets whether or not the private key for this sub-key exists in the
- * keyring
- *
- * @return boolean true the private key for this sub-key exists in the
- * keyring and false if it does not.
- */
- public function hasPrivate()
- {
- return $this->_hasPrivate;
- }
-
- // }}}
- // {{{ isRevoked()
-
- /**
- * Gets whether or not this sub-key is revoked
- *
- * @return boolean true if this sub-key is revoked and false if it is not.
- */
- public function isRevoked()
- {
- return $this->_isRevoked;
- }
-
- // }}}
- // {{{ setCreationDate()
-
- /**
- * Sets the creation date of this sub-key
- *
- * The creation date is a Unix timestamp.
- *
- * @param integer $creationDate the creation date of this sub-key.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setCreationDate($creationDate)
- {
- $this->_creationDate = intval($creationDate);
- return $this;
- }
-
- // }}}
- // {{{ setExpirationDate()
-
- /**
- * Sets the expiration date of this sub-key
- *
- * The expiration date is a Unix timestamp. Specify zero if this sub-key
- * does not expire.
- *
- * @param integer $expirationDate the expiration date of this sub-key.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setExpirationDate($expirationDate)
- {
- $this->_expirationDate = intval($expirationDate);
- return $this;
- }
-
- // }}}
- // {{{ setId()
-
- /**
- * Sets the id of this sub-key
- *
- * @param string $id the id of this sub-key.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setId($id)
- {
- $this->_id = strval($id);
- return $this;
- }
-
- // }}}
- // {{{ setAlgorithm()
-
- /**
- * Sets the algorithm used by this sub-key
- *
- * @param integer $algorithm the algorithm used by this sub-key.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setAlgorithm($algorithm)
- {
- $this->_algorithm = intval($algorithm);
- return $this;
- }
-
- // }}}
- // {{{ setFingerprint()
-
- /**
- * Sets the fingerprint of this sub-key
- *
- * @param string $fingerprint the fingerprint of this sub-key.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setFingerprint($fingerprint)
- {
- $this->_fingerprint = strval($fingerprint);
- return $this;
- }
-
- // }}}
- // {{{ setLength()
-
- /**
- * Sets the length of this sub-key in bits
- *
- * @param integer $length the length of this sub-key in bits.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setLength($length)
- {
- $this->_length = intval($length);
- return $this;
- }
-
- // }}}
- // {{{ setCanSign()
-
- /**
- * Sets whether of not this sub-key can sign data
- *
- * @param boolean $canSign true if this sub-key can sign data and false if
- * it can not.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setCanSign($canSign)
- {
- $this->_canSign = ($canSign) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ setCanEncrypt()
-
- /**
- * Sets whether of not this sub-key can encrypt data
- *
- * @param boolean $canEncrypt true if this sub-key can encrypt data and
- * false if it can not.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setCanEncrypt($canEncrypt)
- {
- $this->_canEncrypt = ($canEncrypt) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ setHasPrivate()
-
- /**
- * Sets whether of not the private key for this sub-key exists in the
- * keyring
- *
- * @param boolean $hasPrivate true if the private key for this sub-key
- * exists in the keyring and false if it does
- * not.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setHasPrivate($hasPrivate)
- {
- $this->_hasPrivate = ($hasPrivate) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ setRevoked()
-
- /**
- * Sets whether or not this sub-key is revoked
- *
- * @param boolean $isRevoked whether or not this sub-key is revoked.
- *
- * @return Crypt_GPG_SubKey the current object, for fluent interface.
- */
- public function setRevoked($isRevoked)
- {
- $this->_isRevoked = ($isRevoked) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ parse()
-
- /**
- * Parses a sub-key object from a sub-key string
- *
- * See <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG distribution} for information
- * on how the sub-key string is parsed.
- *
- * @param string $string the string containing the sub-key.
- *
- * @return Crypt_GPG_SubKey the sub-key object parsed from the string.
- */
- public static function parse($string)
- {
- $tokens = explode(':', $string);
-
- $subKey = new Crypt_GPG_SubKey();
-
- $subKey->setId($tokens[4]);
- $subKey->setLength($tokens[2]);
- $subKey->setAlgorithm($tokens[3]);
- $subKey->setCreationDate(self::_parseDate($tokens[5]));
- $subKey->setExpirationDate(self::_parseDate($tokens[6]));
-
- if ($tokens[1] == 'r') {
- $subKey->setRevoked(true);
- }
-
- if (strpos($tokens[11], 's') !== false) {
- $subKey->setCanSign(true);
- }
-
- if (strpos($tokens[11], 'e') !== false) {
- $subKey->setCanEncrypt(true);
- }
-
- return $subKey;
- }
-
- // }}}
- // {{{ _parseDate()
-
- /**
- * Parses a date string as provided by GPG into a UNIX timestamp
- *
- * @param string $string the date string.
- *
- * @return integer the UNIX timestamp corresponding to the provided date
- * string.
- */
- private static function _parseDate($string)
- {
- if ($string == '') {
- $timestamp = 0;
- } else {
- // all times are in UTC according to GPG documentation
- $timeZone = new DateTimeZone('UTC');
-
- if (strpos($string, 'T') === false) {
- // interpret as UNIX timestamp
- $string = '@' . $string;
- }
-
- $date = new DateTime($string, $timeZone);
-
- // convert to UNIX timestamp
- $timestamp = intval($date->format('U'));
- }
-
- return $timestamp;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/UserId.php b/plugins/enigma/lib/Crypt/GPG/UserId.php
deleted file mode 100644
index 04435708c..000000000
--- a/plugins/enigma/lib/Crypt/GPG/UserId.php
+++ /dev/null
@@ -1,373 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Contains a data class representing a GPG user id
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: UserId.php 295621 2010-03-01 04:18:54Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- */
-
-// {{{ class Crypt_GPG_UserId
-
-/**
- * A class for GPG user id information
- *
- * This class is used to store the results of the {@link Crypt_GPG::getKeys()}
- * method. User id objects are members of a {@link Crypt_GPG_Key} object.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008-2010 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @see Crypt_GPG::getKeys()
- * @see Crypt_GPG_Key::getUserIds()
- */
-class Crypt_GPG_UserId
-{
- // {{{ class properties
-
- /**
- * The name field of this user id
- *
- * @var string
- */
- private $_name = '';
-
- /**
- * The comment field of this user id
- *
- * @var string
- */
- private $_comment = '';
-
- /**
- * The email field of this user id
- *
- * @var string
- */
- private $_email = '';
-
- /**
- * Whether or not this user id is revoked
- *
- * @var boolean
- */
- private $_isRevoked = false;
-
- /**
- * Whether or not this user id is valid
- *
- * @var boolean
- */
- private $_isValid = true;
-
- // }}}
- // {{{ __construct()
-
- /**
- * Creates a new user id
- *
- * User ids can be initialized from an array of named values. Available
- * names are:
- *
- * - <kbd>string name</kbd> - the name field of the user id.
- * - <kbd>string comment</kbd> - the comment field of the user id.
- * - <kbd>string email</kbd> - the email field of the user id.
- * - <kbd>boolean valid</kbd> - whether or not the user id is valid.
- * - <kbd>boolean revoked</kbd> - whether or not the user id is revoked.
- *
- * @param Crypt_GPG_UserId|string|array $userId optional. Either an
- * existing user id object, which is copied; a user id string, which
- * is parsed; or an array of initial values.
- */
- public function __construct($userId = null)
- {
- // parse from string
- if (is_string($userId)) {
- $userId = self::parse($userId);
- }
-
- // copy from object
- if ($userId instanceof Crypt_GPG_UserId) {
- $this->_name = $userId->_name;
- $this->_comment = $userId->_comment;
- $this->_email = $userId->_email;
- $this->_isRevoked = $userId->_isRevoked;
- $this->_isValid = $userId->_isValid;
- }
-
- // initialize from array
- if (is_array($userId)) {
- if (array_key_exists('name', $userId)) {
- $this->setName($userId['name']);
- }
-
- if (array_key_exists('comment', $userId)) {
- $this->setComment($userId['comment']);
- }
-
- if (array_key_exists('email', $userId)) {
- $this->setEmail($userId['email']);
- }
-
- if (array_key_exists('revoked', $userId)) {
- $this->setRevoked($userId['revoked']);
- }
-
- if (array_key_exists('valid', $userId)) {
- $this->setValid($userId['valid']);
- }
- }
- }
-
- // }}}
- // {{{ getName()
-
- /**
- * Gets the name field of this user id
- *
- * @return string the name field of this user id.
- */
- public function getName()
- {
- return $this->_name;
- }
-
- // }}}
- // {{{ getComment()
-
- /**
- * Gets the comments field of this user id
- *
- * @return string the comments field of this user id.
- */
- public function getComment()
- {
- return $this->_comment;
- }
-
- // }}}
- // {{{ getEmail()
-
- /**
- * Gets the email field of this user id
- *
- * @return string the email field of this user id.
- */
- public function getEmail()
- {
- return $this->_email;
- }
-
- // }}}
- // {{{ isRevoked()
-
- /**
- * Gets whether or not this user id is revoked
- *
- * @return boolean true if this user id is revoked and false if it is not.
- */
- public function isRevoked()
- {
- return $this->_isRevoked;
- }
-
- // }}}
- // {{{ isValid()
-
- /**
- * Gets whether or not this user id is valid
- *
- * @return boolean true if this user id is valid and false if it is not.
- */
- public function isValid()
- {
- return $this->_isValid;
- }
-
- // }}}
- // {{{ __toString()
-
- /**
- * Gets a string representation of this user id
- *
- * The string is formatted as:
- * <b><kbd>name (comment) <email-address></kbd></b>.
- *
- * @return string a string representation of this user id.
- */
- public function __toString()
- {
- $components = array();
-
- if (strlen($this->_name) > 0) {
- $components[] = $this->_name;
- }
-
- if (strlen($this->_comment) > 0) {
- $components[] = '(' . $this->_comment . ')';
- }
-
- if (strlen($this->_email) > 0) {
- $components[] = '<' . $this->_email. '>';
- }
-
- return implode(' ', $components);
- }
-
- // }}}
- // {{{ setName()
-
- /**
- * Sets the name field of this user id
- *
- * @param string $name the name field of this user id.
- *
- * @return Crypt_GPG_UserId the current object, for fluent interface.
- */
- public function setName($name)
- {
- $this->_name = strval($name);
- return $this;
- }
-
- // }}}
- // {{{ setComment()
-
- /**
- * Sets the comment field of this user id
- *
- * @param string $comment the comment field of this user id.
- *
- * @return Crypt_GPG_UserId the current object, for fluent interface.
- */
- public function setComment($comment)
- {
- $this->_comment = strval($comment);
- return $this;
- }
-
- // }}}
- // {{{ setEmail()
-
- /**
- * Sets the email field of this user id
- *
- * @param string $email the email field of this user id.
- *
- * @return Crypt_GPG_UserId the current object, for fluent interface.
- */
- public function setEmail($email)
- {
- $this->_email = strval($email);
- return $this;
- }
-
- // }}}
- // {{{ setRevoked()
-
- /**
- * Sets whether or not this user id is revoked
- *
- * @param boolean $isRevoked whether or not this user id is revoked.
- *
- * @return Crypt_GPG_UserId the current object, for fluent interface.
- */
- public function setRevoked($isRevoked)
- {
- $this->_isRevoked = ($isRevoked) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ setValid()
-
- /**
- * Sets whether or not this user id is valid
- *
- * @param boolean $isValid whether or not this user id is valid.
- *
- * @return Crypt_GPG_UserId the current object, for fluent interface.
- */
- public function setValid($isValid)
- {
- $this->_isValid = ($isValid) ? true : false;
- return $this;
- }
-
- // }}}
- // {{{ parse()
-
- /**
- * Parses a user id object from a user id string
- *
- * A user id string is of the form:
- * <b><kbd>name (comment) <email-address></kbd></b> with the <i>comment</i>
- * and <i>email-address</i> fields being optional.
- *
- * @param string $string the user id string to parse.
- *
- * @return Crypt_GPG_UserId the user id object parsed from the string.
- */
- public static function parse($string)
- {
- $userId = new Crypt_GPG_UserId();
- $email = '';
- $comment = '';
-
- // get email address from end of string if it exists
- $matches = array();
- if (preg_match('/^(.+?) <([^>]+)>$/', $string, $matches) === 1) {
- $string = $matches[1];
- $email = $matches[2];
- }
-
- // get comment from end of string if it exists
- $matches = array();
- if (preg_match('/^(.+?) \(([^\)]+)\)$/', $string, $matches) === 1) {
- $string = $matches[1];
- $comment = $matches[2];
- }
-
- $name = $string;
-
- $userId->setName($name);
- $userId->setComment($comment);
- $userId->setEmail($email);
-
- return $userId;
- }
-
- // }}}
-}
-
-// }}}
-
-?>
diff --git a/plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php b/plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php
deleted file mode 100644
index 083bd3012..000000000
--- a/plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php
+++ /dev/null
@@ -1,216 +0,0 @@
-<?php
-
-/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
-
-/**
- * Crypt_GPG is a package to use GPG from PHP
- *
- * This file contains an object that handles GPG's status output for the verify
- * operation.
- *
- * PHP version 5
- *
- * LICENSE:
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the
- * License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @version CVS: $Id: VerifyStatusHandler.php 302908 2010-08-31 03:56:54Z gauthierm $
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-
-/**
- * Signature object class definition
- */
-require_once 'Crypt/GPG/Signature.php';
-
-/**
- * Status line handler for the verify operation
- *
- * This class is used internally by Crypt_GPG and does not need be used
- * directly. See the {@link Crypt_GPG} class for end-user API.
- *
- * This class is responsible for building signature objects that are returned
- * by the {@link Crypt_GPG::verify()} method. See <b>doc/DETAILS</b> in the
- * {@link http://www.gnupg.org/download/ GPG distribution} for detailed
- * information on GPG's status output for the verify operation.
- *
- * @category Encryption
- * @package Crypt_GPG
- * @author Michael Gauthier <mike@silverorange.com>
- * @copyright 2008 silverorange
- * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
- * @link http://pear.php.net/package/Crypt_GPG
- * @link http://www.gnupg.org/
- */
-class Crypt_GPG_VerifyStatusHandler
-{
- // {{{ protected properties
-
- /**
- * The current signature id
- *
- * Ths signature id is emitted by GPG before the new signature line so we
- * must remember it temporarily.
- *
- * @var string
- */
- protected $signatureId = '';
-
- /**
- * List of parsed {@link Crypt_GPG_Signature} objects
- *
- * @var array
- */
- protected $signatures = array();
-
- /**
- * Array index of the current signature
- *
- * @var integer
- */
- protected $index = -1;
-
- // }}}
- // {{{ handle()
-
- /**
- * Handles a status line
- *
- * @param string $line the status line to handle.
- *
- * @return void
- */
- public function handle($line)
- {
- $tokens = explode(' ', $line);
- switch ($tokens[0]) {
- case 'GOODSIG':
- case 'EXPSIG':
- case 'EXPKEYSIG':
- case 'REVKEYSIG':
- case 'BADSIG':
- $signature = new Crypt_GPG_Signature();
-
- // if there was a signature id, set it on the new signature
- if ($this->signatureId != '') {
- $signature->setId($this->signatureId);
- $this->signatureId = '';
- }
-
- // Detect whether fingerprint or key id was returned and set
- // signature values appropriately. Key ids are strings of either
- // 16 or 8 hexadecimal characters. Fingerprints are strings of 40
- // hexadecimal characters. The key id is the last 16 characters of
- // the key fingerprint.
- if (strlen($tokens[1]) > 16) {
- $signature->setKeyFingerprint($tokens[1]);
- $signature->setKeyId(substr($tokens[1], -16));
- } else {
- $signature->setKeyId($tokens[1]);
- }
-
- // get user id string
- $string = implode(' ', array_splice($tokens, 2));
- $string = rawurldecode($string);
-
- $signature->setUserId(Crypt_GPG_UserId::parse($string));
-
- $this->index++;
- $this->signatures[$this->index] = $signature;
- break;
-
- case 'ERRSIG':
- $signature = new Crypt_GPG_Signature();
-
- // if there was a signature id, set it on the new signature
- if ($this->signatureId != '') {
- $signature->setId($this->signatureId);
- $this->signatureId = '';
- }
-
- // Detect whether fingerprint or key id was returned and set
- // signature values appropriately. Key ids are strings of either
- // 16 or 8 hexadecimal characters. Fingerprints are strings of 40
- // hexadecimal characters. The key id is the last 16 characters of
- // the key fingerprint.
- if (strlen($tokens[1]) > 16) {
- $signature->setKeyFingerprint($tokens[1]);
- $signature->setKeyId(substr($tokens[1], -16));
- } else {
- $signature->setKeyId($tokens[1]);
- }
-
- $this->index++;
- $this->signatures[$this->index] = $signature;
-
- break;
-
- case 'VALIDSIG':
- if (!array_key_exists($this->index, $this->signatures)) {
- break;
- }
-
- $signature = $this->signatures[$this->index];
-
- $signature->setValid(true);
- $signature->setKeyFingerprint($tokens[1]);
-
- if (strpos($tokens[3], 'T') === false) {
- $signature->setCreationDate($tokens[3]);
- } else {
- $signature->setCreationDate(strtotime($tokens[3]));
- }
-
- if (array_key_exists(4, $tokens)) {
- if (strpos($tokens[4], 'T') === false) {
- $signature->setExpirationDate($tokens[4]);
- } else {
- $signature->setExpirationDate(strtotime($tokens[4]));
- }
- }
-
- break;
-
- case 'SIG_ID':
- // note: signature id comes before new signature line and may not
- // exist for some signature types
- $this->signatureId = $tokens[1];
- break;
- }
- }
-
- // }}}
- // {{{ getSignatures()
-
- /**
- * Gets the {@link Crypt_GPG_Signature} objects parsed by this handler
- *
- * @return array the signature objects parsed by this handler.
- */
- public function getSignatures()
- {
- return $this->signatures;
- }
-
- // }}}
-}
-
-?>
diff --git a/plugins/enigma/lib/enigma_driver.php b/plugins/enigma/lib/enigma_driver.php
deleted file mode 100644
index a9a3e4715..000000000
--- a/plugins/enigma/lib/enigma_driver.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Abstract driver for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-abstract class enigma_driver
-{
- /**
- * Class constructor.
- *
- * @param string User name (email address)
- */
- abstract function __construct($user);
-
- /**
- * Driver initialization.
- *
- * @return mixed NULL on success, enigma_error on failure
- */
- abstract function init();
-
- /**
- * Encryption.
- */
- abstract function encrypt($text, $keys);
-
- /**
- * Decryption..
- */
- abstract function decrypt($text, $key, $passwd);
-
- /**
- * Signing.
- */
- abstract function sign($text, $key, $passwd);
-
- /**
- * Signature verification.
- *
- * @param string Message body
- * @param string Signature, if message is of type PGP/MIME and body doesn't contain it
- *
- * @return mixed Signature information (enigma_signature) or enigma_error
- */
- abstract function verify($text, $signature);
-
- /**
- * Key/Cert file import.
- *
- * @param string File name or file content
- * @param bollean True if first argument is a filename
- *
- * @return mixed Import status array or enigma_error
- */
- abstract function import($content, $isfile=false);
-
- /**
- * Keys listing.
- *
- * @param string Optional pattern for key ID, user ID or fingerprint
- *
- * @return mixed Array of enigma_key objects or enigma_error
- */
- abstract function list_keys($pattern='');
-
- /**
- * Single key information.
- *
- * @param string Key ID, user ID or fingerprint
- *
- * @return mixed Key (enigma_key) object or enigma_error
- */
- abstract function get_key($keyid);
-
- /**
- * Key pair generation.
- *
- * @param array Key/User data
- *
- * @return mixed Key (enigma_key) object or enigma_error
- */
- abstract function gen_key($data);
-
- /**
- * Key deletion.
- */
- abstract function del_key($keyid);
-}
diff --git a/plugins/enigma/lib/enigma_driver_gnupg.php b/plugins/enigma/lib/enigma_driver_gnupg.php
deleted file mode 100644
index 5aa32217e..000000000
--- a/plugins/enigma/lib/enigma_driver_gnupg.php
+++ /dev/null
@@ -1,305 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | GnuPG (PGP) driver for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-require_once 'Crypt/GPG.php';
-
-class enigma_driver_gnupg extends enigma_driver
-{
- private $rc;
- private $gpg;
- private $homedir;
- private $user;
-
- function __construct($user)
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
- $this->user = $user;
- }
-
- /**
- * Driver initialization and environment checking.
- * Should only return critical errors.
- *
- * @return mixed NULL on success, enigma_error on failure
- */
- function init()
- {
- $homedir = $this->rc->config->get('enigma_pgp_homedir', INSTALL_PATH . '/plugins/enigma/home');
-
- if (!$homedir)
- return new enigma_error(enigma_error::E_INTERNAL,
- "Option 'enigma_pgp_homedir' not specified");
-
- // check if homedir exists (create it if not) and is readable
- if (!file_exists($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Keys directory doesn't exists: $homedir");
- if (!is_writable($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Keys directory isn't writeable: $homedir");
-
- $homedir = $homedir . '/' . $this->user;
-
- // check if user's homedir exists (create it if not) and is readable
- if (!file_exists($homedir))
- mkdir($homedir, 0700);
-
- if (!file_exists($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Unable to create keys directory: $homedir");
- if (!is_writable($homedir))
- return new enigma_error(enigma_error::E_INTERNAL,
- "Unable to write to keys directory: $homedir");
-
- $this->homedir = $homedir;
-
- // Create Crypt_GPG object
- try {
- $this->gpg = new Crypt_GPG(array(
- 'homedir' => $this->homedir,
-// 'debug' => true,
- ));
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- function encrypt($text, $keys)
- {
-/*
- foreach ($keys as $key) {
- $this->gpg->addEncryptKey($key);
- }
- $enc = $this->gpg->encrypt($text);
- return $enc;
-*/
- }
-
- function decrypt($text, $key, $passwd)
- {
-// $this->gpg->addDecryptKey($key, $passwd);
- try {
- $dec = $this->gpg->decrypt($text);
- return $dec;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- function sign($text, $key, $passwd)
- {
-/*
- $this->gpg->addSignKey($key, $passwd);
- $signed = $this->gpg->sign($text, Crypt_GPG::SIGN_MODE_DETACHED);
- return $signed;
-*/
- }
-
- function verify($text, $signature)
- {
- try {
- $verified = $this->gpg->verify($text, $signature);
- return $this->parse_signature($verified[0]);
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function import($content, $isfile=false)
- {
- try {
- if ($isfile)
- return $this->gpg->importKeyFile($content);
- else
- return $this->gpg->importKey($content);
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function list_keys($pattern='')
- {
- try {
- $keys = $this->gpg->getKeys($pattern);
- $result = array();
-//print_r($keys);
- foreach ($keys as $idx => $key) {
- $result[] = $this->parse_key($key);
- unset($keys[$idx]);
- }
-//print_r($result);
- return $result;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function get_key($keyid)
- {
- $list = $this->list_keys($keyid);
-
- if (is_array($list))
- return array_shift($list);
-
- // error
- return $list;
- }
-
- public function gen_key($data)
- {
- }
-
- public function del_key($keyid)
- {
-// $this->get_key($keyid);
-
-
- }
-
- public function del_privkey($keyid)
- {
- try {
- $this->gpg->deletePrivateKey($keyid);
- return true;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- public function del_pubkey($keyid)
- {
- try {
- $this->gpg->deletePublicKey($keyid);
- return true;
- }
- catch (Exception $e) {
- return $this->get_error_from_exception($e);
- }
- }
-
- /**
- * Converts Crypt_GPG exception into Enigma's error object
- *
- * @param mixed Exception object
- *
- * @return enigma_error Error object
- */
- private function get_error_from_exception($e)
- {
- $data = array();
-
- if ($e instanceof Crypt_GPG_KeyNotFoundException) {
- $error = enigma_error::E_KEYNOTFOUND;
- $data['id'] = $e->getKeyId();
- }
- else if ($e instanceof Crypt_GPG_BadPassphraseException) {
- $error = enigma_error::E_BADPASS;
- $data['bad'] = $e->getBadPassphrases();
- $data['missing'] = $e->getMissingPassphrases();
- }
- else if ($e instanceof Crypt_GPG_NoDataException)
- $error = enigma_error::E_NODATA;
- else if ($e instanceof Crypt_GPG_DeletePrivateKeyException)
- $error = enigma_error::E_DELKEY;
- else
- $error = enigma_error::E_INTERNAL;
-
- $msg = $e->getMessage();
-
- return new enigma_error($error, $msg, $data);
- }
-
- /**
- * Converts Crypt_GPG_Signature object into Enigma's signature object
- *
- * @param Crypt_GPG_Signature Signature object
- *
- * @return enigma_signature Signature object
- */
- private function parse_signature($sig)
- {
- $user = $sig->getUserId();
-
- $data = new enigma_signature();
- $data->id = $sig->getId();
- $data->valid = $sig->isValid();
- $data->fingerprint = $sig->getKeyFingerprint();
- $data->created = $sig->getCreationDate();
- $data->expires = $sig->getExpirationDate();
- $data->name = $user->getName();
- $data->comment = $user->getComment();
- $data->email = $user->getEmail();
-
- return $data;
- }
-
- /**
- * Converts Crypt_GPG_Key object into Enigma's key object
- *
- * @param Crypt_GPG_Key Key object
- *
- * @return enigma_key Key object
- */
- private function parse_key($key)
- {
- $ekey = new enigma_key();
-
- foreach ($key->getUserIds() as $idx => $user) {
- $id = new enigma_userid();
- $id->name = $user->getName();
- $id->comment = $user->getComment();
- $id->email = $user->getEmail();
- $id->valid = $user->isValid();
- $id->revoked = $user->isRevoked();
-
- $ekey->users[$idx] = $id;
- }
-
- $ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>');
-
- foreach ($key->getSubKeys() as $idx => $subkey) {
- $skey = new enigma_subkey();
- $skey->id = $subkey->getId();
- $skey->revoked = $subkey->isRevoked();
- $skey->created = $subkey->getCreationDate();
- $skey->expires = $subkey->getExpirationDate();
- $skey->fingerprint = $subkey->getFingerprint();
- $skey->has_private = $subkey->hasPrivate();
- $skey->can_sign = $subkey->canSign();
- $skey->can_encrypt = $subkey->canEncrypt();
-
- $ekey->subkeys[$idx] = $skey;
- };
-
- $ekey->id = $ekey->subkeys[0]->id;
-
- return $ekey;
- }
-}
diff --git a/plugins/enigma/lib/enigma_engine.php b/plugins/enigma/lib/enigma_engine.php
deleted file mode 100644
index 59ae1202c..000000000
--- a/plugins/enigma/lib/enigma_engine.php
+++ /dev/null
@@ -1,547 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Engine of the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-
-*/
-
-/*
- RFC2440: OpenPGP Message Format
- RFC3156: MIME Security with OpenPGP
- RFC3851: S/MIME
-*/
-
-class enigma_engine
-{
- private $rc;
- private $enigma;
- private $pgp_driver;
- private $smime_driver;
-
- public $decryptions = array();
- public $signatures = array();
- public $signed_parts = array();
-
-
- /**
- * Plugin initialization.
- */
- function __construct($enigma)
- {
- $rcmail = rcmail::get_instance();
- $this->rc = $rcmail;
- $this->enigma = $enigma;
- }
-
- /**
- * PGP driver initialization.
- */
- function load_pgp_driver()
- {
- if ($this->pgp_driver)
- return;
-
- $driver = 'enigma_driver_' . $this->rc->config->get('enigma_pgp_driver', 'gnupg');
- $username = $this->rc->user->get_username();
-
- // Load driver
- $this->pgp_driver = new $driver($username);
-
- if (!$this->pgp_driver) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: Unable to load PGP driver: $driver"
- ), true, true);
- }
-
- // Initialise driver
- $result = $this->pgp_driver->init();
-
- if ($result instanceof enigma_error) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: ".$result->getMessage()
- ), true, true);
- }
- }
-
- /**
- * S/MIME driver initialization.
- */
- function load_smime_driver()
- {
- if ($this->smime_driver)
- return;
-
- // NOT IMPLEMENTED!
- return;
-
- $driver = 'enigma_driver_' . $this->rc->config->get('enigma_smime_driver', 'phpssl');
- $username = $this->rc->user->get_username();
-
- // Load driver
- $this->smime_driver = new $driver($username);
-
- if (!$this->smime_driver) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: Unable to load S/MIME driver: $driver"
- ), true, true);
- }
-
- // Initialise driver
- $result = $this->smime_driver->init();
-
- if ($result instanceof enigma_error) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: ".$result->getMessage()
- ), true, true);
- }
- }
-
- /**
- * Handler for plain/text message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_plain(&$p)
- {
- $part = $p['structure'];
-
- // Get message body from IMAP server
- $this->set_part_body($part, $p['object']->uid);
-
- // @TODO: big message body can be a file resource
- // PGP signed message
- if (preg_match('/^-----BEGIN PGP SIGNED MESSAGE-----/', $part->body)) {
- $this->parse_plain_signed($p);
- }
- // PGP encrypted message
- else if (preg_match('/^-----BEGIN PGP MESSAGE-----/', $part->body)) {
- $this->parse_plain_encrypted($p);
- }
- }
-
- /**
- * Handler for multipart/signed message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_signed(&$p)
- {
- $struct = $p['structure'];
-
- // S/MIME
- if ($struct->parts[1] && $struct->parts[1]->mimetype == 'application/pkcs7-signature') {
- $this->parse_smime_signed($p);
- }
- // PGP/MIME:
- // The multipart/signed body MUST consist of exactly two parts.
- // The first part contains the signed data in MIME canonical format,
- // including a set of appropriate content headers describing the data.
- // The second body MUST contain the PGP digital signature. It MUST be
- // labeled with a content type of "application/pgp-signature".
- else if ($struct->parts[1] && $struct->parts[1]->mimetype == 'application/pgp-signature') {
- $this->parse_pgp_signed($p);
- }
- }
-
- /**
- * Handler for multipart/encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- function parse_encrypted(&$p)
- {
- $struct = $p['structure'];
-
- // S/MIME
- if ($struct->mimetype == 'application/pkcs7-mime') {
- $this->parse_smime_encrypted($p);
- }
- // PGP/MIME:
- // The multipart/encrypted MUST consist of exactly two parts. The first
- // MIME body part must have a content type of "application/pgp-encrypted".
- // This body contains the control information.
- // The second MIME body part MUST contain the actual encrypted data. It
- // must be labeled with a content type of "application/octet-stream".
- else if ($struct->parts[0] && $struct->parts[0]->mimetype == 'application/pgp-encrypted' &&
- $struct->parts[1] && $struct->parts[1]->mimetype == 'application/octet-stream'
- ) {
- $this->parse_pgp_encrypted($p);
- }
- }
-
- /**
- * Handler for plain signed message.
- * Excludes message and signature bodies and verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_plain_signed(&$p)
- {
- $this->load_pgp_driver();
- $part = $p['structure'];
-
- // Verify signature
- if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
- $sig = $this->pgp_verify($part->body);
- }
-
- // @TODO: Handle big bodies using (temp) files
-
- // In this way we can use fgets on string as on file handle
- $fh = fopen('php://memory', 'br+');
- // @TODO: fopen/fwrite errors handling
- if ($fh) {
- fwrite($fh, $part->body);
- rewind($fh);
- }
- $part->body = null;
-
- // Extract body (and signature?)
- while (!feof($fh)) {
- $line = fgets($fh, 1024);
-
- if ($part->body === null)
- $part->body = '';
- else if (preg_match('/^-----BEGIN PGP SIGNATURE-----/', $line))
- break;
- else
- $part->body .= $line;
- }
-
- // Remove "Hash" Armor Headers
- $part->body = preg_replace('/^.*\r*\n\r*\n/', '', $part->body);
- // de-Dash-Escape (RFC2440)
- $part->body = preg_replace('/(^|\n)- -/', '\\1-', $part->body);
-
- // Store signature data for display
- if (!empty($sig)) {
- $this->signed_parts[$part->mime_id] = $part->mime_id;
- $this->signatures[$part->mime_id] = $sig;
- }
-
- fclose($fh);
- }
-
- /**
- * Handler for PGP/MIME signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_pgp_signed(&$p)
- {
- $this->load_pgp_driver();
- $struct = $p['structure'];
-
- // Verify signature
- if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
- $msg_part = $struct->parts[0];
- $sig_part = $struct->parts[1];
-
- // Get bodies
- $this->set_part_body($msg_part, $p['object']->uid);
- $this->set_part_body($sig_part, $p['object']->uid);
-
- // Verify
- $sig = $this->pgp_verify($msg_part->body, $sig_part->body);
-
- // Store signature data for display
- $this->signatures[$struct->mime_id] = $sig;
-
- // Message can be multipart (assign signature to each subpart)
- if (!empty($msg_part->parts)) {
- foreach ($msg_part->parts as $part)
- $this->signed_parts[$part->mime_id] = $struct->mime_id;
- }
- else
- $this->signed_parts[$msg_part->mime_id] = $struct->mime_id;
-
- // Remove signature file from attachments list
- unset($struct->parts[1]);
- }
- }
-
- /**
- * Handler for S/MIME signed message.
- * Verifies signature.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_smime_signed(&$p)
- {
- $this->load_smime_driver();
- }
-
- /**
- * Handler for plain encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_plain_encrypted(&$p)
- {
- $this->load_pgp_driver();
- $part = $p['structure'];
-
- // Get body
- $this->set_part_body($part, $p['object']->uid);
-
- // Decrypt
- $result = $this->pgp_decrypt($part->body);
-
- // Store decryption status
- $this->decryptions[$part->mime_id] = $result;
-
- // Parse decrypted message
- if ($result === true) {
- // @TODO
- }
- }
-
- /**
- * Handler for PGP/MIME encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_pgp_encrypted(&$p)
- {
- $this->load_pgp_driver();
- $struct = $p['structure'];
- $part = $struct->parts[1];
-
- // Get body
- $this->set_part_body($part, $p['object']->uid);
-
- // Decrypt
- $result = $this->pgp_decrypt($part->body);
-
- $this->decryptions[$part->mime_id] = $result;
-//print_r($part);
- // Parse decrypted message
- if ($result === true) {
- // @TODO
- }
- else {
- // Make sure decryption status message will be displayed
- $part->type = 'content';
- $p['object']->parts[] = $part;
- }
- }
-
- /**
- * Handler for S/MIME encrypted message.
- *
- * @param array Reference to hook's parameters
- */
- private function parse_smime_encrypted(&$p)
- {
- $this->load_smime_driver();
- }
-
- /**
- * PGP signature verification.
- *
- * @param mixed Message body
- * @param mixed Signature body (for MIME messages)
- *
- * @return mixed enigma_signature or enigma_error
- */
- private function pgp_verify(&$msg_body, $sig_body=null)
- {
- // @TODO: Handle big bodies using (temp) files
- // @TODO: caching of verification result
-
- $sig = $this->pgp_driver->verify($msg_body, $sig_body);
-
- if (($sig instanceof enigma_error) && $sig->getCode() != enigma_error::E_KEYNOTFOUND)
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $error->getMessage()
- ), true, false);
-
-//print_r($sig);
- return $sig;
- }
-
- /**
- * PGP message decryption.
- *
- * @param mixed Message body
- *
- * @return mixed True or enigma_error
- */
- private function pgp_decrypt(&$msg_body)
- {
- // @TODO: Handle big bodies using (temp) files
- // @TODO: caching of verification result
-
- $result = $this->pgp_driver->decrypt($msg_body, $key, $pass);
-
-//print_r($result);
-
- if ($result instanceof enigma_error) {
- $err_code = $result->getCode();
- if (!in_array($err_code, array(enigma_error::E_KEYNOTFOUND, enigma_error::E_BADPASS)))
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- return $result;
- }
-
-// $msg_body = $result;
- return true;
- }
-
- /**
- * PGP keys listing.
- *
- * @param mixed Key ID/Name pattern
- *
- * @return mixed Array of keys or enigma_error
- */
- function list_keys($pattern='')
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->list_keys($pattern);
-
- if ($result instanceof enigma_error) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
-
- return $result;
- }
-
- /**
- * PGP key details.
- *
- * @param mixed Key ID
- *
- * @return mixed enigma_key or enigma_error
- */
- function get_key($keyid)
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->get_key($keyid);
-
- if ($result instanceof enigma_error) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
-
- return $result;
- }
-
- /**
- * PGP keys/certs importing.
- *
- * @param mixed Import file name or content
- * @param boolean True if first argument is a filename
- *
- * @return mixed Import status data array or enigma_error
- */
- function import_key($content, $isfile=false)
- {
- $this->load_pgp_driver();
- $result = $this->pgp_driver->import($content, $isfile);
-
- if ($result instanceof enigma_error) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Enigma plugin: " . $result->getMessage()
- ), true, false);
- }
- else {
- $result['imported'] = $result['public_imported'] + $result['private_imported'];
- $result['unchanged'] = $result['public_unchanged'] + $result['private_unchanged'];
- }
-
- return $result;
- }
-
- /**
- * Handler for keys/certs import request action
- */
- function import_file()
- {
- $uid = get_input_value('_uid', RCUBE_INPUT_POST);
- $mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
- $mime_id = get_input_value('_part', RCUBE_INPUT_POST);
-
- if ($uid && $mime_id) {
- $part = $this->rc->imap->get_message_part($uid, $mime_id);
- }
-
- if ($part && is_array($result = $this->import_key($part))) {
- $this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
- array('new' => $result['imported'], 'old' => $result['unchanged']));
- }
- else
- $this->rc->output->show_message('enigma.keysimportfailed', 'error');
-
- $this->rc->output->send();
- }
-
- /**
- * Checks if specified message part contains body data.
- * If body is not set it will be fetched from IMAP server.
- *
- * @param rcube_message_part Message part object
- * @param integer Message UID
- */
- private function set_part_body($part, $uid)
- {
- // @TODO: Create such function in core
- // @TODO: Handle big bodies using file handles
- if (!isset($part->body)) {
- $part->body = $this->rc->imap->get_message_part(
- $uid, $part->mime_id, $part);
- }
- }
-
- /**
- * Adds CSS style file to the page header.
- */
- private function add_css()
- {
- $skin = $this->rc->config->get('skin');
- if (!file_exists($this->home . "/skins/$skin/enigma.css"))
- $skin = 'default';
-
- $this->include_stylesheet("skins/$skin/enigma.css");
- }
-}
diff --git a/plugins/enigma/lib/enigma_error.php b/plugins/enigma/lib/enigma_error.php
deleted file mode 100644
index 9f424dc2b..000000000
--- a/plugins/enigma/lib/enigma_error.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Error class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_error
-{
- private $code;
- private $message;
- private $data = array();
-
- // error codes
- const E_OK = 0;
- const E_INTERNAL = 1;
- const E_NODATA = 2;
- const E_KEYNOTFOUND = 3;
- const E_DELKEY = 4;
- const E_BADPASS = 5;
-
- function __construct($code = null, $message = '', $data = array())
- {
- $this->code = $code;
- $this->message = $message;
- $this->data = $data;
- }
-
- function getCode()
- {
- return $this->code;
- }
-
- function getMessage()
- {
- return $this->message;
- }
-
- function getData($name)
- {
- if ($name)
- return $this->data[$name];
- else
- return $this->data;
- }
-}
diff --git a/plugins/enigma/lib/enigma_key.php b/plugins/enigma/lib/enigma_key.php
deleted file mode 100644
index 520c36b0b..000000000
--- a/plugins/enigma/lib/enigma_key.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Key class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_key
-{
- public $id;
- public $name;
- public $users = array();
- public $subkeys = array();
-
- const TYPE_UNKNOWN = 0;
- const TYPE_KEYPAIR = 1;
- const TYPE_PUBLIC = 2;
-
- /**
- * Keys list sorting callback for usort()
- */
- static function cmp($a, $b)
- {
- return strcmp($a->name, $b->name);
- }
-
- /**
- * Returns key type
- */
- function get_type()
- {
- if ($this->subkeys[0]->has_private)
- return enigma_key::TYPE_KEYPAIR;
- else if (!empty($this->subkeys[0]))
- return enigma_key::TYPE_PUBLIC;
-
- return enigma_key::TYPE_UNKNOWN;
- }
-
- /**
- * Returns true if all user IDs are revoked
- */
- function is_revoked()
- {
- foreach ($this->subkeys as $subkey)
- if (!$subkey->revoked)
- return false;
-
- return true;
- }
-
- /**
- * Returns true if any user ID is valid
- */
- function is_valid()
- {
- foreach ($this->users as $user)
- if ($user->valid)
- return true;
-
- return false;
- }
-
- /**
- * Returns true if any of subkeys is not expired
- */
- function is_expired()
- {
- $now = time();
-
- foreach ($this->subkeys as $subkey)
- if (!$subkey->expires || $subkey->expires > $now)
- return true;
-
- return false;
- }
-
- /**
- * Converts long ID or Fingerprint to short ID
- * Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID
- *
- * @param string Key ID or fingerprint
- * @return string Key short ID
- */
- static function format_id($id)
- {
- // E.g. 04622F2089E037A5 => 89E037A5
-
- return substr($id, -8);
- }
-
- /**
- * Formats fingerprint string
- *
- * @param string Key fingerprint
- *
- * @return string Formatted fingerprint (with spaces)
- */
- static function format_fingerprint($fingerprint)
- {
- if (!$fingerprint)
- return '';
-
- $result = '';
- for ($i=0; $i<40; $i++) {
- if ($i % 4 == 0)
- $result .= ' ';
- $result .= $fingerprint[$i];
- }
- return $result;
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_signature.php b/plugins/enigma/lib/enigma_signature.php
deleted file mode 100644
index 65990903b..000000000
--- a/plugins/enigma/lib/enigma_signature.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | Signature class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_signature
-{
- public $id;
- public $valid;
- public $fingerprint;
- public $created;
- public $expires;
- public $name;
- public $comment;
- public $email;
-}
diff --git a/plugins/enigma/lib/enigma_subkey.php b/plugins/enigma/lib/enigma_subkey.php
deleted file mode 100644
index 1b9fb95ad..000000000
--- a/plugins/enigma/lib/enigma_subkey.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | SubKey class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_subkey
-{
- public $id;
- public $fingerprint;
- public $expires;
- public $created;
- public $revoked;
- public $has_private;
- public $can_sign;
- public $can_encrypt;
-
- /**
- * Converts internal ID to short ID
- * Crypt_GPG uses internal, but e.g. Thunderbird's Enigmail displays short ID
- *
- * @return string Key ID
- */
- function get_short_id()
- {
- // E.g. 04622F2089E037A5 => 89E037A5
- return enigma_key::format_id($this->id);
- }
-
- /**
- * Getter for formatted fingerprint
- *
- * @return string Formatted fingerprint
- */
- function get_fingerprint()
- {
- return enigma_key::format_fingerprint($this->fingerprint);
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_ui.php b/plugins/enigma/lib/enigma_ui.php
deleted file mode 100644
index b9ccff53d..000000000
--- a/plugins/enigma/lib/enigma_ui.php
+++ /dev/null
@@ -1,459 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | User Interface for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_ui
-{
- private $rc;
- private $enigma;
- private $home;
- private $css_added;
- private $data;
-
-
- function __construct($enigma_plugin, $home='')
- {
- $this->enigma = $enigma_plugin;
- $this->rc = $enigma_plugin->rc;
- // we cannot use $enigma_plugin->home here
- $this->home = $home;
- }
-
- /**
- * UI initialization and requests handlers.
- *
- * @param string Preferences section
- */
- function init($section='')
- {
- $this->enigma->include_script('enigma.js');
-
- // Enigma actions
- if ($this->rc->action == 'plugin.enigma') {
- $action = get_input_value('_a', RCUBE_INPUT_GPC);
-
- switch ($action) {
- case 'keyedit':
- $this->key_edit();
- break;
- case 'keyimport':
- $this->key_import();
- break;
- case 'keysearch':
- case 'keylist':
- $this->key_list();
- break;
- case 'keyinfo':
- default:
- $this->key_info();
- }
- }
- // Message composing UI
- else if ($this->rc->action == 'compose') {
- $this->compose_ui();
- }
- // Preferences UI
- else { // if ($this->rc->action == 'edit-prefs') {
- if ($section == 'enigmacerts') {
- $this->rc->output->add_handlers(array(
- 'keyslist' => array($this, 'tpl_certs_list'),
- 'keyframe' => array($this, 'tpl_cert_frame'),
- 'countdisplay' => array($this, 'tpl_certs_rowcount'),
- 'searchform' => array($this->rc->output, 'search_form'),
- ));
- $this->rc->output->set_pagetitle($this->enigma->gettext('enigmacerts'));
- $this->rc->output->send('enigma.certs');
- }
- else {
- $this->rc->output->add_handlers(array(
- 'keyslist' => array($this, 'tpl_keys_list'),
- 'keyframe' => array($this, 'tpl_key_frame'),
- 'countdisplay' => array($this, 'tpl_keys_rowcount'),
- 'searchform' => array($this->rc->output, 'search_form'),
- ));
- $this->rc->output->set_pagetitle($this->enigma->gettext('enigmakeys'));
- $this->rc->output->send('enigma.keys');
- }
- }
- }
-
- /**
- * Adds CSS style file to the page header.
- */
- function add_css()
- {
- if ($this->css_loaded)
- return;
-
- $skin = $this->rc->config->get('skin');
- if (!file_exists($this->home . "/skins/$skin/enigma.css"))
- $skin = 'default';
-
- $this->enigma->include_stylesheet("skins/$skin/enigma.css");
- $this->css_added = true;
- }
-
- /**
- * Template object for key info/edit frame.
- *
- * @param array Object attributes
- *
- * @return string HTML output
- */
- function tpl_key_frame($attrib)
- {
- if (!$attrib['id']) {
- $attrib['id'] = 'rcmkeysframe';
- }
-
- $attrib['name'] = $attrib['id'];
-
- $this->rc->output->set_env('contentframe', $attrib['name']);
- $this->rc->output->set_env('blankpage', $attrib['src'] ?
- $this->rc->output->abs_url($attrib['src']) : 'program/blank.gif');
-
- return html::tag('iframe', $attrib);
- }
-
- /**
- * Template object for list of keys.
- *
- * @param array Object attributes
- *
- * @return string HTML content
- */
- function tpl_keys_list($attrib)
- {
- // add id to message list table if not specified
- if (!strlen($attrib['id'])) {
- $attrib['id'] = 'rcmenigmakeyslist';
- }
-
- // define list of cols to be displayed
- $a_show_cols = array('name');
-
- // create XHTML table
- $out = rcube_table_output($attrib, array(), $a_show_cols, 'id');
-
- // set client env
- $this->rc->output->add_gui_object('keyslist', $attrib['id']);
- $this->rc->output->include_script('list.js');
-
- // add some labels to client
- $this->rc->output->add_label('enigma.keyconfirmdelete');
-
- return $out;
- }
-
- /**
- * Key listing (and searching) request handler
- */
- private function key_list()
- {
- $this->enigma->load_engine();
-
- $pagesize = $this->rc->config->get('pagesize', 100);
- $page = max(intval(get_input_value('_p', RCUBE_INPUT_GPC)), 1);
- $search = get_input_value('_q', RCUBE_INPUT_GPC);
-
- // define list of cols to be displayed
- $a_show_cols = array('name');
- $result = array();
-
- // Get the list
- $list = $this->enigma->engine->list_keys($search);
-
- if ($list && ($list instanceof enigma_error))
- $this->rc->output->show_message('enigma.keylisterror', 'error');
- else if (empty($list))
- $this->rc->output->show_message('enigma.nokeysfound', 'notice');
- else {
- if (is_array($list)) {
- // Save the size
- $listsize = count($list);
-
- // Sort the list by key (user) name
- usort($list, array('enigma_key', 'cmp'));
-
- // Slice current page
- $list = array_slice($list, ($page - 1) * $pagesize, $pagesize);
-
- $size = count($list);
-
- // Add rows
- foreach($list as $idx => $key) {
- $this->rc->output->command('enigma_add_list_row',
- array('name' => Q($key->name), 'id' => $key->id));
- }
- }
- }
-
- $this->rc->output->set_env('search_request', $search);
- $this->rc->output->set_env('pagecount', ceil($listsize/$pagesize));
- $this->rc->output->set_env('current_page', $page);
- $this->rc->output->command('set_rowcount',
- $this->get_rowcount_text($listsize, $size, $page));
-
- $this->rc->output->send();
- }
-
- /**
- * Template object for list records counter.
- *
- * @param array Object attributes
- *
- * @return string HTML output
- */
- function tpl_keys_rowcount($attrib)
- {
- if (!$attrib['id'])
- $attrib['id'] = 'rcmcountdisplay';
-
- $this->rc->output->add_gui_object('countdisplay', $attrib['id']);
-
- return html::span($attrib, $this->get_rowcount_text());
- }
-
- /**
- * Returns text representation of list records counter
- */
- private function get_rowcount_text($all=0, $curr_count=0, $page=1)
- {
- if (!$curr_count)
- $out = $this->enigma->gettext('nokeysfound');
- else {
- $pagesize = $this->rc->config->get('pagesize', 100);
- $first = ($page - 1) * $pagesize;
-
- $out = $this->enigma->gettext(array(
- 'name' => 'keysfromto',
- 'vars' => array(
- 'from' => $first + 1,
- 'to' => $first + $curr_count,
- 'count' => $all)
- ));
- }
-
- return $out;
- }
-
- /**
- * Key information page handler
- */
- private function key_info()
- {
- $id = get_input_value('_id', RCUBE_INPUT_GET);
-
- $this->enigma->load_engine();
- $res = $this->enigma->engine->get_key($id);
-
- if ($res instanceof enigma_key)
- $this->data = $res;
- else { // error
- $this->rc->output->show_message('enigma.keyopenerror', 'error');
- $this->rc->output->command('parent.enigma_loadframe');
- $this->rc->output->send('iframe');
- }
-
- $this->rc->output->add_handlers(array(
- 'keyname' => array($this, 'tpl_key_name'),
- 'keydata' => array($this, 'tpl_key_data'),
- ));
-
- $this->rc->output->set_pagetitle($this->enigma->gettext('keyinfo'));
- $this->rc->output->send('enigma.keyinfo');
- }
-
- /**
- * Template object for key name
- */
- function tpl_key_name($attrib)
- {
- return Q($this->data->name);
- }
-
- /**
- * Template object for key information page content
- */
- function tpl_key_data($attrib)
- {
- $out = '';
- $table = new html_table(array('cols' => 2));
-
- // Key user ID
- $table->add('title', $this->enigma->gettext('keyuserid'));
- $table->add(null, Q($this->data->name));
- // Key ID
- $table->add('title', $this->enigma->gettext('keyid'));
- $table->add(null, $this->data->subkeys[0]->get_short_id());
- // Key type
- $keytype = $this->data->get_type();
- if ($keytype == enigma_key::TYPE_KEYPAIR)
- $type = $this->enigma->gettext('typekeypair');
- else if ($keytype == enigma_key::TYPE_PUBLIC)
- $type = $this->enigma->gettext('typepublickey');
- $table->add('title', $this->enigma->gettext('keytype'));
- $table->add(null, $type);
- // Key fingerprint
- $table->add('title', $this->enigma->gettext('fingerprint'));
- $table->add(null, $this->data->subkeys[0]->get_fingerprint());
-
- $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
-
- $out .= html::tag('fieldset', null,
- html::tag('legend', null,
- $this->enigma->gettext('subkeys')) . $table->show($attrib));
-
- // Additional user IDs
- $table = new html_table(array('cols' => 2));
- // Columns: User ID, Validity
-
- $out .= html::tag('fieldset', null,
- html::tag('legend', null,
- $this->enigma->gettext('userids')) . $table->show($attrib));
-
- return $out;
- }
-
- /**
- * Key import page handler
- */
- private function key_import()
- {
- // Import process
- if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'])) {
- $this->enigma->load_engine();
- $result = $this->enigma->engine->import_key($_FILES['_file']['tmp_name'], true);
-
- if (is_array($result)) {
- // reload list if any keys has been added
- if ($result['imported']) {
- $this->rc->output->command('parent.enigma_list', 1);
- }
- else
- $this->rc->output->command('parent.enigma_loadframe');
-
- $this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
- array('new' => $result['imported'], 'old' => $result['unchanged']));
-
- $this->rc->output->send('iframe');
- }
- else
- $this->rc->output->show_message('enigma.keysimportfailed', 'error');
- }
- else if ($err = $_FILES['_file']['error']) {
- if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
- $this->rc->output->show_message('filesizeerror', 'error',
- array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))));
- } else {
- $this->rc->output->show_message('fileuploaderror', 'error');
- }
- }
-
- $this->rc->output->add_handlers(array(
- 'importform' => array($this, 'tpl_key_import_form'),
- ));
-
- $this->rc->output->set_pagetitle($this->enigma->gettext('keyimport'));
- $this->rc->output->send('enigma.keyimport');
- }
-
- /**
- * Template object for key import (upload) form
- */
- function tpl_key_import_form($attrib)
- {
- $attrib += array('id' => 'rcmKeyImportForm');
-
- $upload = new html_inputfield(array('type' => 'file', 'name' => '_file',
- 'id' => 'rcmimportfile', 'size' => 30));
-
- $form = html::p(null,
- Q($this->enigma->gettext('keyimporttext'), 'show')
- . html::br() . html::br() . $upload->show()
- );
-
- $this->rc->output->add_label('selectimportfile', 'importwait');
- $this->rc->output->add_gui_object('importform', $attrib['id']);
-
- $out = $this->rc->output->form_tag(array(
- 'action' => $this->rc->url(array('action' => 'plugin.enigma', 'a' => 'keyimport')),
- 'method' => 'post',
- 'enctype' => 'multipart/form-data') + $attrib,
- $form);
-
- return $out;
- }
-
- private function compose_ui()
- {
- if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_value('_id', RCUBE_INPUT_GET))
- return;
-
- // Options menu button
- // @TODO: make this work with non-default skins
- $this->enigma->add_button(array(
- 'name' => 'enigmamenu',
- 'imagepas' => 'skins/default/enigma.png',
- 'imageact' => 'skins/default/enigma.png',
- 'onclick' => "rcmail_ui.show_popup('enigmamenu', true); return false",
- 'title' => 'securityoptions',
- 'domain' => 'enigma',
- ), 'toolbar');
-
- // Options menu contents
- $this->enigma->add_hook('render_page', array($this, 'compose_menu'));
- }
-
- function compose_menu($p)
- {
- $menu = new html_table(array('cols' => 2));
- $chbox = new html_checkbox(array('value' => 1));
-
- $menu->add(null, html::label(array('for' => 'enigmadefaultopt'),
- Q($this->enigma->gettext('identdefault'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_default', 'id' => 'enigmadefaultopt')));
-
- $menu->add(null, html::label(array('for' => 'enigmasignopt'),
- Q($this->enigma->gettext('signmsg'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_sign', 'id' => 'enigmasignopt')));
-
- $menu->add(null, html::label(array('for' => 'enigmacryptopt'),
- Q($this->enigma->gettext('encryptmsg'))));
- $menu->add(null, $chbox->show(1, array('name' => '_enigma_crypt', 'id' => 'enigmacryptopt')));
-
- $menu = html::div(array('id' => 'enigmamenu', 'class' => 'popupmenu'),
- $menu->show());
-
- $p['content'] = preg_replace('/(<form name="form"[^>]+>)/i', '\\1'."\n$menu", $p['content']);
-
- return $p;
-
- }
-
-}
diff --git a/plugins/enigma/lib/enigma_userid.php b/plugins/enigma/lib/enigma_userid.php
deleted file mode 100644
index 36185e718..000000000
--- a/plugins/enigma/lib/enigma_userid.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/*
- +-------------------------------------------------------------------------+
- | User ID class for the Enigma Plugin |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-*/
-
-class enigma_userid
-{
- public $revoked;
- public $valid;
- public $name;
- public $comment;
- public $email;
-}
diff --git a/plugins/enigma/localization/en_US.inc b/plugins/enigma/localization/en_US.inc
deleted file mode 100644
index e0f03d9a0..000000000
--- a/plugins/enigma/localization/en_US.inc
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-$labels = array();
-$labels['enigmasettings'] = 'Enigma: Settings';
-$labels['enigmacerts'] = 'Enigma: Certificates (S/MIME)';
-$labels['enigmakeys'] = 'Enigma: Keys (PGP)';
-$labels['keysfromto'] = 'Keys $from to $to of $count';
-$labels['keyname'] = 'Name';
-$labels['keyid'] = 'Key ID';
-$labels['keyuserid'] = 'User ID';
-$labels['keytype'] = 'Key type';
-$labels['fingerprint'] = 'Fingerprint';
-$labels['subkeys'] = 'Subkeys';
-$labels['basicinfo'] = 'Basic Information';
-$labels['userids'] = 'Additional User IDs';
-$labels['typepublickey'] = 'public key';
-$labels['typekeypair'] = 'key pair';
-$labels['keyattfound'] = 'This message contains attached PGP key(s).';
-$labels['keyattimport'] = 'Import key(s)';
-
-$labels['createkeys'] = 'Create a new key pair';
-$labels['importkeys'] = 'Import key(s)';
-$labels['exportkeys'] = 'Export key(s)';
-$labels['deletekeys'] = 'Delete key(s)';
-$labels['keyactions'] = 'Key actions...';
-$labels['keydisable'] = 'Disable key';
-$labels['keyrevoke'] = 'Revoke key';
-$labels['keysend'] = 'Send public key in a message';
-$labels['keychpass'] = 'Change password';
-
-$labels['securityoptions'] = 'Message security options...';
-$labels['identdefault'] = 'Use settings of selected identity';
-$labels['encryptmsg'] = 'Encrypt this message';
-$labels['signmsg'] = 'Digitally sign this message';
-
-$messages = array();
-$messages['sigvalid'] = 'Verified signature from $sender.';
-$messages['siginvalid'] = 'Invalid signature from $sender.';
-$messages['signokey'] = 'Unverified signature. Public key not found. Key ID: $keyid.';
-$messages['sigerror'] = 'Unverified signature. Internal error.';
-$messages['decryptok'] = 'Message decrypted.';
-$messages['decrypterror'] = 'Decryption failed.';
-$messages['decryptnokey'] = 'Decryption failed. Private key not found. Key ID: $keyid.';
-$messages['decryptbadpass'] = 'Decryption failed. Bad password.';
-$messages['nokeysfound'] = 'No keys found';
-$messages['keyopenerror'] = 'Unable to get key information! Internal error.';
-$messages['keylisterror'] = 'Unable to list keys! Internal error.';
-$messages['keysimportfailed'] = 'Unable to import key(s)! Internal error.';
-$messages['keysimportsuccess'] = 'Key(s) imported successfully. Imported: $new, unchanged: $old.';
-$messages['keyconfirmdelete'] = 'Are you sure, you want to delete selected key(s)?';
-$messages['keyimporttext'] = 'You can import private and public key(s) or revocation signatures in ASCII-Armor format.';
-
-?>
diff --git a/plugins/enigma/localization/ja_JP.inc b/plugins/enigma/localization/ja_JP.inc
deleted file mode 100644
index 882014440..000000000
--- a/plugins/enigma/localization/ja_JP.inc
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-// EN-Revision: 4203
-
-$labels = array();
-$labels['enigmasettings'] = 'Enigma: 設定';
-$labels['enigmacerts'] = 'Enigma: 証明書 (S/MIME)';
-$labels['enigmakeys'] = 'Enigma: 鍵 (PGP)';
-$labels['keysfromto'] = '鍵の一覧 $from ~ $to (合計: $count )';
-$labels['keyname'] = '名前';
-$labels['keyid'] = '鍵 ID';
-$labels['keyuserid'] = 'ユーザー ID';
-$labels['keytype'] = '鍵の種類';
-$labels['fingerprint'] = '指紋';
-$labels['subkeys'] = 'Subkeys';
-$labels['basicinfo'] = '基本情報';
-$labels['userids'] = '追加のユーザー ID';
-$labels['typepublickey'] = '公開鍵';
-$labels['typekeypair'] = '鍵のペア';
-$labels['keyattfound'] = 'このメールは PGP 鍵の添付があります。';
-$labels['keyattimport'] = '鍵のインポート';
-
-$labels['createkeys'] = '新しい鍵のペアを作成する';
-$labels['importkeys'] = '鍵のインポート';
-$labels['exportkeys'] = '鍵のエクスポート';
-$labels['deletekeys'] = '鍵の削除';
-$labels['keyactions'] = '鍵の操作...';
-$labels['keydisable'] = '鍵を無効にする';
-$labels['keyrevoke'] = '鍵を取り消す';
-$labels['keysend'] = 'メッセージに公開鍵を含んで送信する';
-$labels['keychpass'] = 'パスワードの変更';
-
-$labels['securityoptions'] = 'メールのセキュリティ オプション...';
-$labels['identdefault'] = '選択した識別子の設定を使う';
-$labels['encryptmsg'] = 'このメールの暗号化';
-$labels['signmsg'] = 'このメールのデジタル署名';
-
-$messages = array();
-$messages['sigvalid'] = '$sender からの署名を検証しました。';
-$messages['siginvalid'] = '$sender からの署名が正しくありません。';
-$messages['signokey'] = '署名は未検証です。公開鍵が見つかりません。鍵 ID: $keyid';
-$messages['sigerror'] = '署名は未検証です。内部エラーです。';
-$messages['decryptok'] = 'メールを復号しました。';
-$messages['decrypterror'] = '復号に失敗しました。';
-$messages['decryptnokey'] = '復号に失敗しました。秘密鍵が見つかりません。鍵 ID: $keyid.';
-$messages['decryptbadpass'] = '復号に失敗しました。パスワードが正しくありません。';
-$messages['nokeysfound'] = '鍵が見つかりません。';
-$messages['keyopenerror'] = '鍵情報の取得に失敗しました! 内部エラーです。';
-$messages['keylisterror'] = '鍵情報のリストに失敗しました! 内部エラーです。';
-$messages['keysimportfailed'] = '鍵のインポートに失敗しました! 内部エラーです。';
-$messages['keysimportsuccess'] = '鍵をインポートしました。インポート: $new, 未変更: $old';
-$messages['keyconfirmdelete'] = '選択した鍵を本当に削除しますか?';
-$messages['keyimporttext'] = '秘密鍵と公開鍵のインポート、または ASCII 形式の署名を無効にできます。';
-
-?>
diff --git a/plugins/enigma/skins/default/enigma.css b/plugins/enigma/skins/default/enigma.css
deleted file mode 100644
index b1c656f82..000000000
--- a/plugins/enigma/skins/default/enigma.css
+++ /dev/null
@@ -1,182 +0,0 @@
-/*** Style for Enigma plugin ***/
-
-/***** Messages displaying *****/
-
-#enigma-message,
-/* fixes border-top */
-#messagebody div #enigma-message
-{
- margin: 0;
- margin-bottom: 5px;
- min-height: 20px;
- padding: 10px 10px 6px 46px;
-}
-
-div.enigmaerror,
-/* fixes border-top */
-#messagebody div.enigmaerror
-{
- background: url(enigma_error.png) 6px 1px no-repeat;
- background-color: #EF9398;
- border: 1px solid #DC5757;
-}
-
-div.enigmanotice,
-/* fixes border-top */
-#messagebody div.enigmanotice
-{
- background: url(enigma.png) 6px 1px no-repeat;
- background-color: #A6EF7B;
- border: 1px solid #76C83F;
-}
-
-div.enigmawarning,
-/* fixes border-top */
-#messagebody div.enigmawarning
-{
- background: url(enigma.png) 6px 1px no-repeat;
- background-color: #F7FDCB;
- border: 1px solid #C2D071;
-}
-
-#enigma-message a
-{
- color: #666666;
- padding-left: 10px;
-}
-
-#enigma-message a:hover
-{
- color: #333333;
-}
-
-/***** Keys/Certs Management *****/
-
-div.enigmascreen
-{
- position: absolute;
- top: 65px;
- right: 10px;
- bottom: 10px;
- left: 10px;
-}
-
-#enigmacontent-box
-{
- position: absolute;
- top: 0px;
- left: 290px;
- right: 0px;
- bottom: 0px;
- border: 1px solid #999999;
- overflow: hidden;
-}
-
-#enigmakeyslist
-{
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- border: 1px solid #999999;
- background-color: #F9F9F9;
- overflow: hidden;
-}
-
-#keylistcountbar
-{
- margin-top: 4px;
- margin-left: 4px;
-}
-
-#keys-table
-{
- width: 100%;
- table-layout: fixed;
-}
-
-#keys-table td
-{
- cursor: default;
- text-overflow: ellipsis;
- -o-text-overflow: ellipsis;
-}
-
-#key-details table td.title
-{
- font-weight: bold;
- text-align: right;
-}
-
-#keystoolbar
-{
- position: absolute;
- top: 30px;
- left: 10px;
- height: 35px;
-}
-
-#keystoolbar a
-{
- padding-right: 10px;
-}
-
-#keystoolbar a.button,
-#keystoolbar a.buttonPas,
-#keystoolbar span.separator {
- display: block;
- float: left;
- width: 32px;
- height: 32px;
- padding: 0;
- margin-right: 10px;
- overflow: hidden;
- background: url(keys_toolbar.png) 0 0 no-repeat transparent;
- opacity: 0.99; /* this is needed to make buttons appear correctly in Chrome */
-}
-
-#keystoolbar a.buttonPas {
- opacity: 0.35;
-}
-
-#keystoolbar a.createSel {
- background-position: 0 -32px;
-}
-
-#keystoolbar a.create {
- background-position: 0 0;
-}
-
-#keystoolbar a.deleteSel {
- background-position: -32px -32px;
-}
-
-#keystoolbar a.delete {
- background-position: -32px 0;
-}
-
-#keystoolbar a.importSel {
- background-position: -64px -32px;
-}
-
-#keystoolbar a.import {
- background-position: -64px 0;
-}
-
-#keystoolbar a.exportSel {
- background-position: -96px -32px;
-}
-
-#keystoolbar a.export {
- background-position: -96px 0;
-}
-
-#keystoolbar a.keymenu {
- background-position: -128px 0;
- width: 36px;
-}
-
-#keystoolbar span.separator {
- width: 5px;
- background-position: -166px 0;
-}
diff --git a/plugins/enigma/skins/default/enigma.png b/plugins/enigma/skins/default/enigma.png
deleted file mode 100644
index 3ef106e2a..000000000
--- a/plugins/enigma/skins/default/enigma.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/default/enigma_error.png b/plugins/enigma/skins/default/enigma_error.png
deleted file mode 100644
index 9bf100efd..000000000
--- a/plugins/enigma/skins/default/enigma_error.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/default/key.png b/plugins/enigma/skins/default/key.png
deleted file mode 100644
index ea1cbd11c..000000000
--- a/plugins/enigma/skins/default/key.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/default/key_add.png b/plugins/enigma/skins/default/key_add.png
deleted file mode 100644
index f22cc870a..000000000
--- a/plugins/enigma/skins/default/key_add.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/default/keys_toolbar.png b/plugins/enigma/skins/default/keys_toolbar.png
deleted file mode 100644
index 7cc258cc8..000000000
--- a/plugins/enigma/skins/default/keys_toolbar.png
+++ /dev/null
Binary files differ
diff --git a/plugins/enigma/skins/default/templates/keyimport.html b/plugins/enigma/skins/default/templates/keyimport.html
deleted file mode 100644
index 4e0b304a5..000000000
--- a/plugins/enigma/skins/default/templates/keyimport.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title><roundcube:object name="pagetitle" /></title>
-<roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/enigma.css" />
-</head>
-<body class="iframe">
-
-<div id="keyimport-title" class="boxtitle"><roundcube:label name="enigma.importkeys" /></div>
-
-<div id="import-form" class="boxcontent">
- <roundcube:object name="importform" />
- <p>
- <br /><roundcube:button command="plugin.enigma-import" type="input" class="button mainaction" label="import" />
- </p>
-</div>
-
-</body>
-</html>
diff --git a/plugins/enigma/skins/default/templates/keyinfo.html b/plugins/enigma/skins/default/templates/keyinfo.html
deleted file mode 100644
index 2e8ed61db..000000000
--- a/plugins/enigma/skins/default/templates/keyinfo.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title><roundcube:object name="pagetitle" /></title>
-<roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/enigma.css" />
-</head>
-<body class="iframe">
-
-<div id="keyinfo-title" class="boxtitle"><roundcube:object name="keyname" part="name" /></div>
-
-<div id="key-details" class="boxcontent">
- <roundcube:object name="keydata" />
-</div>
-
-</body>
-</html>
diff --git a/plugins/enigma/skins/default/templates/keys.html b/plugins/enigma/skins/default/templates/keys.html
deleted file mode 100644
index 810c4a211..000000000
--- a/plugins/enigma/skins/default/templates/keys.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title><roundcube:object name="pagetitle" /></title>
-<roundcube:include file="/includes/links.html" />
-<link rel="stylesheet" type="text/css" href="/this/enigma.css" />
-<script type="text/javascript" src="/functions.js"></script>
-<script type="text/javascript" src="/splitter.js"></script>
-<style type="text/css">
-#enigmakeyslist { width: <roundcube:exp expression="!empty(cookie:enigmaviewsplitter) ? cookie:enigmaviewsplitter-5 : 210" />px; }
-#enigmacontent-box { left: <roundcube:exp expression="!empty(cookie:enigmaviewsplitter) ? cookie:enigmaviewsplitter+5 : 220" />px;
-<roundcube:exp expression="browser:ie ? ('width:expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:enigmaeviewsplitter) ? cookie:enigmaviewsplitter+5 : 220).')+\\'px\\');') : ''" />
-}
-</style>
-</head>
-<body class="iframe" onload="rcube_init_mail_ui()">
-
-<div id="prefs-title" class="boxtitle"><roundcube:label name="enigma.enigmakeys" /></div>
-<div id="prefs-details" class="boxcontent">
-
-<div id="keystoolbar">
- <roundcube:button command="plugin.enigma-key-create" type="link" class="buttonPas create" classAct="button create" classSel="button createSel" title="enigma.createkeys" content=" " />
- <roundcube:button command="plugin.enigma-key-delete" type="link" class="buttonPas delete" classAct="button delete" classSel="button deleteSel" title="enigma.deletekeys" content=" " />
- <span class="separator">&nbsp;</span>
- <roundcube:button command="plugin.enigma-key-import" type="link" class="buttonPas import" classAct="button import" classSel="button importSel" title="enigma.importkeys" content=" " />
- <roundcube:button command="plugin.enigma-key-export" type="link" class="buttonPas export" classAct="button export" classSel="button exportSel" title="enigma.exportkeys" content=" " />
- <roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button keymenu" title="enigma.keyactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " />
-</div>
-
-<div id="quicksearchbar" style="top: 35px; right: 10px;">
- <roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass.png" />
- <roundcube:object name="searchform" id="quicksearchbox" />
- <roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
-</div>
-
-<div class="enigmascreen">
-
-<div id="enigmakeyslist">
-<div class="boxtitle"><roundcube:label name="enigma.keyname" /></div>
-<div class="boxlistcontent">
- <roundcube:object name="keyslist" id="keys-table" class="records-table" cellspacing="0" noheader="true" />
-</div>
-<div class="boxfooter">
-<div id="keylistcountbar" class="pagenav">
- <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstpage" content=" " />
- <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previouspage" content=" " />
- <roundcube:object name="countdisplay" style="padding:0 .5em; float:left" />
- <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextpage" content=" " />
- <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastpage" content=" " />
-</div>
-</div>
-</div>
-
-<script type="text/javascript">
- var enigmaviewsplit = new rcube_splitter({id:'enigmaviewsplitter', p1: 'enigmakeyslist', p2: 'enigmacontent-box', orientation: 'v', relative: true, start: 215});
- rcmail.add_onload('enigmaviewsplit.init()');
-</script>
-
-<div id="enigmacontent-box">
- <roundcube:object name="keyframe" id="keyframe" width="100%" height="100%" frameborder="0" src="/watermark.html" />
-</div>
-
-</div>
-</div>
-
-<div id="messagemenu" class="popupmenu">
- <ul class="toolbarmenu">
- <li><roundcube:button class="disablelink" command="enigma.key-disable" label="enigma.keydisable" target="_blank" classAct="disablelink active" /></li>
- <li><roundcube:button class="revokelink" command="enigma.key-revoke" label="enigma.keyrevoke" classAct="revokelink active" /></li>
- <li class="separator_below"><roundcube:button class="sendlink" command="enigma.key-send" label="enigma.keysend" classAct="sendlink active" /></li>
- <li><roundcube:button class="chpasslink" command="enigma.key-chpass" label="enigma.keychpass" classAct="chpasslink active" /></li>
- </ul>
-</div>
-
-</body>
-</html>
diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php
deleted file mode 100644
index edf8e1f45..000000000
--- a/plugins/kolab_addressbook/kolab_addressbook.php
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-
-require_once(dirname(__FILE__) . '/rcube_kolab_contacts.php');
-
-/**
- * Kolab address book
- *
- * Sample plugin to add a new address book source with data from Kolab storage
- * This is work-in-progress for the Roundcube+Kolab integration.
- *
- * @author Thomas Bruederli <roundcube@gmail.com>
- *
- */
-class kolab_addressbook extends rcube_plugin
-{
- private $folders;
- private $sources;
-
- /**
- * Required startup method of a Roundcube plugin
- */
- public function init()
- {
- // load required plugin
- $this->require_plugin('kolab_core');
-
- $this->add_texts('localization');
-
- // register hooks
- $this->add_hook('addressbooks_list', array($this, 'address_sources'));
- $this->add_hook('addressbook_get', array($this, 'get_address_book'));
- $this->add_hook('contact_form', array($this, 'contact_form'));
-
- // extend list of address sources to be used for autocompletion
- $rcmail = rcmail::get_instance();
- if ($rcmail->action == 'autocomplete' || $rcmail->action == 'group-expand') {
- $sources = (array) $rcmail->config->get('autocomplete_addressbooks', array());
- foreach ($this->_list_sources() as $abook_id => $abook) {
- if (!in_array($abook_id, $sources))
- $sources[] = $abook_id;
- }
- $rcmail->config->set('autocomplete_addressbooks', $sources);
- }
- }
-
- /**
- * Handler for the addressbooks_list hook.
- *
- * This will add all instances of available Kolab-based address books
- * to the list of address sources of Roundcube.
- *
- * @param array Hash array with hook parameters
- * @return array Hash array with modified hook parameters
- */
- public function address_sources($p)
- {
- foreach ($this->_list_sources() as $abook_id => $abook) {
- // register this address source
- $p['sources'][$abook_id] = array(
- 'id' => $abook_id,
- 'name' => $abook->get_name(),
- 'readonly' => $abook->readonly,
- 'groups' => $abook->groups,
- );
- }
-
- return $p;
- }
-
-
- /**
- * Getter for the rcube_addressbook instance
- */
- public function get_address_book($p)
- {
- if ($this->sources[$p['id']]) {
- $p['instance'] = $this->sources[$p['id']];
- }
-
- return $p;
- }
-
-
- private function _list_sources()
- {
- // already read sources
- if (isset($this->sources))
- return $this->sources;
-
- // get all folders that have "contact" type
- $this->folders = rcube_kolab::get_folders('contact');
- $this->sources = array();
-
- if (PEAR::isError($this->folders)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Failed to list contact folders from Kolab server:" . $this->folders->getMessage()),
- true, false);
- }
- else {
- foreach ($this->folders as $c_folder) {
- // create instance of rcube_contacts
- $abook_id = strtolower(asciiwords(strtr($c_folder->name, '/.', '--')));
- $abook = new rcube_kolab_contacts($c_folder->name);
- $this->sources[$abook_id] = $abook;
- }
- }
-
- return $this->sources;
- }
-
-
- /**
- * Plugin hook called before rendering the contact form or detail view
- */
- public function contact_form($p)
- {
- // extend the list of contact fields to be displayed in the 'info' section
- if (is_array($p['form']['info'])) {
- $p['form']['info']['content']['initials'] = array('size' => 6);
- $p['form']['info']['content']['anniversary'] = array('size' => 12, 'render_func' => 'rcmail_format_date_col');
-
- // TODO: add more Kolab-specific fields
-
- // re-order fields according to the coltypes list
- $block = array();
- $contacts = reset($this->sources);
- foreach ($contacts->coltypes as $col => $prop) {
- if (isset($p['form']['info']['content'][$col]))
- $block[$col] = $p['form']['info']['content'][$col];
- }
-
- $p['form']['info']['content'] = $block;
- }
-
- return $p;
- }
-
-}
diff --git a/plugins/kolab_addressbook/localization/en_US.inc b/plugins/kolab_addressbook/localization/en_US.inc
deleted file mode 100644
index d22318b04..000000000
--- a/plugins/kolab_addressbook/localization/en_US.inc
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-$labels = array();
-$labels['initials'] = 'Initials';
-$labels['anniversary'] = 'Anniversary';
-
-?> \ No newline at end of file
diff --git a/plugins/kolab_addressbook/rcube_kolab_contacts.php b/plugins/kolab_addressbook/rcube_kolab_contacts.php
deleted file mode 100644
index 5e5646e68..000000000
--- a/plugins/kolab_addressbook/rcube_kolab_contacts.php
+++ /dev/null
@@ -1,829 +0,0 @@
-<?php
-
-
-/**
- * Backend class for a custom address book
- *
- * This part of the Roundcube+Kolab integration and connects the
- * rcube_addressbook interface with the rcube_kolab wrapper for Kolab_Storage
- *
- * @author Thomas Bruederli
- * @see rcube_addressbook
- */
-class rcube_kolab_contacts extends rcube_addressbook
-{
- public $primary_key = 'ID';
- public $readonly = false;
- public $groups = true;
- public $coltypes = array(
- 'name' => array('limit' => 1),
- 'firstname' => array('limit' => 1),
- 'surname' => array('limit' => 1),
- 'middlename' => array('limit' => 1),
- 'prefix' => array('limit' => 1),
- 'suffix' => array('limit' => 1),
- 'nickname' => array('limit' => 1),
- 'jobtitle' => array('limit' => 1),
- 'organization' => array('limit' => 1),
- 'department' => array('limit' => 1),
- 'gender' => array('limit' => 1),
- 'initials' => array('type' => 'text', 'size' => 6, 'limit' => 1, 'label' => 'kolab_addressbook.initials'),
- 'email' => array('subtypes' => null),
- 'phone' => array(),
- 'im' => array('limit' => 1),
- 'website' => array('limit' => 1, 'subtypes' => null),
- 'address' => array('limit' => 2, 'subtypes' => array('home','business')),
- 'birthday' => array('limit' => 1),
- 'anniversary' => array('type' => 'date', 'size' => 12, 'limit' => 1, 'label' => 'kolab_addressbook.anniversary'),
- // TODO: define more Kolab-specific fields such as: office-location, profession, manager-name, assistant, spouse-name, children, language, latitude, longitude, pgp-publickey, free-busy-url
- 'notes' => array(),
- );
-
- private $gid;
- private $imap;
- private $kolab;
- private $folder;
- private $contactstorage;
- private $liststorage;
- private $contacts;
- private $distlists;
- private $groupmembers;
- private $id2uid;
- private $filter;
- private $result;
- private $imap_folder = 'INBOX/Contacts';
- private $gender_map = array(0 => 'male', 1 => 'female');
- private $phonetypemap = array('home' => 'home1', 'work' => 'business1', 'work2' => 'business2', 'workfax' => 'businessfax');
- private $addresstypemap = array('work' => 'business');
- private $fieldmap = array(
- // kolab => roundcube
- 'full-name' => 'name',
- 'given-name' => 'firstname',
- 'middle-names' => 'middlename',
- 'last-name' => 'surname',
- 'prefix' => 'prefix',
- 'suffix' => 'suffix',
- 'nick-name' => 'nickname',
- 'organization' => 'organization',
- 'department' => 'department',
- 'job-title' => 'jobtitle',
- 'initials' => 'initials',
- 'birthday' => 'birthday',
- 'anniversary' => 'anniversary',
- 'im-address' => 'im:aim',
- 'web-page' => 'website',
- 'body' => 'notes',
- );
-
-
- public function __construct($imap_folder = null)
- {
- if ($imap_folder)
- $this->imap_folder = $imap_folder;
-
- // extend coltypes configuration
- $format = rcube_kolab::get_format('contact');
- $this->coltypes['phone']['subtypes'] = $format->_phone_types;
- $this->coltypes['address']['subtypes'] = $format->_address_types;
-
- // set localized labels for proprietary cols
- foreach ($this->coltypes as $col => $prop) {
- if (is_string($prop['label']))
- $this->coltypes[$col]['label'] = rcube_label($prop['label']);
- }
-
- // fetch objects from the given IMAP folder
- $this->contactstorage = rcube_kolab::get_storage($this->imap_folder);
- $this->liststorage = rcube_kolab::get_storage($this->imap_folder, 'distributionlist');
-
- $this->ready = !PEAR::isError($this->contactstorage) && !PEAR::isError($this->liststorage);
- }
-
-
- /**
- * Getter for the address book name to be displayed
- *
- * @return string Name of this address book
- */
- public function get_name()
- {
- return strtr(preg_replace('!^(INBOX|user)/!i', '', $this->imap_folder), '/', ':');
- }
-
-
- /**
- * Setter for the current group
- */
- public function set_group($gid)
- {
- $this->gid = $gid;
- }
-
-
- /**
- * Save a search string for future listings
- *
- * @param mixed Search params to use in listing method, obtained by get_search_set()
- */
- public function set_search_set($filter)
- {
- $this->filter = $filter;
- }
-
-
- /**
- * Getter for saved search properties
- *
- * @return mixed Search properties used by this class
- */
- public function get_search_set()
- {
- return $this->filter;
- }
-
-
- /**
- * Reset saved results and search parameters
- */
- public function reset()
- {
- $this->result = null;
- $this->filter = null;
- }
-
-
- /**
- * List all active contact groups of this source
- *
- * @param string Optional search string to match group name
- * @return array Indexed list of contact groups, each a hash array
- */
- function list_groups($search = null)
- {
- $this->_fetch_groups();
- $groups = array();
- foreach ((array)$this->distlists as $group) {
- if (!$search || strstr(strtolower($group['last-name']), strtolower($search)))
- $groups[] = array('ID' => $group['ID'], 'name' => $group['last-name']);
- }
- return $groups;
- }
-
- /**
- * List the current set of contact records
- *
- * @param array List of cols to show
- * @param int Only return this number of records, use negative values for tail
- * @return array Indexed list of contact records, each a hash array
- */
- public function list_records($cols=null, $subset=0)
- {
- $this->result = $this->count();
-
- // list member of the selected group
- if ($this->gid) {
- $seen = array();
- $this->result->count = 0;
- foreach ((array)$this->distlists[$this->gid]['member'] as $member) {
- // skip member that don't match the search filter
- if ($this->filter && array_search($member['ID'], $this->filter) === false)
- continue;
- if ($this->contacts[$member['ID']] && !$seen[$member['ID']]++)
- $this->result->count++;
- }
- $ids = array_keys($seen);
- }
- else
- $ids = $this->filter ? $this->filter : array_keys($this->contacts);
-
- // fill contact data into the current result set
- $i = $j = 0;
- foreach ($ids as $id) {
- if ($i++ < $this->result->first)
- continue;
- $this->result->add($this->contacts[$id]);
- if (++$j == $this->page_size)
- break;
- }
-
- return $this->result;
- }
-
-
- /**
- * Search records
- *
- * @param array List of fields to search in
- * @param string Search value
- * @param boolean True if results are requested, False if count only
- * @param boolean True to skip the count query (select only)
- * @param array List of fields that cannot be empty
- * @return object rcube_result_set List of contact records and 'count' value
- */
- public function search($fields, $value, $strict=false, $select=true, $nocount=false, $required=array())
- {
- $this->_fetch_contacts();
-
- // search by ID
- if ($fields == $this->primary_key) {
- return $this->get_record($value);
- }
-
- $value = strtolower($value);
- if (!is_array($fields))
- $fields = array($fields);
- if (!is_array($required) && !empty($required))
- $required = array($required);
-
- $this->filter = array();
-
- // search be iterating over all records in memory
- foreach ($this->contacts as $id => $contact) {
- // check if current contact has required values, otherwise skip it
- if ($required) {
- foreach ($required as $f)
- if (empty($contact[$f]))
- continue 2;
- }
- foreach ($fields as $f) {
- foreach ((array)$contact[$f] as $val) {
- $val = strtolower($val);
- if (($strict && $val == $value) || (!$strict && strstr($val, $value))) {
- $this->filter[] = $id;
- break 2;
- }
- }
- }
- }
-
- // list records (now limited by $this->filter)
- return $this->list_records();
- }
-
-
- /**
- * Count number of available contacts in database
- *
- * @return rcube_result_set Result set with values for 'count' and 'first'
- */
- public function count()
- {
- $this->_fetch_contacts();
- $this->_fetch_groups();
- $count = $this->gid ? count($this->distlists[$this->gid]['member']) : ($this->filter ? count($this->filter) : count($this->contacts));
- return new rcube_result_set($count, ($this->list_page-1) * $this->page_size);
- }
-
-
- /**
- * Return the last result set
- *
- * @return rcube_result_set Current result set or NULL if nothing selected yet
- */
- public function get_result()
- {
- return $this->result;
- }
-
- /**
- * Get a specific contact record
- *
- * @param mixed record identifier(s)
- * @param boolean True to return record as associative array, otherwise a result set is returned
- * @return mixed Result object with all record fields or False if not found
- */
- public function get_record($id, $assoc=false)
- {
- $this->_fetch_contacts();
- if ($this->contacts[$id]) {
- $this->result = new rcube_result_set(1);
- $this->result->add($this->contacts[$id]);
- return $assoc ? $this->contacts[$id] : $this->result;
- }
-
- return false;
- }
-
-
- /**
- * Get group assignments of a specific contact record
- *
- * @param mixed Record identifier
- * @return array List of assigned groups as ID=>Name pairs
- */
- public function get_record_groups($id)
- {
- $out = array();
- $this->_fetch_groups();
-
- foreach ((array)$this->groupmembers[$id] as $gid) {
- if ($group = $this->distlists[$gid])
- $out[$gid] = $group['last-name'];
- }
-
- return $out;
- }
-
-
- /**
- * Create a new contact record
- *
- * @param array Assoziative array with save data
- * Keys: Field name with optional section in the form FIELD:SECTION
- * Values: Field value. Can be either a string or an array of strings for multiple values
- * @param boolean True to check for duplicates first
- * @return mixed The created record ID on success, False on error
- */
- public function insert($save_data, $check=false)
- {
- if (!is_array($save_data))
- return false;
-
- $insert_id = $existing = false;
-
- // check for existing records by e-mail comparison
- if ($check) {
- foreach ($this->get_col_values('email', $save_data, true) as $email) {
- if (($res = $this->search('email', $email, true, false)) && $res->count) {
- $existing = true;
- break;
- }
- }
- }
-
- if (!$existing) {
- // generate new Kolab contact item
- $object = $this->_from_rcube_contact($save_data);
- $object['uid'] = $this->contactstorage->generateUID();
-
- $saved = $this->contactstorage->save($object);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving contact object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- $contact = $this->_to_rcube_contact($object);
- $id = $contact['ID'];
- $this->contacts[$id] = $contact;
- $this->id2uid[$id] = $object['uid'];
- $insert_id = $id;
- }
- }
-
- return $insert_id;
- }
-
-
- /**
- * Update a specific contact record
- *
- * @param mixed Record identifier
- * @param array Assoziative array with save data
- * Keys: Field name with optional section in the form FIELD:SECTION
- * Values: Field value. Can be either a string or an array of strings for multiple values
- * @return boolean True on success, False on error
- */
- public function update($id, $save_data)
- {
- $updated = false;
- $this->_fetch_contacts();
- if ($this->contacts[$id] && ($uid = $this->id2uid[$id])) {
- $old = $this->contactstorage->getObject($uid);
- $object = array_merge($old, $this->_from_rcube_contact($save_data));
-
- $saved = $this->contactstorage->save($object, $uid);
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving contact object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- $this->contacts[$id] = $this->_to_rcube_contact($object);
- $updated = true;
- }
- }
-
- return $updated;
- }
-
- /**
- * Mark one or more contact records as deleted
- *
- * @param array Record identifiers
- */
- public function delete($ids)
- {
- $this->_fetch_contacts();
- $this->_fetch_groups();
-
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $count = 0;
- foreach ($ids as $id) {
- if ($uid = $this->id2uid[$id]) {
- $deleted = $this->contactstorage->delete($uid);
-
- if (PEAR::isError($deleted)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error deleting a contact object from the Kolab server:" . $deleted->getMessage()),
- true, false);
- }
- else {
- // remove from distribution lists
- foreach ((array)$this->groupmembers[$id] as $gid)
- $this->remove_from_group($gid, $id);
-
- // clear internal cache
- unset($this->contacts[$id], $this->id2uid[$id], $this->groupmembers[$id]);
- $count++;
- }
- }
- }
-
- return $count;
- }
-
- /**
- * Remove all records from the database
- */
- public function delete_all()
- {
- if (!PEAR::isError($this->contactstorage->deleteAll())) {
- $this->contacts = array();
- $this->id2uid = array();
- $this->result = null;
- }
- }
-
-
- /**
- * Close connection to source
- * Called on script shutdown
- */
- public function close()
- {
- rcube_kolab::shutdown();
- }
-
-
- /**
- * Create a contact group with the given name
- *
- * @param string The group name
- * @return mixed False on error, array with record props in success
- */
- function create_group($name)
- {
- $this->_fetch_groups();
- $result = false;
-
- $list = array(
- 'uid' => $this->liststorage->generateUID(),
- 'last-name' => $name,
- 'member' => array(),
- );
- $saved = $this->liststorage->save($list);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- return false;
- }
- else {
- $id = md5($list['uid']);
- $this->distlists[$record['ID']] = $list;
- $result = array('id' => $id, 'name' => $name);
- }
-
- return $result;
- }
-
- /**
- * Delete the given group and all linked group members
- *
- * @param string Group identifier
- * @return boolean True on success, false if no data was changed
- */
- function delete_group($gid)
- {
- $this->_fetch_groups();
- $result = false;
-
- if ($list = $this->distlists[$gid])
- $deleted = $this->liststorage->delete($list['uid']);
-
- if (PEAR::isError($deleted)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error deleting distribution-list object from the Kolab server:" . $deleted->getMessage()),
- true, false);
- }
- else
- $result = true;
-
- return $result;
- }
-
- /**
- * Rename a specific contact group
- *
- * @param string Group identifier
- * @param string New name to set for this group
- * @return boolean New name on success, false if no data was changed
- */
- function rename_group($gid, $newname)
- {
- $this->_fetch_groups();
- $list = $this->distlists[$gid];
-
- if ($newname != $list['last-name']) {
- $list['last-name'] = $newname;
- $saved = $this->liststorage->save($list, $list['uid']);
- }
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- return false;
- }
-
- return $newname;
- }
-
- /**
- * Add the given contact records the a certain group
- *
- * @param string Group identifier
- * @param array List of contact identifiers to be added
- * @return int Number of contacts added
- */
- function add_to_group($gid, $ids)
- {
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $added = 0;
- $exists = array();
-
- $this->_fetch_groups();
- $this->_fetch_contacts();
- $list = $this->distlists[$gid];
-
- foreach ((array)$list['member'] as $i => $member)
- $exists[] = $member['ID'];
-
- // substract existing assignments from list
- $ids = array_diff($ids, $exists);
-
- foreach ($ids as $contact_id) {
- if ($uid = $this->id2uid[$contact_id]) {
- $contact = $this->contacts[$contact_id];
- foreach ($this->get_col_values('email', $contact, true) as $email) {
- $list['member'][] = array(
- 'uid' => $uid,
- 'display-name' => $contact['name'],
- 'smtp-address' => $email,
- );
- }
- $this->groupmembers[$contact_id][] = $gid;
- $added++;
- }
- }
-
- if ($added)
- $saved = $this->liststorage->save($list, $list['uid']);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list to Kolab server:" . $saved->getMessage()),
- true, false);
- $added = false;
- }
- else {
- $this->distlists[$gid] = $list;
- }
-
- return $added;
- }
-
- /**
- * Remove the given contact records from a certain group
- *
- * @param string Group identifier
- * @param array List of contact identifiers to be removed
- * @return int Number of deleted group members
- */
- function remove_from_group($gid, $ids)
- {
- if (!is_array($ids))
- $ids = explode(',', $ids);
-
- $this->_fetch_groups();
- if (!($list = $this->distlists[$gid]))
- return false;
-
- $new_member = array();
- foreach ((array)$list['member'] as $member) {
- if (!in_array($member['ID'], $ids))
- $new_member[] = $member;
- }
-
- // write distribution list back to server
- $list['member'] = $new_member;
- $saved = $this->liststorage->save($list, $list['uid']);
-
- if (PEAR::isError($saved)) {
- raise_error(array(
- 'code' => 600, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Error saving distribution-list object to Kolab server:" . $saved->getMessage()),
- true, false);
- }
- else {
- // remove group assigments in local cache
- foreach ($ids as $id) {
- $j = array_search($gid, $this->groupmembers[$id]);
- unset($this->groupmembers[$id][$j]);
- }
- $this->distlists[$gid] = $list;
- return true;
- }
-
- return false;
- }
-
-
- /**
- * Simply fetch all records and store them in private member vars
- */
- private function _fetch_contacts()
- {
- if (!isset($this->contacts)) {
- // read contacts
- $this->contacts = $this->id2uid = array();
- foreach ((array)$this->contactstorage->getObjects() as $record) {
- $contact = $this->_to_rcube_contact($record);
- $id = $contact['ID'];
- $this->contacts[$id] = $contact;
- $this->id2uid[$id] = $record['uid'];
- }
-
- // TODO: sort data arrays according to desired list sorting
- }
- }
-
-
- /**
- * Read distribution-lists AKA groups from server
- */
- private function _fetch_groups()
- {
- if (!isset($this->distlists)) {
- $this->distlists = $this->groupmembers = array();
- foreach ((array)$this->liststorage->getObjects() as $record) {
- // FIXME: folders without any distribution-list objects return contacts instead ?!
- if ($record['__type'] != 'Group')
- continue;
- $record['ID'] = md5($record['uid']);
- foreach ((array)$record['member'] as $i => $member) {
- $mid = md5($member['uid']);
- $record['member'][$i]['ID'] = $mid;
- $this->groupmembers[$mid][] = $record['ID'];
- }
- $this->distlists[$record['ID']] = $record;
- }
- }
- }
-
-
- /**
- * Map fields from internal Kolab_Format to Roundcube contact format
- */
- private function _to_rcube_contact($record)
- {
- $out = array(
- 'ID' => md5($record['uid']),
- 'email' => array(),
- 'phone' => array(),
- );
-
- foreach ($this->fieldmap as $kolab => $rcube) {
- if (strlen($record[$kolab]))
- $out[$rcube] = $record[$kolab];
- }
-
- if (isset($record['gender']))
- $out['gender'] = $this->gender_map[$record['gender']];
-
- foreach ((array)$record['email'] as $i => $email)
- $out['email'][] = $email['smtp-address'];
-
- if (!$record['email'] && $record['emails'])
- $out['email'] = preg_split('/,\s*/', $record['emails']);
-
- foreach ((array)$record['phone'] as $i => $phone)
- $out['phone:'.$phone['type']][] = $phone['number'];
-
- if (is_array($record['address'])) {
- foreach ($record['address'] as $i => $adr) {
- $key = 'address:' . $adr['type'];
- $out[$key][] = array(
- 'street' => $adr['street'],
- 'locality' => $adr['locality'],
- 'zipcode' => $adr['postal-code'],
- 'region' => $adr['region'],
- 'country' => $adr['country'],
- );
- }
- }
-
- // remove empty fields
- return array_filter($out);
- }
-
- private function _from_rcube_contact($contact)
- {
- $object = array();
-
- foreach (array_flip($this->fieldmap) as $rcube => $kolab) {
- if (isset($contact[$rcube]))
- $object[$kolab] = is_array($contact[$rcube]) ? $contact[$rcube][0] : $contact[$rcube];
- else if ($rcube .= ':home' && isset($contact[$rcube]))
- $object[$kolab] = is_array($contact[$rcube]) ? $contact[$rcube][0] : $contact[$rcube];
- }
-
- // format dates
- if ($object['birthday'] && ($date = @strtotime($object['birthday'])))
- $object['birthday'] = date('Y-m-d', $date);
- if ($object['anniversary'] && ($date = @strtotime($object['anniversary'])))
- $object['anniversary'] = date('Y-m-d', $date);
-
- $gendermap = array_flip($this->gender_map);
- if (isset($contact['gender']))
- $object['gender'] = $gendermap[$contact['gender']];
-
- $emails = $this->get_col_values('email', $contact, true);
- $object['emails'] = join(', ', $emails);
-
- foreach ($this->get_col_values('phone', $contact) as $type => $values) {
- if ($this->phonetypemap[$type])
- $type = $this->phonetypemap[$type];
- foreach ((array)$values as $phone)
- $object['phone'][] = array('number' => $phone, 'type' => $type);
- }
-
- foreach ($this->get_col_values('address', $contact) as $type => $values) {
- if ($this->addresstypemap[$type])
- $type = $this->addresstypemap[$type];
-
- $basekey = 'addr-' . $type . '-';
- foreach ((array)$values as $adr) {
- // switch type if slot is already taken
- if (isset($object[$basekey . 'type'])) {
- $type = $type == 'home' ? 'business' : 'home';
- $basekey = 'addr-' . $type . '-';
- }
-
- if (!isset($object[$basekey . 'type'])) {
- $object[$basekey . 'type'] = $type;
- $object[$basekey . 'street'] = $adr['street'];
- $object[$basekey . 'locality'] = $adr['locality'];
- $object[$basekey . 'postal-code'] = $adr['zipcode'];
- $object[$basekey . 'region'] = $adr['region'];
- $object[$basekey . 'country'] = $adr['country'];
- }
- else {
- $object['address'][] = array(
- 'type' => $type,
- 'street' => $adr['street'],
- 'locality' => $adr['locality'],
- 'postal-code' => $adr['zipcode'],
- 'region' => $adr['region'],
- 'country' => $adr['country'],
- );
- }
- }
- }
-
- return $object;
- }
-
-}
diff --git a/plugins/kolab_core/README.txt b/plugins/kolab_core/README.txt
deleted file mode 100644
index 87537c0b8..000000000
--- a/plugins/kolab_core/README.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-Kolab Integration Plugin README
--------------------------------
-
-This plugin relies on classes from the Horde project. In order to have all
-the required files available you need to install the following packages from
-Horde:
- Horde_Framework
- Kolab_Format
- Kolab_Storage
- Horde_NLS
- Horde_DOM
-
-This is best done using PEAR. Make sure that the local PEAR directory is in
-the PHP isntall path and execute the following commands to install the
-required packages:
-
-pear channel-discover pear.horde.org
-
-pear install horde/Horde_Framework
-pear install horde/Horde_DOM
-pear install horde/Horde_NLS
-pear install horde/Horde_Share
-pear install horde/Log
-pear install horde/Kolab_Format
-pear install horde/Kolab_Storage
-
-
-Configuration
--------------
-
-Rename the config.inc.php.dist to config.inc.php within this plugin directory
-and add the corresponding values for your local Kolab server.
diff --git a/plugins/kolab_core/config.inc.php.dist b/plugins/kolab_core/config.inc.php.dist
deleted file mode 100644
index b6ac25a4d..000000000
--- a/plugins/kolab_core/config.inc.php.dist
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-// Sample configuration for Kolab LDAP binding used by Kolab_Storage
-$rcmail_config['kolab']['ldap']['basedn'] = 'dc=kolabserver,dc=local';
-$rcmail_config['kolab']['ldap']['phpdn'] = 'cn=nobody,cn=internal,dc=kolabserver,dc=local';
-$rcmail_config['kolab']['ldap']['phppw'] = '<ldap-pwd-goes-here>';
-
-?>
diff --git a/plugins/kolab_core/kolab_core.php b/plugins/kolab_core/kolab_core.php
deleted file mode 100644
index e98b02dcd..000000000
--- a/plugins/kolab_core/kolab_core.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * Kolab core library
- *
- * Plugin to setup a basic environment for interaction with a Kolab server.
- * Other Kolab-related plugins will depend on it and can use the static API rcube_core
- *
- * This is work-in-progress for the Roundcube+Kolab integration.
- *
- * @author Thomas Bruederli <roundcube@gmail.com>
- *
- */
-class kolab_core extends rcube_plugin
-{
- /**
- * Required startup method of a Roundcube plugin
- */
- public function init()
- {
- // load local config
- $this->load_config();
-
- // extend include path to load bundled Horde classes
- $include_path = $this->home . PATH_SEPARATOR . ini_get('include_path');
- set_include_path($include_path);
- }
-
-}
-
diff --git a/plugins/kolab_core/rcube_kolab.php b/plugins/kolab_core/rcube_kolab.php
deleted file mode 100644
index 94511e55d..000000000
--- a/plugins/kolab_core/rcube_kolab.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-
-require_once 'Horde/Kolab/Storage/List.php';
-require_once 'Horde/Kolab/Format.php';
-require_once 'Horde/Auth.php';
-require_once 'Horde/Auth/kolab.php';
-require_once 'Horde/Perms.php';
-
-/**
- * Glue class to handle access to the Kolab data using the Kolab_* classes
- * from the Horde project.
- *
- * @author Thomas Bruederli
- */
-class rcube_kolab
-{
- private static $horde_auth;
-
-
- /**
- * Setup the environment needed by the Kolab_* classes to access Kolab data
- */
- public static function setup()
- {
- global $conf;
-
- // setup already done
- if (self::$horde_auth)
- return;
-
- $rcmail = rcmail::get_instance();
-
- // load ldap credentials from local config
- $conf['kolab'] = $rcmail->config->get('kolab');
-
- $conf['kolab']['ldap']['server'] = 'ldap://' . $_SESSION['imap_host'] . ':389';
- $conf['kolab']['imap']['server'] = $_SESSION['imap_host'];
- $conf['kolab']['imap']['port'] = $_SESSION['imap_port'];
-
- // pass the current IMAP authentication credentials to the Horde auth system
- self::$horde_auth = Auth::singleton('kolab');
- if (self::$horde_auth->authenticate($_SESSION['username'], array('password' => ($pwd = $rcmail->decrypt($_SESSION['password']))), false)) {
- $_SESSION['__auth'] = array(
- 'authenticated' => true,
- 'userId' => $_SESSION['username'],
- 'timestamp' => time(),
- 'remote_addr' => $_SERVER['REMOTE_ADDR'],
- );
- Auth::setCredential('password', $pwd);
- }
- }
-
-
- /**
- * Get instance of a Kolab (XML) format object
- *
- * @param string Data type (contact,event,task,note)
- * @return object Horde_Kolab_Format_XML The format object
- */
- public static function get_format($type)
- {
- self::setup();
- return Horde_Kolab_Format::factory('XML', $type);
- }
-
- /**
- * Get a list of storage folders for the given data type
- *
- * @param string Data type to list folders for (contact,event,task,note)
- * @return array List of Kolab_Folder objects
- */
- public static function get_folders($type)
- {
- self::setup();
- $kolab = Kolab_List::singleton();
- return $kolab->getByType($type);
- }
-
- /**
- * Get storage object for read/write access to the Kolab backend
- *
- * @param string IMAP folder to access
- * @param string Object type to deal with (leave empty for auto-detection using annotations)
- * @return object Kolab_Data The data storage object
- */
- public static function get_storage($folder, $data_type = null)
- {
- self::setup();
- $kolab = Kolab_List::singleton();
- return $kolab->getFolder($folder)->getData($data_type);
- }
-
- /**
- * Cleanup session data when done
- */
- public static function shutdown()
- {
- if (isset($_SESSION['__auth'])) {
- // unset auth data from session. no need to store it persistantly
- unset($_SESSION['__auth']);
-
- // FIXME: remove strange numeric entries
- foreach ($_SESSION as $key => $val) {
- if (!$val && is_numeric($key))
- unset($_SESSION[$key]);
- }
- }
- }
-}