⚝
One Hat Cyber Team
⚝
Your IP:
216.73.217.4
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-horde
/
imp
/
lib
/
Crypt
/
Edit File: Pgp.php
<?php /** * Copyright 2002-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (GPL). If you * did not receive this file, see http://www.horde.org/licenses/gpl. * * @category Horde * @copyright 2002-2017 Horde LLC * @license http://www.horde.org/licenses/gpl GPL * @package IMP */ /** * The IMP_Crypt_Pgp:: class contains all functions related to handling * PGP messages within IMP. * * @author Michael Slusarz <slusarz@horde.org> * @category Horde * @copyright 2002-2017 Horde LLC * @license http://www.horde.org/licenses/gpl GPL * @package IMP */ class IMP_Crypt_Pgp extends Horde_Crypt_Pgp { /* Name of PGP public key field in addressbook. */ const PUBKEY_FIELD = 'pgpPublicKey'; /* Encryption type constants. */ const ENCRYPT = 'pgp_encrypt'; const SIGN = 'pgp_sign'; const SIGNENC = 'pgp_signenc'; const SYM_ENCRYPT = 'pgp_sym_enc'; const SYM_SIGNENC = 'pgp_syn_sign'; /** * Return the list of available encryption options for composing. * * @return array Keys are encryption type constants, values are gettext * strings describing the encryption type. */ public function encryptList() { $ret = array( self::ENCRYPT => _("PGP Encrypt Message") ); if ($this->getPersonalPrivateKey()) { $ret += array( self::SIGN => _("PGP Sign Message"), self::SIGNENC => _("PGP Sign/Encrypt Message") ); } return $ret + array( self::SYM_ENCRYPT => _("PGP Encrypt Message with passphrase"), self::SYM_SIGNENC => _("PGP Sign/Encrypt Message with passphrase") ); } /** * Generate the personal Public/Private keypair and store in prefs. * * @param string $name See Horde_Crypt_Pgp::. * @param string $email See Horde_Crypt_Pgp::. * @param string $passphrase See Horde_Crypt_Pgp::. * @param string $comment See Horde_Crypt_Pgp::. * @param string $keylength See Horde_Crypt_Pgp::. * @param integer $expire See Horde_Crypt_Pgp::. * * @throws Horde_Crypt_Exception */ public function generatePersonalKeys($name, $email, $passphrase, $comment = '', $keylength = 1024, $expire = null) { $keys = $this->generateKey($name, $email, $passphrase, $comment, $keylength, $expire); /* Store the keys in the user's preferences. */ $this->addPersonalPublicKey($keys['public']); $this->addPersonalPrivateKey($keys['private']); } /** * Add the personal public key to the prefs. * * @param mixed $public_key The public key to add (either string or * array). */ public function addPersonalPublicKey($public_key) { $GLOBALS['prefs']->setValue('pgp_public_key', trim(is_array($public_key) ? implode('', $public_key) : $public_key)); } /** * Add the personal private key to the prefs. * * @param mixed $private_key The private key to add (either string or * array). */ public function addPersonalPrivateKey($private_key) { $GLOBALS['prefs']->setValue('pgp_private_key', trim(is_array($private_key) ? implode('', $private_key) : $private_key)); } /** * Get the personal public key from the prefs. * * @return string The personal PGP public key. */ public function getPersonalPublicKey() { return $GLOBALS['prefs']->getValue('pgp_public_key'); } /** * Get the personal private key from the prefs. * * @return string The personal PGP private key. */ public function getPersonalPrivateKey() { return $GLOBALS['prefs']->getValue('pgp_private_key'); } /** * Deletes the specified personal keys from the prefs. */ public function deletePersonalKeys() { $GLOBALS['prefs']->setValue('pgp_public_key', ''); $GLOBALS['prefs']->setValue('pgp_private_key', ''); $this->unsetPassphrase('personal'); } /** * Add a public key to an address book. * * @param string $public_key An PGP public key. * * @return array See Horde_Crypt_Pgp::pgpPacketInformation() * @throws Horde_Crypt_Exception * @throws Horde_Exception */ public function addPublicKey($public_key) { /* Make sure the key is valid. */ $key_info = $this->pgpPacketInformation($public_key); if (!isset($key_info['signature'])) { throw new Horde_Crypt_Exception(_("Not a valid public key.")); } /* Remove the '_SIGNATURE' entry. */ unset($key_info['signature']['_SIGNATURE']); /* Store all signatures that appear in the key. */ foreach ($key_info['signature'] as $id => $sig) { /* Check to make sure the key does not already exist in ANY * address book and remove the id from the key_info for a correct * output. */ try { $result = $this->getPublicKey($sig['email'], array('nocache' => true, 'noserver' => true, 'nohooks' => true)); if (!empty($result)) { unset($key_info['signature'][$id]); continue; } } catch (Horde_Crypt_Exception $e) {} /* Add key to the user's address book. */ $GLOBALS['registry']->call('contacts/addField', array($sig['email'], $sig['name'], self::PUBKEY_FIELD, $public_key, $GLOBALS['prefs']->getValue('add_source'))); } return $key_info; } /** * Retrieves a public key by e-mail. * * First, the key will be attempted to be retrieved from a user's address * book(s). * Second, if unsuccessful, the key is attempted to be retrieved via a * public PGP keyserver. * * @param string $address The e-mail address to search by. * @param array $options Additional options: * - keyid: (string) The key ID of the user's key. * DEFAULT: key ID not used * - nocache: (boolean) Don't retrieve from cache? * DEFAULT: false * - noserver: (boolean) Whether to check the public key servers for the * key. * DEFAULT: false * * @return string The PGP public key requested. * @throws Horde_Crypt_Exception */ public function getPublicKey($address, $options = array()) { global $injector, $registry; $keyid = empty($options['keyid']) ? '' : $options['keyid']; /* If there is a cache driver configured, try to get the public key * from the cache. */ if (empty($options['nocache']) && ($cache = $injector->getInstance('Horde_Cache'))) { $result = $cache->get("PGPpublicKey_" . $address . $keyid, 3600); if ($result) { Horde::log('PGPpublicKey: ' . serialize($result), 'DEBUG'); return $result; } } if (empty($options['nohooks'])) { try { $key = $injector->getInstance('Horde_Core_Hooks')->callHook( 'pgp_key', 'imp', array($address, $keyid) ); if ($key) { return $key; } } catch (Horde_Exception_HookNotSet $e) {} } /* Try retrieving by e-mail only first. */ $params = $injector->getInstance('IMP_Contacts')->getAddressbookSearchParams(); $result = null; try { $result = $registry->call('contacts/getField', array($address, self::PUBKEY_FIELD, $params['sources'], true, true)); } catch (Horde_Exception $e) {} if (is_null($result)) { /* TODO: Retrieve by ID. */ /* See if the address points to the user's public key. */ $identity = $injector->getInstance('IMP_Identity'); $personal_pubkey = $this->getPersonalPublicKey(); if (!empty($personal_pubkey) && $identity->hasAddress($address)) { $result = $personal_pubkey; } elseif (empty($options['noserver'])) { $result = null; try { foreach ($this->_keyserverList() as $val) { try { $result = $val->get( empty($keyid) ? $val->getKeyId($address) : $keyid ); break; } catch (Exception $e) {} } if (is_null($result)) { throw $e; } /* If there is a cache driver configured and a cache * object exists, store the retrieved public key in the * cache. */ if (is_object($cache)) { $cache->set("PGPpublicKey_" . $address . $keyid, $result, 3600); } } catch (Horde_Crypt_Exception $e) { /* Return now, if no public key found at all. */ Horde::log('PGPpublicKey: ' . $e->getMessage(), 'DEBUG'); throw new Horde_Crypt_Exception(sprintf(_("Could not retrieve public key for %s."), $address)); } } else { $result = ''; } } /* If more than one public key is returned, just return the first in * the array. There is no way of knowing which is the "preferred" key, * if the keys are different. */ if (is_array($result)) { $result = reset($result); } return $result; } /** * Retrieves all public keys from a user's address book(s). * * @return array All PGP public keys available. * @throws Horde_Crypt_Exception */ public function listPublicKeys() { $params = $GLOBALS['injector']->getInstance('IMP_Contacts')->getAddressbookSearchParams(); return empty($params['sources']) ? array() : $GLOBALS['registry']->call('contacts/getAllAttributeValues', array(self::PUBKEY_FIELD, $params['sources'])); } /** * Deletes a public key from a user's address book(s) by e-mail. * * @param string $email The e-mail address to delete. * * @throws Horde_Crypt_Exception */ public function deletePublicKey($email) { $params = $GLOBALS['injector']->getInstance('IMP_Contacts')->getAddressbookSearchParams(); return $GLOBALS['registry']->call('contacts/deleteField', array($email, self::PUBKEY_FIELD, $params['sources'])); } /** * Send a public key to a public PGP keyserver. * * @param string $pubkey The PGP public key. * * @throws Horde_Crypt_Exception */ public function sendToPublicKeyserver($pubkey) { $servers = $this->_keyserverList(); $servers[0]->put($pubkey); } /** * Verifies a signed message with a given public key. * * @param string $text The text to verify. * @param string $address E-mail address of public key. * @param string $signature A PGP signature block. * @param string $charset Charset to use. * * @return stdClass See Horde_Crypt_Pgp::decrypt(). * @throws Horde_Crypt_Exception */ public function verifySignature($text, $address, $signature = '', $charset = null) { if (!empty($signature)) { $packet_info = $this->pgpPacketInformation($signature); if (isset($packet_info['keyid'])) { $keyid = $packet_info['keyid']; } } if (!isset($keyid)) { $keyid = $this->getSignersKeyID($text); } /* Get key ID of key. */ $public_key = $this->getPublicKey($address, array('keyid' => $keyid)); if (empty($signature)) { $options = array('type' => 'signature'); } else { $options = array('type' => 'detached-signature', 'signature' => $signature); } $options['pubkey'] = $public_key; if (!empty($charset)) { $options['charset'] = $charset; } return $this->decrypt($text, $options); } /** * Decrypt a message with user's public/private keypair or a passphrase. * * @param string $text The text to decrypt. * @param string $type Either 'literal', 'personal', or 'symmetric'. * @param array $opts Additional options: * - passphrase: (boolean) If $type is 'personal' or 'symmetrical', the * passphrase to use. * - sender: (string) The sender of the message (used to check signature * if message is both encrypted & signed). * * @return stdClass See Horde_Crypt_Pgp::decrypt(). * @throws Horde_Crypt_Exception */ public function decryptMessage($text, $type, array $opts = array()) { $opts = array_merge(array( 'passphrase' => null ), $opts); $pubkey = $this->getPersonalPublicKey(); if (isset($opts['sender'])) { try { $pubkey .= "\n" . $this->getPublicKey($opts['sender']); } catch (Horde_Crypt_Exception $e) {} } switch ($type) { case 'literal': return $this->decrypt($text, array( 'no_passphrase' => true, 'pubkey' => $pubkey, 'type' => 'message' )); break; case 'symmetric': return $this->decrypt($text, array( 'passphrase' => $opts['passphrase'], 'pubkey' => $pubkey, 'type' => 'message' )); break; case 'personal': return $this->decrypt($text, array( 'passphrase' => $opts['passphrase'], 'privkey' => $this->getPersonalPrivateKey(), 'pubkey' => $pubkey, 'type' => 'message' )); } } /** * Gets a passphrase from the session cache. * * @param integer $type The type of passphrase. Either 'personal' or * 'symmetric'. * @param string $id If $type is 'symmetric', the ID of the stored * passphrase. * * @return mixed The passphrase, if set, or null. */ public function getPassphrase($type, $id = null) { if ($type == 'personal') { $id = 'personal'; } return (($cache = $GLOBALS['session']->get('imp', 'pgp')) && isset($cache[$type][$id])) ? $cache[$type][$id] : null; } /** * Store's the user's passphrase in the session cache. * * @param integer $type The type of passphrase. Either 'personal' or * 'symmetric'. * @param string $passphrase The user's passphrase. * @param string $id If $type is 'symmetric', the ID of the * stored passphrase. * * @return boolean Returns true if correct passphrase, false if incorrect. */ public function storePassphrase($type, $passphrase, $id = null) { global $session; if ($type == 'personal') { if ($this->verifyPassphrase($this->getPersonalPublicKey(), $this->getPersonalPrivateKey(), $passphrase) === false) { return false; } $id = 'personal'; } $cache = $session->get('imp', 'pgp', Horde_Session::TYPE_ARRAY); $cache[$type][$id] = $passphrase; $session->set('imp', 'pgp', $cache, $session::ENCRYPT); return true; } /** * Clear the passphrase from the session cache. * * @param integer $type The type of passphrase. Either 'personal' or * 'symmetric'. * @param string $id If $type is 'symmetric', the ID of the * stored passphrase. Else, all passphrases * are deleted. */ public function unsetPassphrase($type, $id = null) { if ($cache = $GLOBALS['session']->get('imp', 'pgp')) { if (($type == 'symmetric') && !is_null($id)) { unset($cache['symmetric'][$id]); } else { unset($cache[$type]); } $GLOBALS['session']->set('imp', 'pgp', $cache); } } /** * Generates a cache ID for symmetric message data. * * @param string $mailbox The mailbox of the message. * @param integer $uid The UID of the message. * @param string $id The MIME ID of the message. * * @return string A unique symmetric cache ID. */ public function getSymmetricId($mailbox, $uid, $id) { return implode('|', array($mailbox, $uid, $id)); } /** * Provide the list of parameters needed for signing a message. * * @return array The list of parameters needed by encrypt(). */ protected function _signParameters() { return array( 'pubkey' => $this->getPersonalPublicKey(), 'privkey' => $this->getPersonalPrivateKey(), 'passphrase' => $this->getPassphrase('personal') ); } /** * Provide the list of parameters needed for encrypting a message. * * @param Horde_Mail_Rfc822_List $addresses The e-mail address of the * keys to use for encryption. * @param string $symmetric If true, the symmetric * password to use for * encrypting. If null, uses the * personal key. * * @return array The list of parameters needed by encrypt(). * @throws Horde_Crypt_Exception */ protected function _encryptParameters(Horde_Mail_Rfc822_List $addresses, $symmetric) { if (!is_null($symmetric)) { return array( 'symmetric' => true, 'passphrase' => $symmetric ); } $addr_list = array(); foreach ($addresses as $val) { /* Get the public key for the address. */ $bare_addr = $val->bare_address; $addr_list[$bare_addr] = $this->getPublicKey($bare_addr); } return array('recips' => $addr_list); } /** * Sign a Horde_Mime_Part using PGP using IMP default parameters. * * @param Horde_Mime_Part $mime_part The object to sign. * * @return Horde_Mime_Part See Horde_Crypt_Pgp::signMIMEPart(). * @throws Horde_Crypt_Exception */ public function impSignMimePart($mime_part) { return $this->signMimePart($mime_part, $this->_signParameters()); } /** * Encrypt a Horde_Mime_Part using PGP using IMP default parameters. * * @param Horde_Mime_Part $mime_part The object to encrypt. * @param Horde_Mail_Rfc822_List $addresses The e-mail address of the * keys to use for encryption. * @param string $symmetric If true, the symmetric * password to use for * encrypting. If null, uses the * personal key. * * @return Horde_Mime_Part See Horde_Crypt_Pgp::encryptMimePart(). * @throws Horde_Crypt_Exception */ public function impEncryptMimePart($mime_part, Horde_Mail_Rfc822_List $addresses, $symmetric = null) { return $this->encryptMimePart($mime_part, $this->_encryptParameters($addresses, $symmetric)); } /** * Sign and Encrypt a Horde_Mime_Part using PGP using IMP default * parameters. * * @param Horde_Mime_Part $mime_part The object to sign and * encrypt. * @param Horde_Mail_Rfc822_List $addresses The e-mail address of the * keys to use for encryption. * @param string $symmetric If true, the symmetric * password to use for * encrypting. If null, uses the * personal key. * * @return Horde_Mime_Part See Horde_Crypt_Pgp::signAndencryptMimePart(). * @throws Horde_Crypt_Exception */ public function impSignAndEncryptMimePart($mime_part, Horde_Mail_Rfc822_List $addresses, $symmetric = null) { return $this->signAndEncryptMimePart($mime_part, $this->_signParameters(), $this->_encryptParameters($addresses, $symmetric)); } /** * Generate a Horde_Mime_Part object, in accordance with RFC 2015/3156, * that contains the user's public key. * * @return Horde_Mime_Part See Horde_Crypt_Pgp::publicKeyMimePart(). */ public function publicKeyMimePart($key = null) { return parent::publicKeyMimePart($this->getPersonalPublicKey()); } /** * Extracts public/private keys from armor data. * * @param string $data Armor text. * * @return array Array with these keys: * - public: (array) Array of public keys. * - private: (array) Array of private keys. */ public function getKeys($data) { global $injector; $out = array( 'public' => array(), 'private' => array() ); foreach ($injector->getInstance('Horde_Crypt_Pgp_Parse')->parse($data) as $val) { switch ($val['type']) { case Horde_Crypt_Pgp::ARMOR_PUBLIC_KEY: case Horde_Crypt_Pgp::ARMOR_PRIVATE_KEY: $key = implode("\n", $val['data']); if ($key_info = $this->pgpPacketInformation($key)) { if (($val['type'] == Horde_Crypt_Pgp::ARMOR_PUBLIC_KEY) && !empty($key_info['public_key'])) { $out['public'][] = $key; } elseif (($val['type'] == Horde_Crypt_Pgp::ARMOR_PRIVATE_KEY) && !empty($key_info['secret_key'])) { $out['private'][] = $key; } } break; } } if (!empty($out['private']) && empty($out['public']) && $res = $this->getPublicKeyFromPrivateKey(reset($out['private']))) { $out['public'][] = $res; } return $out; } /** * Return list of keyserver objects. * * @return array List of Horde_Crypt_Pgp_Keyserver objects. * @throws Horde_Crypt_Exception */ protected function _keyserverList() { global $conf, $injector; if (empty($conf['gnupg']['keyserver'])) { throw new Horde_Crypt_Exception(_("Public PGP keyserver support has been disabled.")); } $http = $injector->getInstance('Horde_Core_Factory_HttpClient')->create(); if (!empty($conf['gnupg']['timeout'])) { $http->{'request.timeout'} = $conf['gnupg']['timeout']; } $out = array(); foreach ($conf['gnupg']['keyserver'] as $server) { $out[] = new Horde_Crypt_Pgp_Keyserver($this, array( 'http' => $http, 'keyserver' => 'http://' . $server )); } return $out; } }
Simpan