[ Index ] |
|
Code source de IMP H3 (4.1.5) |
1 <?php 2 3 require_once IMP_BASE . '/lib/Crypt/PGP.php'; 4 5 /** 6 * The IMP_MIME_Viewer_pgp class allows viewing/decrypting of PGP 7 * formatted messages. This class implements RFC 3156. 8 * 9 * This class handles the following MIME types: 10 * application/pgp-encryption 11 * application/pgp-keys 12 * application/pgp-signature 13 * 14 * This class may add the following parameters to the URL: 15 * 'rawpgpkey' -- Display the PGP Public Key in raw, text format 16 * 17 * $Horde: imp/lib/MIME/Viewer/pgp.php,v 1.96.6.15 2007/03/09 11:43:18 jan Exp $ 18 * 19 * Copyright 2002-2007 Michael Slusarz <slusarz@bigworm.colorado.edu> 20 * 21 * See the enclosed file COPYING for license information (GPL). If you 22 * did not receive this file, see http://www.fsf.org/copyleft/gpl.html. 23 * 24 * @author Michael Slusarz <slusarz@bigworm.colorado.edu> 25 * @since IMP 4.0 26 * @package Horde_MIME_Viewer 27 */ 28 class IMP_MIME_Viewer_pgp extends MIME_Viewer { 29 30 /** 31 * IMP_PGP object. 32 * 33 * @var IMP_PGP 34 */ 35 var $_imp_pgp; 36 37 /** 38 * The address of the sender. 39 * 40 * @var string 41 */ 42 var $_address; 43 44 /** 45 * Pointer to the MIME_Contents item. 46 * 47 * @var MIME_Contents 48 */ 49 var $_contents = null; 50 51 /** 52 * Classwide cache for icons for status messages. 53 * 54 * @var string 55 */ 56 var $_icon = null; 57 58 /** 59 * Classwide cache for status messages. 60 * 61 * @var array 62 */ 63 var $_status = array(); 64 65 /** 66 * The MIME content-type of this part. 67 * 68 * @var string 69 */ 70 var $_type = 'text/html'; 71 72 /** 73 * Render out the currently set contents. 74 * 75 * @param array $params An array with a reference to a MIME_Contents 76 * object. 77 * 78 * @return string The rendered text in HTML. 79 */ 80 function render($params) 81 { 82 global $conf, $prefs; 83 84 /* Set the MIME_Contents class variable. */ 85 $this->_contents = &$params[0]; 86 87 $msg = ''; 88 89 if (empty($this->_imp_pgp) && !empty($conf['utils']['gnupg'])) { 90 $this->_imp_pgp = &new IMP_PGP(); 91 } 92 93 /* Determine the address of the sender. */ 94 if (empty($this->_address)) { 95 $base_ob = &$this->_contents->getBaseObjectPtr(); 96 $this->_address = $base_ob->getFromAddress(); 97 } 98 99 /* We need to insert JavaScript code now if PGP support is active. */ 100 if (!empty($conf['utils']['gnupg']) && 101 $prefs->getValue('use_pgp') && 102 !Util::getFormData('rawpgpkey')) { 103 $msg = Util::bufferOutput(array('Horde', 'addScriptFile'), 'popup.js'); 104 } 105 106 /* For RFC 2015/3156, there are 3 types of messages: 107 + multipart/encrypted 108 + multipart/signed 109 + application/pgp-keys */ 110 switch ($this->mime_part->getType()) { 111 case 'application/pgp-keys': 112 $msg .= $this->_outputPGPKey(); 113 break; 114 115 case 'multipart/signed': 116 case 'application/pgp-signature': 117 $msg .= $this->_outputPGPSigned(); 118 break; 119 120 case 'multipart/encrypted': 121 case 'application/pgp-encrypted': 122 $msg .= $this->_outputPGPEncrypted(); 123 break; 124 } 125 126 return $msg; 127 } 128 129 /** 130 * Return the content-type of the output. 131 * 132 * @return string The MIME content type of the output. 133 */ 134 function getType() 135 { 136 return $this->_type; 137 } 138 139 /** 140 * Generates HTML output for 'application/pgp-keys' MIME_Parts.. 141 * 142 * @access private 143 * 144 * @return string The HTML output. 145 */ 146 function _outputPGPKey() 147 { 148 global $conf, $prefs; 149 150 $mime = &$this->mime_part; 151 $part = $this->_contents->getDecodedMIMEPart($mime->getMIMEId()); 152 153 if (empty($conf['utils']['gnupg'])) { 154 $text = '<pre>' . $part->getContents() . '</pre>'; 155 } elseif (Util::getFormData('rawpgpkey')) { 156 $text = $part->getContents(); 157 $this->_type = 'text/plain'; 158 } else { 159 require_once 'Horde/Text.php'; 160 161 $pgp_key = $mime->getContents(); 162 163 /* Initialize status message. */ 164 $this->_initStatus($this->getIcon($mime->getType()), _("PGP")); 165 $this->_status[] = _("This PGP Public Key was attached to the message."); 166 167 if ($prefs->getValue('use_pgp') && 168 $GLOBALS['registry']->hasMethod('contacts/addField') && 169 $prefs->getValue('add_source')) { 170 $this->_status[] = Horde::link('#', _("Click to Save PGP Public Key in your Address book"), null, null, $this->_imp_pgp->savePublicKeyURL($mime) . ' return false;') . _("Click to Save PGP Public Key in your Address book") . '</a>.'; 171 } 172 $this->_status[] = sprintf(_("The raw text of the PGP Public Key can be viewed %s."), $this->_contents->linkViewJS($part, 'view_attach', _("HERE"), _("PGP Public Key Text"), null, array('rawpgpkey' => 1))); 173 174 $text = $this->_outputStatus(false) . 175 '<span class="fixed">' . nl2br(str_replace(' ', ' ', $this->_imp_pgp->pgpPrettyKey($pgp_key))) . '</span>'; 176 } 177 178 return $text; 179 } 180 181 /** 182 * Generates HTML output for 'multipart/signed' and 183 * 'application/pgp-signature' MIME_Parts. 184 * 185 * @access private 186 * 187 * @return string The HTML output. 188 */ 189 function _outputPGPSigned() 190 { 191 global $conf, $prefs; 192 193 $active = ($prefs->getValue('use_pgp') && !empty($conf['utils']['gnupg'])); 194 $mime = &$this->mime_part; 195 $mimetype = $mime->getType(); 196 $text = ''; 197 198 $signenc = $mime->getInformation('pgp_signenc'); 199 if ($signenc) { 200 $this->_status[] = _("The message below has been encrypted with PGP."); 201 } 202 203 $this->_initStatus($this->getIcon($mimetype), _("PGP")); 204 $this->_status[] = _("The message below has been digitally signed via PGP."); 205 206 if (!$active) { 207 $this->_status[] = _("PGP support is not currently active so the digital signature is unable to be verified."); 208 } 209 210 /* Store PGP results in $sig_result; store text in $data. */ 211 $sig_result = ''; 212 if ($mimetype == 'multipart/signed') { 213 /* If the MIME ID is 0, we need to store the body of the message 214 in the MIME_Part object. */ 215 if (!$signenc) { 216 if (($mimeID = $mime->getMIMEId())) { 217 $mime->setContents($this->_contents->getBodyPart($mimeID)); 218 } else { 219 $mime->setContents($this->_contents->getBody()); 220 } 221 $mime->splitContents(); 222 } 223 224 /* Data that is signed appears in the first MIME subpart. */ 225 $subpart = $mime->getPart($mime->getRelativeMIMEId(1)); 226 $signature_data = rtrim($subpart->getCanonicalContents(), "\r"); 227 228 require_once 'Horde/MIME/Structure.php'; 229 $mime_message = &MIME_Structure::parseTextMIMEMessage($signature_data); 230 231 /* The PGP signature appears in the second MIME subpart. */ 232 $subpart = $mime->getPart($mime->getRelativeMIMEId(2)); 233 if ($subpart && $subpart->getType() == 'application/pgp-signature') { 234 if ($active) { 235 $subpart->transferDecodeContents(); 236 $sig_result = $this->_imp_pgp->verifySignature($signature_data, $this->_address, $subpart->getContents()); 237 } 238 } else { 239 $this->_status[] = _("The message below does not appear to be in the correct PGP format (according to RFC 2015)."); 240 } 241 } elseif ($mimetype == 'application/pgp-signature') { 242 /* Get the signed message to output. */ 243 require_once 'Horde/MIME/Message.php'; 244 $mime_message = &new MIME_Message(); 245 $mime_message->setType('text/plain'); 246 $mime->transferDecodeContents(); 247 248 if (empty($this->_imp_pgp)) { 249 $mime_message->setContents($mime->getContents()); 250 } else { 251 $mime_message->setContents($this->_imp_pgp->getSignedMessage($mime)); 252 } 253 254 /* Pass the signed text straight through to PGP program */ 255 if ($active) { 256 $sig_result = $this->_imp_pgp->verifySignature($mime->getContents(), $this->_address); 257 } 258 } 259 260 $text = $this->_outputStatus(); 261 262 if ($active) { 263 $text .= $this->_outputPGPSignatureTest($sig_result); 264 } 265 266 /* We need to stick the output into a MIME_Contents object. */ 267 $mc = &new MIME_Contents($mime_message, array('download' => 'download_attach', 'view' => 'view_attach'), array(&$this->_contents)); 268 $mc->buildMessage(); 269 270 return $text . '<table cellpadding="0" cellspacing="0">' . $mc->getMessage(true) . '</table>'; 271 } 272 273 /** 274 * Generates HTML output for 'multipart/encrypted' and 275 * 'application/pgp-encrypted' MIME_Parts. 276 * 277 * @access private 278 * 279 * @return string The HTML output. 280 */ 281 function _outputPGPEncrypted() 282 { 283 global $conf, $prefs; 284 285 $mime = &$this->mime_part; 286 $mimetype = $mime->getType(); 287 $text = ''; 288 289 $this->_initStatus($this->getIcon($mimetype), _("PGP")); 290 291 /* Print out message now if PGP is not active. */ 292 if (empty($conf['utils']['gnupg']) || !$prefs->getValue('use_pgp')) { 293 $this->_status[] = _("PGP support is not currently active so the message is unable to be decrypted."); 294 return $this->_outputStatus(); 295 } 296 297 if ($mimetype == 'multipart/encrypted') { 298 /* PGP control information appears in the first MIME subpart. We 299 don't currently need to do anything with this information. The 300 encrypted data appears in the second MIME subpart. */ 301 $subpart = $mime->getPart($mime->getRelativeMIMEId(2)); 302 if (!$subpart) { 303 return $text; 304 } 305 $encrypted_data = $this->_contents->getBodyPart($subpart->getMIMEId()); 306 } elseif ($mimetype == 'application/pgp-encrypted') { 307 $encrypted_data = $mime->getContents(); 308 } else { 309 return $text; 310 } 311 312 /* Check if this is a literal compressed message. */ 313 $info = $this->_imp_pgp->pgpPacketInformation($encrypted_data); 314 $literal = !empty($info['literal']); 315 $this->_status[] = $literal ? _("The message below has been compressed with PGP.") : _("The message below has been encrypted with PGP."); 316 317 if (!$literal && !$this->_imp_pgp->getPersonalPrivateKey()) { 318 $this->_status[] = _("No personal private key exists so the message is unable to be decrypted."); 319 return $this->_outputStatus(); 320 } 321 322 if (!$literal && !$this->_imp_pgp->getPassphrase()) { 323 $url = $this->_imp_pgp->getJSOpenWinCode('open_passphrase_dialog'); 324 $this->_status[] = Horde::link('#', _("You must enter the passphrase for your PGP private key to view this message"), null, null, $url . ' return false;') . _("You must enter the passphrase for your PGP private key to view this message") . '</a>'; 325 $text .= $this->_outputStatus() . 326 '<script type="text/javascript">' . $url . '</script>'; 327 } else { 328 if ($mimetype == 'multipart/encrypted') { 329 if ($subpart->getType() == 'application/octet-stream') { 330 $decrypted_data = $this->_imp_pgp->decryptMessage($encrypted_data, !$literal); 331 if (is_a($decrypted_data, 'PEAR_Error')) { 332 $this->_status[] = _("The message below does not appear to be a valid PGP encrypted message. Error: ") . $decrypted_data->getMessage(); 333 $text .= $this->_outputStatus(); 334 } else { 335 /* We need to check if this is a signed/encrypted 336 message. */ 337 require_once 'Horde/MIME/Structure.php'; 338 $mime_message = &MIME_Structure::parseTextMIMEMessage($decrypted_data->message); 339 if (!$mime_message) { 340 require_once 'Horde/Text/Filter.php'; 341 $text .= $this->_signedOutput($decrypted_data->sig_result); 342 $decrypted_message = String::convertCharset($decrypted_data->message, $subpart->getCharset()); 343 $text .= '<span class="fixed">' . Text_Filter::filter($decrypted_message, 'text2html', array('parselevel' => TEXT_HTML_SYNTAX)) . '</span>'; 344 } else { 345 $mimetype = $mime_message->getType(); 346 if (($mimetype == 'multipart/signed') || 347 ($mimetype == 'application/pgp-signature')) { 348 $mime_message->setInformation('pgp_signenc', true); 349 $mime_message->setContents($decrypted_data->message); 350 $mime_message->splitContents(); 351 } else { 352 $text .= $this->_signedOutput($decrypted_data->sig_result); 353 } 354 355 /* We need to stick the output into a 356 MIME_Contents object. */ 357 $mc = &new MIME_Contents($mime_message, array('download' => 'download_attach', 'view' => 'view_attach'), array(&$this->_contents)); 358 $mc->buildMessage(); 359 if ($mime_message->getInformation('pgp_signenc')) { 360 $text .= $mc->getMessage(true); 361 } else { 362 $text .= '<table cellpadding="0" cellspacing="0">' . $mc->getMessage(true) . '</table>'; 363 } 364 } 365 } 366 } else { 367 $this->_status[] = _("The message below does not appear to be in the correct PGP format (according to RFC 2015)."); 368 $text .= $this->_outputStatus(); 369 } 370 } elseif ($mimetype == 'application/pgp-encrypted') { 371 $decrypted_data = $this->_imp_pgp->decryptMessage($encrypted_data, !$literal); 372 if (is_a($decrypted_data, 'PEAR_Error')) { 373 $decrypted_message = $decrypted_data->getMessage(); 374 $text .= $this->_outputStatus(); 375 } else { 376 $text .= $this->_signedOutput($decrypted_data->sig_result); 377 $decrypted_message = String::convertCharset($decrypted_data->message, $mime->getCharset()); 378 } 379 380 require_once 'Horde/Text/Filter.php'; 381 $text .= '<span class="fixed">' . Text_Filter::filter($decrypted_message, 'text2html', array('parselevel' => TEXT_HTML_SYNTAX)) . '</span>'; 382 } 383 } 384 385 return $text; 386 } 387 388 /** 389 * Generates HTML output for the PGP signature test. 390 * 391 * @access private 392 * 393 * @param string $result Result string of the PGP output concerning the 394 * signature test. 395 * 396 * @return string The HTML output. 397 */ 398 function _outputPGPSignatureTest($result) 399 { 400 $text = ''; 401 402 if (is_a($result, 'PEAR_Error')) { 403 $this->_initStatus($GLOBALS['registry']->getImageDir('horde') . '/alerts/error.png', _("Error")); 404 $result = $result->getMessage(); 405 } else { 406 $this->_initStatus($GLOBALS['registry']->getImageDir('horde') . '/alerts/success.png', _("Success")); 407 /* This message has been verified but there was no output from the 408 PGP program. */ 409 if (empty($result)) { 410 $result = _("The message below has been verified."); 411 } 412 } 413 414 require_once 'Horde/Text/Filter.php'; 415 416 $this->_status[] = Text_Filter::filter($result, 'text2html', array('parselevel' => TEXT_HTML_NOHTML)); 417 418 return $this->_outputStatus(); 419 } 420 421 /** 422 * Output signed message status. 423 * 424 * @access private 425 * 426 * @param string $result The signature result. 427 * 428 * @return string HTML output. 429 */ 430 function _signedOutput($result) 431 { 432 if (!empty($result)) { 433 $this->_status[] = _("The message below has been digitally signed via PGP."); 434 $text = $this->_outputStatus() . 435 $this->_outputPGPSignatureTest($result); 436 } else { 437 $text = $this->_outputStatus(); 438 } 439 440 return $text; 441 } 442 443 /* Various formatting helper functions */ 444 function _initStatus($src, $alt = '') 445 { 446 if (is_null($this->_icon)) { 447 $this->_icon = Horde::img($src, $alt, 'height="16" width="16"', '') . ' '; 448 } 449 } 450 451 function _outputStatus($printable = true) 452 { 453 $output = ''; 454 if (!empty($this->_status)) { 455 $output = $this->_contents->formatStatusMsg($this->_status, $this->_icon, $printable); 456 } 457 $this->_icon = null; 458 $this->_status = array(); 459 return $output; 460 } 461 462 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:30:07 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |