summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2013-10-06 15:02:25 +0200
committerAleksander Machniak <alec@alec.pl>2013-10-06 15:02:25 +0200
commit4daaa09438bc05f9d5d6cf339cc0b60b511057e9 (patch)
tree1e997f86db73e6b53e6ea29d2d1c507ac802dd48 /plugins
parentbba13c33a097ac35ef8a29ef255be3ac47858f78 (diff)
Move PEAR libs from plugins into main Roundcube lib directory,
list them as dependencies in INSTALL file (#1489182)
Diffstat (limited to 'plugins')
-rw-r--r--plugins/enigma/lib/Crypt/GPG.php2542
-rw-r--r--plugins/enigma/lib/Crypt/GPG/DecryptStatusHandler.php336
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Engine.php1758
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Exceptions.php473
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Key.php223
-rw-r--r--plugins/enigma/lib/Crypt/GPG/Signature.php428
-rw-r--r--plugins/enigma/lib/Crypt/GPG/SubKey.php649
-rw-r--r--plugins/enigma/lib/Crypt/GPG/UserId.php373
-rw-r--r--plugins/enigma/lib/Crypt/GPG/VerifyStatusHandler.php216
-rw-r--r--plugins/managesieve/Changelog1
-rw-r--r--plugins/managesieve/lib/Net/Sieve.php1276
11 files changed, 1 insertions, 8274 deletions
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/managesieve/Changelog b/plugins/managesieve/Changelog
index c792c81da..115aec14f 100644
--- a/plugins/managesieve/Changelog
+++ b/plugins/managesieve/Changelog
@@ -1,3 +1,4 @@
+- lib/Net Sieve.php moved to Roundcube /lib directory
- Added managesieve_domains option to limit redirect destinations
- Fix bug where at least one additional address of vacation message was required (#1489345)
- Fix so i;ascii-numeric comparator is not forced as default for :count and :value operators
diff --git a/plugins/managesieve/lib/Net/Sieve.php b/plugins/managesieve/lib/Net/Sieve.php
deleted file mode 100644
index 8a0a9b0e1..000000000
--- a/plugins/managesieve/lib/Net/Sieve.php
+++ /dev/null
@@ -1,1276 +0,0 @@
-<?php
-/**
- * This file contains the Net_Sieve class.
- *
- * PHP version 4
- *
- * +-----------------------------------------------------------------------+
- * | All rights reserved. |
- * | |
- * | Redistribution and use in source and binary forms, with or without |
- * | modification, are permitted provided that the following conditions |
- * | are met: |
- * | |
- * | o Redistributions of source code must retain the above copyright |
- * | notice, this list of conditions and the following disclaimer. |
- * | o Redistributions in binary form must reproduce the above copyright |
- * | notice, this list of conditions and the following disclaimer in the |
- * | documentation and/or other materials provided with the distribution.|
- * | |
- * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
- * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
- * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
- * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
- * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
- * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
- * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
- * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
- * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
- * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
- * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- * +-----------------------------------------------------------------------+
- *
- * @category Networking
- * @package Net_Sieve
- * @author Richard Heyes <richard@phpguru.org>
- * @author Damian Fernandez Sosa <damlists@cnba.uba.ar>
- * @author Anish Mistry <amistry@am-productions.biz>
- * @author Jan Schneider <jan@horde.org>
- * @copyright 2002-2003 Richard Heyes
- * @copyright 2006-2008 Anish Mistry
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version SVN: $Id: Sieve.php 300898 2010-07-01 09:49:02Z yunosh $
- * @link http://pear.php.net/package/Net_Sieve
- */
-
-require_once 'PEAR.php';
-require_once 'Net/Socket.php';
-
-/**
- * TODO
- *
- * o supportsAuthMech()
- */
-
-/**
- * Disconnected state
- * @const NET_SIEVE_STATE_DISCONNECTED
- */
-define('NET_SIEVE_STATE_DISCONNECTED', 1, true);
-
-/**
- * Authorisation state
- * @const NET_SIEVE_STATE_AUTHORISATION
- */
-define('NET_SIEVE_STATE_AUTHORISATION', 2, true);
-
-/**
- * Transaction state
- * @const NET_SIEVE_STATE_TRANSACTION
- */
-define('NET_SIEVE_STATE_TRANSACTION', 3, true);
-
-
-/**
- * A class for talking to the timsieved server which comes with Cyrus IMAP.
- *
- * @category Networking
- * @package Net_Sieve
- * @author Richard Heyes <richard@phpguru.org>
- * @author Damian Fernandez Sosa <damlists@cnba.uba.ar>
- * @author Anish Mistry <amistry@am-productions.biz>
- * @author Jan Schneider <jan@horde.org>
- * @copyright 2002-2003 Richard Heyes
- * @copyright 2006-2008 Anish Mistry
- * @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version Release: 1.3.0
- * @link http://pear.php.net/package/Net_Sieve
- * @link http://www.ietf.org/rfc/rfc3028.txt RFC 3028 (Sieve: A Mail
- * Filtering Language)
- * @link http://tools.ietf.org/html/draft-ietf-sieve-managesieve A
- * Protocol for Remotely Managing Sieve Scripts
- */
-class Net_Sieve
-{
- /**
- * The authentication methods this class supports.
- *
- * Can be overwritten if having problems with certain methods.
- *
- * @var array
- */
- var $supportedAuthMethods = array('DIGEST-MD5', 'CRAM-MD5', 'EXTERNAL',
- 'PLAIN' , 'LOGIN');
-
- /**
- * SASL authentication methods that require Auth_SASL.
- *
- * @var array
- */
- var $supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5');
-
- /**
- * The socket handle.
- *
- * @var resource
- */
- var $_sock;
-
- /**
- * Parameters and connection information.
- *
- * @var array
- */
- var $_data;
-
- /**
- * Current state of the connection.
- *
- * One of the NET_SIEVE_STATE_* constants.
- *
- * @var integer
- */
- var $_state;
-
- /**
- * Constructor error.
- *
- * @var PEAR_Error
- */
- var $_error;
-
- /**
- * Whether to enable debugging.
- *
- * @var boolean
- */
- var $_debug = false;
-
- /**
- * Debug output handler.
- *
- * This has to be a valid callback.
- *
- * @var string|array
- */
- var $_debug_handler = null;
-
- /**
- * Whether to pick up an already established connection.
- *
- * @var boolean
- */
- var $_bypassAuth = false;
-
- /**
- * Whether to use TLS if available.
- *
- * @var boolean
- */
- var $_useTLS = true;
-
- /**
- * Additional options for stream_context_create().
- *
- * @var array
- */
- var $_options = null;
-
- /**
- * Maximum number of referral loops
- *
- * @var array
- */
- var $_maxReferralCount = 15;
-
- /**
- * Constructor.
- *
- * Sets up the object, connects to the server and logs in. Stores any
- * generated error in $this->_error, which can be retrieved using the
- * getError() method.
- *
- * @param string $user Login username.
- * @param string $pass Login password.
- * @param string $host Hostname of server.
- * @param string $port Port of server.
- * @param string $logintype Type of login to perform (see
- * $supportedAuthMethods).
- * @param string $euser Effective user. If authenticating as an
- * administrator, login as this user.
- * @param boolean $debug Whether to enable debugging (@see setDebug()).
- * @param string $bypassAuth Skip the authentication phase. Useful if the
- * socket is already open.
- * @param boolean $useTLS Use TLS if available.
- * @param array $options Additional options for
- * stream_context_create().
- * @param mixed $handler A callback handler for the debug output.
- */
- function Net_Sieve($user = null, $pass = null, $host = 'localhost',
- $port = 2000, $logintype = '', $euser = '',
- $debug = false, $bypassAuth = false, $useTLS = true,
- $options = null, $handler = null)
- {
- $this->_state = NET_SIEVE_STATE_DISCONNECTED;
- $this->_data['user'] = $user;
- $this->_data['pass'] = $pass;
- $this->_data['host'] = $host;
- $this->_data['port'] = $port;
- $this->_data['logintype'] = $logintype;
- $this->_data['euser'] = $euser;
- $this->_sock = new Net_Socket();
- $this->_bypassAuth = $bypassAuth;
- $this->_useTLS = $useTLS;
- $this->_options = $options;
- $this->setDebug($debug, $handler);
-
- /* Try to include the Auth_SASL package. If the package is not
- * available, we disable the authentication methods that depend upon
- * it. */
- if ((@include_once 'Auth/SASL.php') === false) {
- $this->_debug('Auth_SASL not present');
- foreach ($this->supportedSASLAuthMethods as $SASLMethod) {
- $pos = array_search($SASLMethod, $this->supportedAuthMethods);
- $this->_debug('Disabling method ' . $SASLMethod);
- unset($this->supportedAuthMethods[$pos]);
- }
- }
-
- if (strlen($user) && strlen($pass)) {
- $this->_error = $this->_handleConnectAndLogin();
- }
- }
-
- /**
- * Returns any error that may have been generated in the constructor.
- *
- * @return boolean|PEAR_Error False if no error, PEAR_Error otherwise.
- */
- function getError()
- {
- return PEAR::isError($this->_error) ? $this->_error : false;
- }
-
- /**
- * Sets the debug state and handler function.
- *
- * @param boolean $debug Whether to enable debugging.
- * @param string $handler A custom debug handler. Must be a valid callback.
- *
- * @return void
- */
- function setDebug($debug = true, $handler = null)
- {
- $this->_debug = $debug;
- $this->_debug_handler = $handler;
- }
-
- /**
- * Connects to the server and logs in.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function _handleConnectAndLogin()
- {
- if (PEAR::isError($res = $this->connect($this->_data['host'], $this->_data['port'], $this->_options, $this->_useTLS))) {
- return $res;
- }
- if ($this->_bypassAuth === false) {
- if (PEAR::isError($res = $this->login($this->_data['user'], $this->_data['pass'], $this->_data['logintype'], $this->_data['euser'], $this->_bypassAuth))) {
- return $res;
- }
- }
- return true;
- }
-
- /**
- * Handles connecting to the server and checks the response validity.
- *
- * @param string $host Hostname of server.
- * @param string $port Port of server.
- * @param array $options List of options to pass to
- * stream_context_create().
- * @param boolean $useTLS Use TLS if available.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function connect($host, $port, $options = null, $useTLS = true)
- {
- $this->_data['host'] = $host;
- $this->_data['port'] = $port;
- $this->_useTLS = $useTLS;
- if (!empty($options) && is_array($options)) {
- $this->_options = array_merge($this->_options, $options);
- }
-
- if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) {
- return PEAR::raiseError('Not currently in DISCONNECTED state', 1);
- }
-
- if (PEAR::isError($res = $this->_sock->connect($host, $port, false, 5, $options))) {
- return $res;
- }
-
- if ($this->_bypassAuth) {
- $this->_state = NET_SIEVE_STATE_TRANSACTION;
- } else {
- $this->_state = NET_SIEVE_STATE_AUTHORISATION;
- if (PEAR::isError($res = $this->_doCmd())) {
- return $res;
- }
- }
-
- // Explicitly ask for the capabilities in case the connection is
- // picked up from an existing connection.
- if (PEAR::isError($res = $this->_cmdCapability())) {
- return PEAR::raiseError(
- 'Failed to connect, server said: ' . $res->getMessage(), 2
- );
- }
-
- // Check if we can enable TLS via STARTTLS.
- if ($useTLS && !empty($this->_capability['starttls'])
- && function_exists('stream_socket_enable_crypto')
- ) {
- if (PEAR::isError($res = $this->_startTLS())) {
- return $res;
- }
- }
-
- return true;
- }
-
- /**
- * Disconnect from the Sieve server.
- *
- * @param boolean $sendLogoutCMD Whether to send LOGOUT command before
- * disconnecting.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function disconnect($sendLogoutCMD = true)
- {
- return $this->_cmdLogout($sendLogoutCMD);
- }
-
- /**
- * Logs into server.
- *
- * @param string $user Login username.
- * @param string $pass Login password.
- * @param string $logintype Type of login method to use.
- * @param string $euser Effective UID (perform on behalf of $euser).
- * @param boolean $bypassAuth Do not perform authentication.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function login($user, $pass, $logintype = null, $euser = '', $bypassAuth = false)
- {
- $this->_data['user'] = $user;
- $this->_data['pass'] = $pass;
- $this->_data['logintype'] = $logintype;
- $this->_data['euser'] = $euser;
- $this->_bypassAuth = $bypassAuth;
-
- if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- if (!$bypassAuth ) {
- if (PEAR::isError($res = $this->_cmdAuthenticate($user, $pass, $logintype, $euser))) {
- return $res;
- }
- }
- $this->_state = NET_SIEVE_STATE_TRANSACTION;
-
- return true;
- }
-
- /**
- * Returns an indexed array of scripts currently on the server.
- *
- * @return array Indexed array of scriptnames.
- */
- function listScripts()
- {
- if (is_array($scripts = $this->_cmdListScripts())) {
- $this->_active = $scripts[1];
- return $scripts[0];
- } else {
- return $scripts;
- }
- }
-
- /**
- * Returns the active script.
- *
- * @return string The active scriptname.
- */
- function getActive()
- {
- if (!empty($this->_active)) {
- return $this->_active;
- }
- if (is_array($scripts = $this->_cmdListScripts())) {
- $this->_active = $scripts[1];
- return $scripts[1];
- }
- }
-
- /**
- * Sets the active script.
- *
- * @param string $scriptname The name of the script to be set as active.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function setActive($scriptname)
- {
- return $this->_cmdSetActive($scriptname);
- }
-
- /**
- * Retrieves a script.
- *
- * @param string $scriptname The name of the script to be retrieved.
- *
- * @return string The script on success, PEAR_Error on failure.
- */
- function getScript($scriptname)
- {
- return $this->_cmdGetScript($scriptname);
- }
-
- /**
- * Adds a script to the server.
- *
- * @param string $scriptname Name of the script.
- * @param string $script The script content.
- * @param boolean $makeactive Whether to make this the active script.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function installScript($scriptname, $script, $makeactive = false)
- {
- if (PEAR::isError($res = $this->_cmdPutScript($scriptname, $script))) {
- return $res;
- }
- if ($makeactive) {
- return $this->_cmdSetActive($scriptname);
- }
- return true;
- }
-
- /**
- * Removes a script from the server.
- *
- * @param string $scriptname Name of the script.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function removeScript($scriptname)
- {
- return $this->_cmdDeleteScript($scriptname);
- }
-
- /**
- * Checks if the server has space to store the script by the server.
- *
- * @param string $scriptname The name of the script to mark as active.
- * @param integer $size The size of the script.
- *
- * @return boolean|PEAR_Error True if there is space, PEAR_Error otherwise.
- *
- * @todo Rename to hasSpace()
- */
- function haveSpace($scriptname, $size)
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in TRANSACTION state', 1);
- }
-
- $command = sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size);
- if (PEAR::isError($res = $this->_doCmd($command))) {
- return $res;
- }
- return true;
- }
-
- /**
- * Returns the list of extensions the server supports.
- *
- * @return array List of extensions or PEAR_Error on failure.
- */
- function getExtensions()
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 7);
- }
- return $this->_capability['extensions'];
- }
-
- /**
- * Returns whether the server supports an extension.
- *
- * @param string $extension The extension to check.
- *
- * @return boolean Whether the extension is supported or PEAR_Error on
- * failure.
- */
- function hasExtension($extension)
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 7);
- }
-
- $extension = trim($this->_toUpper($extension));
- if (is_array($this->_capability['extensions'])) {
- foreach ($this->_capability['extensions'] as $ext) {
- if ($ext == $extension) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Returns the list of authentication methods the server supports.
- *
- * @return array List of authentication methods or PEAR_Error on failure.
- */
- function getAuthMechs()
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 7);
- }
- return $this->_capability['sasl'];
- }
-
- /**
- * Returns whether the server supports an authentication method.
- *
- * @param string $method The method to check.
- *
- * @return boolean Whether the method is supported or PEAR_Error on
- * failure.
- */
- function hasAuthMech($method)
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 7);
- }
-
- $method = trim($this->_toUpper($method));
- if (is_array($this->_capability['sasl'])) {
- foreach ($this->_capability['sasl'] as $sasl) {
- if ($sasl == $method) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * Handles the authentication using any known method.
- *
- * @param string $uid The userid to authenticate as.
- * @param string $pwd The password to authenticate with.
- * @param string $userMethod The method to use. If empty, the class chooses
- * the best (strongest) available method.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- */
- function _cmdAuthenticate($uid, $pwd, $userMethod = null, $euser = '')
- {
- if (PEAR::isError($method = $this->_getBestAuthMethod($userMethod))) {
- return $method;
- }
- switch ($method) {
- case 'DIGEST-MD5':
- return $this->_authDigestMD5($uid, $pwd, $euser);
- case 'CRAM-MD5':
- $result = $this->_authCRAMMD5($uid, $pwd, $euser);
- break;
- case 'LOGIN':
- $result = $this->_authLOGIN($uid, $pwd, $euser);
- break;
- case 'PLAIN':
- $result = $this->_authPLAIN($uid, $pwd, $euser);
- break;
- case 'EXTERNAL':
- $result = $this->_authEXTERNAL($uid, $pwd, $euser);
- break;
- default :
- $result = PEAR::raiseError(
- $method . ' is not a supported authentication method'
- );
- break;
- }
-
- if (PEAR::isError($res = $this->_doCmd())) {
- return $res;
- }
-
- return $result;
- }
-
- /**
- * Authenticates the user using the PLAIN method.
- *
- * @param string $user The userid to authenticate as.
- * @param string $pass The password to authenticate with.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- */
- function _authPLAIN($user, $pass, $euser)
- {
- return $this->_sendCmd(
- sprintf(
- 'AUTHENTICATE "PLAIN" "%s"',
- base64_encode($euser . chr(0) . $user . chr(0) . $pass)
- )
- );
- }
-
- /**
- * Authenticates the user using the LOGIN method.
- *
- * @param string $user The userid to authenticate as.
- * @param string $pass The password to authenticate with.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- */
- function _authLOGIN($user, $pass, $euser)
- {
- if (PEAR::isError($result = $this->_sendCmd('AUTHENTICATE "LOGIN"'))) {
- return $result;
- }
- if (PEAR::isError($result = $this->_doCmd('"' . base64_encode($user) . '"', true))) {
- return $result;
- }
- return $this->_doCmd('"' . base64_encode($pass) . '"', true);
- }
-
- /**
- * Authenticates the user using the CRAM-MD5 method.
- *
- * @param string $user The userid to authenticate as.
- * @param string $pass The password to authenticate with.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- */
- function _authCRAMMD5($user, $pass, $euser)
- {
- if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "CRAM-MD5"', true))) {
- return $challenge;
- }
-
- $challenge = base64_decode(trim($challenge));
- $cram = Auth_SASL::factory('crammd5');
- if (PEAR::isError($response = $cram->getResponse($user, $pass, $challenge))) {
- return $response;
- }
-
- return $this->_sendStringResponse(base64_encode($response));
- }
-
- /**
- * Authenticates the user using the DIGEST-MD5 method.
- *
- * @param string $user The userid to authenticate as.
- * @param string $pass The password to authenticate with.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- */
- function _authDigestMD5($user, $pass, $euser)
- {
- if (PEAR::isError($challenge = $this->_doCmd('AUTHENTICATE "DIGEST-MD5"', true))) {
- return $challenge;
- }
-
- $challenge = base64_decode(trim($challenge));
- $digest = Auth_SASL::factory('digestmd5');
- // @todo Really 'localhost'?
- if (PEAR::isError($response = $digest->getResponse($user, $pass, $challenge, 'localhost', 'sieve', $euser))) {
- return $response;
- }
-
- if (PEAR::isError($result = $this->_sendStringResponse(base64_encode($response)))) {
- return $result;
- }
- if (PEAR::isError($result = $this->_doCmd('', true))) {
- return $result;
- }
- if ($this->_toUpper(substr($result, 0, 2)) == 'OK') {
- return;
- }
-
- /* We don't use the protocol's third step because SIEVE doesn't allow
- * subsequent authentication, so we just silently ignore it. */
- if (PEAR::isError($result = $this->_sendStringResponse(''))) {
- return $result;
- }
-
- return $this->_doCmd();
- }
-
- /**
- * Authenticates the user using the EXTERNAL method.
- *
- * @param string $user The userid to authenticate as.
- * @param string $pass The password to authenticate with.
- * @param string $euser The effective uid to authenticate as.
- *
- * @return void
- *
- * @since 1.1.7
- */
- function _authEXTERNAL($user, $pass, $euser)
- {
- $cmd = sprintf(
- 'AUTHENTICATE "EXTERNAL" "%s"',
- base64_encode(strlen($euser) ? $euser : $user)
- );
- return $this->_sendCmd($cmd);
- }
-
- /**
- * Removes a script from the server.
- *
- * @param string $scriptname Name of the script to delete.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function _cmdDeleteScript($scriptname)
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- $command = sprintf('DELETESCRIPT %s', $this->_escape($scriptname));
- if (PEAR::isError($res = $this->_doCmd($command))) {
- return $res;
- }
- return true;
- }
-
- /**
- * Retrieves the contents of the named script.
- *
- * @param string $scriptname Name of the script to retrieve.
- *
- * @return string The script if successful, PEAR_Error otherwise.
- */
- function _cmdGetScript($scriptname)
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- $command = sprintf('GETSCRIPT %s', $this->_escape($scriptname));
- if (PEAR::isError($res = $this->_doCmd($command))) {
- return $res;
- }
-
- return preg_replace('/^{[0-9]+}\r\n/', '', $res);
- }
-
- /**
- * Sets the active script, i.e. the one that gets run on new mail by the
- * server.
- *
- * @param string $scriptname The name of the script to mark as active.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function _cmdSetActive($scriptname)
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- $command = sprintf('SETACTIVE %s', $this->_escape($scriptname));
- if (PEAR::isError($res = $this->_doCmd($command))) {
- return $res;
- }
-
- $this->_activeScript = $scriptname;
- return true;
- }
-
- /**
- * Returns the list of scripts on the server.
- *
- * @return array An array with the list of scripts in the first element
- * and the active script in the second element on success,
- * PEAR_Error otherwise.
- */
- function _cmdListScripts()
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- if (PEAR::isError($res = $this->_doCmd('LISTSCRIPTS'))) {
- return $res;
- }
-
- $scripts = array();
- $activescript = null;
- $res = explode("\r\n", $res);
- foreach ($res as $value) {
- if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) {
- $script_name = stripslashes($matches[1]);
- $scripts[] = $script_name;
- if (!empty($matches[2])) {
- $activescript = $script_name;
- }
- }
- }
-
- return array($scripts, $activescript);
- }
-
- /**
- * Adds a script to the server.
- *
- * @param string $scriptname Name of the new script.
- * @param string $scriptdata The new script.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function _cmdPutScript($scriptname, $scriptdata)
- {
- if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
- return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
- }
-
- $stringLength = $this->_getLineLength($scriptdata);
- $command = sprintf("PUTSCRIPT %s {%d+}\r\n%s",
- $this->_escape($scriptname), $stringLength, $scriptdata);
-
- if (PEAR::isError($res = $this->_doCmd($command))) {
- return $res;
- }
-
- return true;
- }
-
- /**
- * Logs out of the server and terminates the connection.
- *
- * @param boolean $sendLogoutCMD Whether to send LOGOUT command before
- * disconnecting.
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function _cmdLogout($sendLogoutCMD = true)
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 1);
- }
-
- if ($sendLogoutCMD) {
- if (PEAR::isError($res = $this->_doCmd('LOGOUT'))) {
- return $res;
- }
- }
-
- $this->_sock->disconnect();
- $this->_state = NET_SIEVE_STATE_DISCONNECTED;
-
- return true;
- }
-
- /**
- * Sends the CAPABILITY command
- *
- * @return boolean True on success, PEAR_Error otherwise.
- */
- function _cmdCapability()
- {
- if (NET_SIEVE_STATE_DISCONNECTED == $this->_state) {
- return PEAR::raiseError('Not currently connected', 1);
- }
- if (PEAR::isError($res = $this->_doCmd('CAPABILITY'))) {
- return $res;
- }
- $this->_parseCapability($res);
- return true;
- }
-
- /**
- * Parses the response from the CAPABILITY command and stores the result
- * in $_capability.
- *
- * @param string $data The response from the capability command.
- *
- * @return void
- */
- function _parseCapability($data)
- {
- // Clear the cached capabilities.
- $this->_capability = array('sasl' => array(),
- 'extensions' => array());
-
- $data = preg_split('/\r?\n/', $this->_toUpper($data), -1, PREG_SPLIT_NO_EMPTY);
-
- for ($i = 0; $i < count($data); $i++) {
- if (!preg_match('/^"([A-Z]+)"( "(.*)")?$/', $data[$i], $matches)) {
- continue;
- }
- switch ($matches[1]) {
- case 'IMPLEMENTATION':
- $this->_capability['implementation'] = $matches[3];
- break;
-
- case 'SASL':
- $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
- break;
-
- case 'SIEVE':
- $this->_capability['extensions'] = preg_split('/\s+/', $matches[3]);
- break;
-
- case 'STARTTLS':
- $this->_capability['starttls'] = true;
- break;
- }
- }
- }
-
- /**
- * Sends a command to the server
- *
- * @param string $cmd The command to send.
- *
- * @return void
- */
- function _sendCmd($cmd)
- {
- $status = $this->_sock->getStatus();
- if (PEAR::isError($status) || $status['eof']) {
- return PEAR::raiseError('Failed to write to socket: connection lost');
- }
- if (PEAR::isError($error = $this->_sock->write($cmd . "\r\n"))) {
- return PEAR::raiseError(
- 'Failed to write to socket: ' . $error->getMessage()
- );
- }
- $this->_debug("C: $cmd");
- }
-
- /**
- * Sends a string response to the server.
- *
- * @param string $str The string to send.
- *
- * @return void
- */
- function _sendStringResponse($str)
- {
- return $this->_sendCmd('{' . $this->_getLineLength($str) . "+}\r\n" . $str);
- }
-
- /**
- * Receives a single line from the server.
- *
- * @return string The server response line.
- */
- function _recvLn()
- {
- if (PEAR::isError($lastline = $this->_sock->gets(8192))) {
- return PEAR::raiseError(
- 'Failed to read from socket: ' . $lastline->getMessage()
- );
- }
-
- $lastline = rtrim($lastline);
- $this->_debug("S: $lastline");
-
- if ($lastline === '') {
- return PEAR::raiseError('Failed to read from socket');
- }
-
- return $lastline;
- }
-
- /**
- * Receives x bytes from the server.
- *
- * @param int $length Number of bytes to read
- *
- * @return string The server response.
- */
- function _recvBytes($length)
- {
- $response = '';
- $response_length = 0;
-
- while ($response_length < $length) {
- $response .= $this->_sock->read($length - $response_length);
- $response_length = $this->_getLineLength($response);
- }
-
- $this->_debug("S: " . rtrim($response));
-
- return $response;
- }
-
- /**
- * Send a command and retrieves a response from the server.
- *
- * @param string $cmd The command to send.
- * @param boolean $auth Whether this is an authentication command.
- *
- * @return string|PEAR_Error Reponse string if an OK response, PEAR_Error
- * if a NO response.
- */
- function _doCmd($cmd = '', $auth = false)
- {
- $referralCount = 0;
- while ($referralCount < $this->_maxReferralCount) {
- if (strlen($cmd)) {
- if (PEAR::isError($error = $this->_sendCmd($cmd))) {
- return $error;
- }
- }
-
- $response = '';
- while (true) {
- if (PEAR::isError($line = $this->_recvLn())) {
- return $line;
- }
- $uc_line = $this->_toUpper($line);
-
- if ('OK' == substr($uc_line, 0, 2)) {
- $response .= $line;
- return rtrim($response);
- }
-
- if ('NO' == substr($uc_line, 0, 2)) {
- // Check for string literal error message.
- if (preg_match('/{([0-9]+)}$/i', $line, $matches)) {
- $line = substr($line, 0, -(strlen($matches[1])+2))
- . str_replace(
- "\r\n", ' ', $this->_recvBytes($matches[1] + 2)
- );
- }
- return PEAR::raiseError(trim($response . substr($line, 2)), 3);
- }
-
- if ('BYE' == substr($uc_line, 0, 3)) {
- if (PEAR::isError($error = $this->disconnect(false))) {
- return PEAR::raiseError(
- 'Cannot handle BYE, the error was: '
- . $error->getMessage(),
- 4
- );
- }
- // Check for referral, then follow it. Otherwise, carp an
- // error.
- if (preg_match('/^bye \(referral "(sieve:\/\/)?([^"]+)/i', $line, $matches)) {
- // Replace the old host with the referral host
- // preserving any protocol prefix.
- $this->_data['host'] = preg_replace(
- '/\w+(?!(\w|\:\/\/)).*/', $matches[2],
- $this->_data['host']
- );
- if (PEAR::isError($error = $this->_handleConnectAndLogin())) {
- return PEAR::raiseError(
- 'Cannot follow referral to '
- . $this->_data['host'] . ', the error was: '
- . $error->getMessage(),
- 5
- );
- }
- break;
- }
- return PEAR::raiseError(trim($response . $line), 6);
- }
-
- // "\+?" is added in the regexp to workaround DBMail bug
- // http://dbmail.org/mantis/view.php?id=963
- if (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) {
- // Matches literal string responses.
- $line = $this->_recvBytes($matches[1] + 2);
-
- if (!$auth) {
- // Receive the pending OK only if we aren't
- // authenticating since string responses during
- // authentication don't need an OK.
- $this->_recvLn();
- }
- return $line;
- }
-
- if ($auth) {
- // String responses during authentication don't need an
- // OK.
- $response .= $line;
- return rtrim($response);
- }
-
- $response .= $line . "\r\n";
- $referralCount++;
- }
- }
-
- return PEAR::raiseError('Max referral count (' . $referralCount . ') reached. Cyrus murder loop error?', 7);
- }
-
- /**
- * Returns the name of the best authentication method that the server
- * has advertised.
- *
- * @param string $userMethod Only consider this method as available.
- *
- * @return string The name of the best supported authentication method or
- * a PEAR_Error object on failure.
- */
- function _getBestAuthMethod($userMethod = null)
- {
- if (!isset($this->_capability['sasl'])) {
- return PEAR::raiseError('This server doesn\'t support any authentication methods. SASL problem?');
- }
- if (!$this->_capability['sasl']) {
- return PEAR::raiseError('This server doesn\'t support any authentication methods.');
- }
-
- if ($userMethod) {
- if (in_array($userMethod, $this->_capability['sasl'])) {
- return $userMethod;
- }
- return PEAR::raiseError(
- sprintf('No supported authentication method found. The server supports these methods: %s, but we want to use: %s',
- implode(', ', $this->_capability['sasl']),
- $userMethod));
- }
-
- foreach ($this->supportedAuthMethods as $method) {
- if (in_array($method, $this->_capability['sasl'])) {
- return $method;
- }
- }
-
- return PEAR::raiseError(
- sprintf('No supported authentication method found. The server supports these methods: %s, but we only support: %s',
- implode(', ', $this->_capability['sasl']),
- implode(', ', $this->supportedAuthMethods)));
- }
-
- /**
- * Starts a TLS connection.
- *
- * @return boolean True on success, PEAR_Error on failure.
- */
- function _startTLS()
- {
- if (PEAR::isError($res = $this->_doCmd('STARTTLS'))) {
- return $res;
- }
-
- if (!stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- return PEAR::raiseError('Failed to establish TLS connection', 2);
- }
-
- $this->_debug('STARTTLS negotiation successful');
-
- // The server should be sending a CAPABILITY response after
- // negotiating TLS. Read it, and ignore if it doesn't.
- // Doesn't work with older timsieved versions
- $regexp = '/^CYRUS TIMSIEVED V([0-9.]+)/';
- if (!preg_match($regexp, $this->_capability['implementation'], $matches)
- || version_compare($matches[1], '2.3.10', '>=')
- ) {
- $this->_doCmd();
- }
-
- // RFC says we need to query the server capabilities again now that we
- // are under encryption.
- if (PEAR::isError($res = $this->_cmdCapability())) {
- return PEAR::raiseError(
- 'Failed to connect, server said: ' . $res->getMessage(), 2
- );
- }
-
- return true;
- }
-
- /**
- * Returns the length of a string.
- *
- * @param string $string A string.
- *
- * @return integer The length of the string.
- */
- function _getLineLength($string)
- {
- if (extension_loaded('mbstring')) {
- return mb_strlen($string, 'latin1');
- } else {
- return strlen($string);
- }
- }
-
- /**
- * Locale independant strtoupper() implementation.
- *
- * @param string $string The string to convert to lowercase.
- *
- * @return string The lowercased string, based on ASCII encoding.
- */
- function _toUpper($string)
- {
- $language = setlocale(LC_CTYPE, 0);
- setlocale(LC_CTYPE, 'C');
- $string = strtoupper($string);
- setlocale(LC_CTYPE, $language);
- return $string;
- }
-
- /**
- * Convert string into RFC's quoted-string or literal-c2s form
- *
- * @param string $string The string to convert.
- *
- * @return string Result string
- */
- function _escape($string)
- {
- // Some implementations doesn't allow UTF-8 characters in quoted-string
- // It's safe to use literal-c2s
- if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) {
- return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string);
- }
-
- return '"' . addcslashes($string, '\\"') . '"';
- }
-
- /**
- * Write debug text to the current debug output handler.
- *
- * @param string $message Debug message text.
- *
- * @return void
- */
- function _debug($message)
- {
- if ($this->_debug) {
- if ($this->_debug_handler) {
- call_user_func_array($this->_debug_handler, array(&$this, $message));
- } else {
- echo "$message\n";
- }
- }
- }
-}