diff options
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 .= ' ' . 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.pngBinary files differ deleted file mode 100644 index 3ef106e2a..000000000 --- a/plugins/enigma/skins/default/enigma.png +++ /dev/null diff --git a/plugins/enigma/skins/default/enigma_error.png b/plugins/enigma/skins/default/enigma_error.pngBinary files differ deleted file mode 100644 index 9bf100efd..000000000 --- a/plugins/enigma/skins/default/enigma_error.png +++ /dev/null diff --git a/plugins/enigma/skins/default/key.png b/plugins/enigma/skins/default/key.pngBinary files differ deleted file mode 100644 index ea1cbd11c..000000000 --- a/plugins/enigma/skins/default/key.png +++ /dev/null diff --git a/plugins/enigma/skins/default/key_add.png b/plugins/enigma/skins/default/key_add.pngBinary files differ deleted file mode 100644 index f22cc870a..000000000 --- a/plugins/enigma/skins/default/key_add.png +++ /dev/null diff --git a/plugins/enigma/skins/default/keys_toolbar.png b/plugins/enigma/skins/default/keys_toolbar.pngBinary files differ deleted file mode 100644 index 7cc258cc8..000000000 --- a/plugins/enigma/skins/default/keys_toolbar.png +++ /dev/null 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"> </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]); -            } -        } -    } -} | 
