⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.50
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
/
Mime
/
Viewer
/
View File Name :
Pgp.php
* @category Horde * @copyright 2002-2017 Horde LLC * @license http://www.horde.org/licenses/gpl GPL * @package IMP */ class IMP_Mime_Viewer_Pgp extends Horde_Mime_Viewer_Base { /* Metadata constants. */ const PGP_SIGN_ENC = 'imp-pgp-signed-encrypted'; /** * This driver's display capabilities. * * @var array */ protected $_capability = array( 'full' => false, 'info' => false, 'inline' => true, /* This driver *does* render raw data, but only for * application/pgp-signature parts that have been processed by the * text/plain driver and for displaying raw pgp keys. Altering this * value is handled via the canRender() function. */ 'raw' => false ); /** * Metadata for the current viewer/data. * * @var array */ protected $_metadata = array( 'compressed' => false, 'embedded' => true, 'forceinline' => true ); /** * The address of the sender. * * @var Horde_Mail_Rfc822_Address */ protected $_sender = null; /** * Return the full rendered version of the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _render() { switch ($this->_mimepart->getType()) { case 'application/pgp-keys': $vars = $GLOBALS['injector']->getInstance('Horde_Variables'); if ($vars->pgp_view_key) { // Throws exception on error. return array( $this->_mimepart->getMimeId() => array( 'data' => '
' . nl2br(str_replace(' ', ' ', $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp')->pgpPrettyKey($this->_mimepart->getContents()))) . '
', 'type' => 'text/html; charset=' . $this->getConfigParam('charset') ) ); } return array( $this->_mimepart->getMimeId() => array( 'data' => $this->_mimepart->getContents(), 'type' => 'text/plain; charset=' . $this->_mimepart->getCharset() ) ); } } /** * Return the full rendered version of the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _renderRaw() { $ret = array( 'data' => '', 'type' => 'text/plain; charset=' . $this->getConfigParam('charset') ); switch ($this->_mimepart->getType()) { case 'application/pgp-signature': $parts = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp_Parse')->parse($this->_mimepart->getContents()); foreach (array_keys($parts) as $key) { if ($parts[$key]['type'] == Horde_Crypt_Pgp::ARMOR_SIGNATURE) { $ret['data'] = implode("\r\n", $parts[$key]['data']); break; } } break; } return array( $this->_mimepart->getMimeId() => $ret ); } /** * Return the rendered inline version of the Horde_Mime_Part object. * * @return array See parent::render(). */ protected function _renderInline() { $id = $this->_mimepart->getMimeId(); switch ($this->_mimepart->getType()) { case 'application/pgp-keys': return $this->_outputPGPKey(); case 'multipart/signed': return $this->_outputPGPSigned(); case 'multipart/encrypted': $cache = $this->getConfigParam('imp_contents')->getViewCache(); if (isset($cache->pgp[$id])) { return array_merge(array( $id => array( 'data' => null, 'status' => $cache->pgp[$id]['status'], 'type' => 'text/plain; charset=' . $this->getConfigParam('charset'), 'wrap' => $cache->pgp[$id]['wrap'] ) ), $cache->pgp[$id]['other']); } // Fall-through case 'application/pgp-encrypted': case 'application/pgp-signature': default: return array(); } } /** * If this MIME part can contain embedded MIME part(s), and those part(s) * exist, return a representation of that data. * * @return mixed A Horde_Mime_Part object representing the embedded data. * Returns null if no embedded MIME part(s) exist. */ protected function _getEmbeddedMimeParts() { if ($this->_mimepart->getType() != 'multipart/encrypted') { return null; } $partlist = array_keys($this->_mimepart->contentTypeMap()); $base_id = reset($partlist); $version_id = next($partlist); $data_id = Horde_Mime::mimeIdArithmetic($version_id, 'next'); $status = new IMP_Mime_Status(); $status->icon('mime/encryption.png', 'PGP'); $cache = $this->getConfigParam('imp_contents')->getViewCache(); $cache->pgp[$base_id] = array( 'status' => array($status), 'other' => array( $version_id => null, $data_id => null ), 'wrap' => '' ); /* Is PGP active? */ if (empty($GLOBALS['conf']['gnupg']['path']) || !$GLOBALS['prefs']->getValue('use_pgp')) { $status->addText(_("The data in this part has been encrypted via PGP, however, PGP support is disabled so the message cannot be decrypted.")); return null; } /* PGP version information appears in the first MIME subpart. We * don't currently need to do anything with this information. The * encrypted data appears in the second MIME subpart. */ $encrypted_part = $this->getConfigParam('imp_contents')->getMIMEPart($data_id); $encrypted_data = $encrypted_part->getContents(); $symmetric_pass = $personal_pass = null; /* Check if this a symmetrically encrypted message. */ try { $imp_pgp = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp'); $symmetric = $imp_pgp->encryptedSymmetrically($encrypted_data); if ($symmetric) { $symmetric_id = $this->_getSymmetricID(); $symmetric_pass = $imp_pgp->getPassphrase('symmetric', $symmetric_id); if (is_null($symmetric_pass)) { $status->addText(_("The data in this part has been encrypted via PGP.")); /* Ask for the correct passphrase if this is encrypted * symmetrically. */ $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_PassphraseDialog', array( 'params' => array( 'symmetricid' => $symmetric_id ), 'type' => 'pgpSymmetric' )); $status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getDomId())) . _("You must enter the passphrase used to encrypt this message to view it.") . ''); return null; } } } catch (Horde_Exception $e) { Horde::log($e, 'INFO'); return null; } /* Check if this is a literal compressed message. */ try { $info = $imp_pgp->pgpPacketInformation($encrypted_data); } catch (Horde_Exception $e) { Horde::log($e, 'INFO'); return null; } $literal = !empty($info['literal']); if ($literal) { $status->addText(_("The data in this part has been compressed via PGP.")); } else { $status->addText(_("The data in this part has been encrypted via PGP.")); if (!$symmetric) { if ($imp_pgp->getPersonalPrivateKey()) { $personal_pass = $imp_pgp->getPassphrase('personal'); if (is_null($personal_pass)) { /* Ask for the private key's passphrase if this is * encrypted asymmetrically. */ $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_PassphraseDialog', array( 'type' => 'pgpPersonal' )); $status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getDomId())) . _("You must enter the passphrase for your PGP private key to view this message.") . ''); return null; } } else { /* Output if there is no personal private key to decrypt * with. */ $status->addText(_("However, no personal private key exists so the message cannot be decrypted.")); return null; } } } try { if (!is_null($symmetric_pass)) { $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'symmetric', array( 'passphrase' => $symmetric_pass, 'sender' => $this->_getSender()->bare_address )); } elseif (!is_null($personal_pass)) { $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'personal', array( 'passphrase' => $personal_pass, 'sender' => $this->_getSender()->bare_address )); } else { $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'literal'); } } catch (Horde_Exception $e) { $status->addText(_("The data in this part does not appear to be a valid PGP encrypted message. Error: ") . $e->getMessage()); if (!is_null($symmetric_pass)) { $imp_pgp->unsetPassphrase('symmetric', $this->_getSymmetricID()); return $this->_getEmbeddedMimeParts(); } return null; } $cache->pgp[$base_id]['wrap'] = 'mimePartWrapValid'; /* Check for combined encryption/signature data. */ if ($decrypted_data->result) { $sig_text = is_bool($decrypted_data->result) ? _("The data in this part has been digitally signed via PGP.") : $this->_textFilter($decrypted_data->result, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML)); $status2 = new IMP_Mime_Status($sig_text); $status2->action(IMP_Mime_Status::SUCCESS); $cache->pgp[$base_id]['status'][] = $status2; } /* Force armor data as text/plain data. */ if ($this->_mimepart->getMetadata(Horde_Crypt_Pgp_Parse::PGP_ARMOR)) { $decrypted_data->message = "Content-Type: text/plain\n\n" . $decrypted_data->message; } $new_part = Horde_Mime_Part::parseMessage($decrypted_data->message, array( 'forcemime' => true )); if ($new_part->getType() == 'multipart/signed') { $data = new Horde_Stream_Temp(); try { $data->add(Horde_Mime_Part::getRawPartText($decrypted_data->message, 'header', '1')); $data->add("\n\n"); $data->add(Horde_Mime_Part::getRawPartText($decrypted_data->message, 'body', '1')); } catch (Horde_Mime_Exception $e) {} $new_part->setMetadata(self::PGP_SIGN_ENC, $data->stream); $new_part->setContents($decrypted_data->message, array( 'encoding' => 'binary' )); } return $new_part; } /** * Generates output for 'application/pgp-keys' MIME_Parts. * * @return string The HTML output. */ protected function _outputPGPKey() { /* Is PGP active? */ if (empty($GLOBALS['conf']['gnupg']['path']) || !$GLOBALS['prefs']->getValue('use_pgp')) { return array(); } /* Initialize status message. */ $status = new IMP_Mime_Status(_("A PGP Public Key is attached to the message.")); $status->icon('mime/encryption.png', 'PGP'); $imp_contents = $this->getConfigParam('imp_contents'); $mime_id = $this->_mimepart->getMimeId(); if ($GLOBALS['prefs']->getValue('use_pgp') && $GLOBALS['prefs']->getValue('add_source') && $GLOBALS['registry']->hasMethod('contacts/addField')) { // TODO: Check for key existence. $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_ImportEncryptKey', array( 'mime_id' => $mime_id, 'muid' => strval($imp_contents->getIndicesOb()), 'type' => 'pgp' )); $status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getDomId())) . _("Save the key to your address book.") . ''); } $status->addText($imp_contents->linkViewJS($this->_mimepart, 'view_attach', _("View key details."), array('params' => array('mode' => IMP_Contents::RENDER_FULL, 'pgp_view_key' => 1)))); return array( $mime_id => array( 'data' => '', 'status' => $status, 'type' => 'text/html; charset=' . $this->getConfigParam('charset') ) ); } /** * Generates HTML output for 'multipart/signed' MIME parts. * * @return string The HTML output. */ protected function _outputPGPSigned() { global $conf, $injector, $prefs, $registry, $session; $partlist = array_keys($this->_mimepart->contentTypeMap()); $base_id = reset($partlist); $signed_id = next($partlist); $sig_id = Horde_Mime::mimeIdArithmetic($signed_id, 'next'); if (!$prefs->getValue('use_pgp') || empty($conf['gnupg']['path'])) { return array( $sig_id => null ); } $status = new IMP_Mime_Status(); $status->addText(_("The data in this part has been digitally signed via PGP.")); $status->icon('mime/encryption.png', 'PGP'); $ret = array( $base_id => array( 'data' => '', 'nosummary' => true, 'status' => array($status), 'type' => 'text/html; charset=' . $this->getConfigParam('charset'), 'wrap' => 'mimePartWrap' ), $sig_id => null ); if ($prefs->getValue('pgp_verify') || $injector->getInstance('Horde_Variables')->pgp_verify_msg) { $imp_contents = $this->getConfigParam('imp_contents'); $sig_part = $imp_contents->getMIMEPart($sig_id); $status2 = new IMP_Mime_Status(); if (!$sig_part) { $status2->action(IMP_Mime_Status::ERROR); $sig_text = _("This digitally signed message is broken."); $ret[$base_id]['wrap'] = 'mimePartWrapInvalid'; } else { /* Close session, since this may be a long-running * operation. */ $session->close(); try { $imp_pgp = $injector->getInstance('IMP_Crypt_Pgp'); if ($sig_raw = $sig_part->getMetadata(Horde_Crypt_Pgp_Parse::SIG_RAW)) { $sig_result = $imp_pgp->verifySignature($sig_raw, $this->_getSender()->bare_address, null, $sig_part->getMetadata(Horde_Crypt_Pgp_Parse::SIG_CHARSET)); } else { $stream = $imp_contents->isEmbedded($signed_id) ? $this->_mimepart->getMetadata(self::PGP_SIGN_ENC) : $imp_contents->getBodyPart($signed_id, array('mimeheaders' => true, 'stream' => true))->data; rewind($stream); stream_filter_register('horde_eol', 'Horde_Stream_Filter_Eol'); stream_filter_append($stream, 'horde_eol', STREAM_FILTER_READ, array( 'eol' => Horde_Mime_Part::RFC_EOL )); $sig_result = $imp_pgp->verifySignature(stream_get_contents($stream), $this->_getSender()->bare_address, $sig_part->getContents()); } $status2->action(IMP_Mime_Status::SUCCESS); $sig_text = $sig_result->message; $ret[$base_id]['wrap'] = 'mimePartWrapValid'; } catch (Horde_Exception $e) { $status2->action(IMP_Mime_Status::ERROR); $sig_text = $e->getMessage(); $ret[$base_id]['wrap'] = 'mimePartWrapInvalid'; } } $status2->addText($this->_textFilter($sig_text, 'text2html', array( 'parselevel' => Horde_Text_Filter_Text2html::NOHTML ))); $ret[$base_id]['status'][] = $status2; } else { switch ($registry->getView()) { case Horde_Registry::VIEW_BASIC: $status->addText(Horde::link(Horde::selfUrlParams()->add(array('pgp_verify_msg' => 1))) . _("Click HERE to verify the message.") . ''); break; case Horde_Registry::VIEW_DYNAMIC: $status->addText(Horde::link('#', '', 'pgpVerifyMsg') . _("Click HERE to verify the message.") . ''); break; } } return $ret; } /** * Generates the symmetric ID for this message. * * @return string Symmetric ID. */ protected function _getSymmetricID() { return $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp')->getSymmetricID($this->getConfigParam('imp_contents')->getMailbox(), $this->getConfigParam('imp_contents')->getUid(), $this->_mimepart->getMimeId()); } /** * Determine the address of the sender. * * @return Horde_Mail_Rfc822_Address The from address. */ protected function _getSender() { if (is_null($this->_sender)) { $headers = $this->getConfigParam('imp_contents')->getHeader(); $tmp = $headers->getOb('from'); $this->_sender = $tmp[0]; } return $this->_sender; } /** * Can this driver render the data? * * @param string $mode See parent::canRender(). * * @return boolean See parent::canRender(). */ public function canRender($mode) { switch ($mode) { case 'full': if ($this->_mimepart->getType() == 'application/pgp-keys') { return true; } break; case 'raw': if (($this->_mimepart->getType() == 'application/pgp-signature') && $this->_mimepart->getMetadata(Horde_Crypt_Pgp_Parse::SIG_RAW)) { return true; } break; } return parent::canRender($mode); } }