[ Index ]
 

Code source de IMP H3 (4.1.5)

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/lib/MIME/Viewer/ -> pkcs7.php (source)

   1  <?php
   2  
   3  require_once  IMP_BASE . '/lib/Crypt/SMIME.php';
   4  require_once 'Horde/MIME/Structure.php';
   5  
   6  /**
   7   * The IMP_MIME_Viewer_pkcs7 class allows viewing/decrypting of S/MIME
   8   * messages.
   9   * This class implements parts of RFC 2630, RFC 2632, and RFC 2633.
  10   *
  11   * This class handles the following MIME types:
  12   *   application/pkcs7-mime
  13   *   application/pkcs7-signature
  14   *   application/x-pkcs7-mime
  15   *   application/x-pkcs7-signature
  16   *
  17   * $Horde: imp/lib/MIME/Viewer/pkcs7.php,v 1.68.2.20 2007/01/02 13:55:00 jan Exp $
  18   *
  19   * Copyright 2002-2007 Mike Cochrane <mike@graftonhall.co.nz>
  20   * Copyright 2004-2007 Michael Slusarz <slusarz@curecanti.org>
  21   *
  22   * See the enclosed file COPYING for license information (GPL). If you
  23   * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
  24   *
  25   * @author  Mike Cochrane <mike@graftonhall.co.nz>
  26   * @author  Michael Slusarz <slusarz@curecanti.org>
  27   * @since   IMP 4.0
  28   * @package Horde_MIME_Viewer
  29   */
  30  class IMP_MIME_Viewer_pkcs7 extends MIME_Viewer {
  31  
  32      /**
  33       * IMP_SMIME object.
  34       *
  35       * @var IMP_SMIME
  36       */
  37      var $_impSmime;
  38  
  39      /**
  40       * Classwide cache for icons for status messages.
  41       *
  42       * @var string
  43       */
  44      var $_icon = null;
  45  
  46      /**
  47       * Pointer to the MIME_Contents item.
  48       *
  49       * @var MIME_Contents
  50       */
  51      var $_contents = null;
  52  
  53      /**
  54       * Classwide cache for status messages.
  55       *
  56       * @var array
  57       */
  58      var $_status = array();
  59  
  60      /**
  61       * The IMP_Headers object for the message data.
  62       *
  63       * @var IMP_Headers
  64       */
  65      var $_headers;
  66  
  67      /**
  68       * Some mailers set S/MIME messages to always be attachments.  However,
  69       * most of the time S/MIME is used to secure the contents of the message,
  70       * so displaying as an attachment makes no sense.  Therefore, force
  71       * viewing inline (or at least let MIME_Viewer/MIME_Contents make the
  72       * determination on whether the data can be viewed inline or not).
  73       *
  74       * @var boolean
  75       */
  76      var $_forceinline = true;
  77  
  78      /**
  79       * Render out the currently set contents.
  80       *
  81       * @param array $params  An array with a reference to a MIME_Contents
  82       *                       object.
  83       *
  84       * @return string  The rendered text in HTML.
  85       */
  86      function render($params)
  87      {
  88          /* Set the MIME_Contents class variable. */
  89          $this->_contents = &$params[0];
  90  
  91          $msg = '';
  92  
  93          if (empty($this->_impSmime)) {
  94              $this->_impSmime = &new IMP_SMIME();
  95          }
  96  
  97          /* Check to see if S/MIME support is available. */
  98          $openssl_check = $this->_impSmime->checkForOpenSSL();
  99          if ($GLOBALS['prefs']->getValue('use_smime') &&
 100              !is_a($openssl_check, 'PEAR_Error')) {
 101              /* We need to insert JavaScript code now if S/MIME support is
 102                 active. */
 103              $msg = Util::bufferOutput(array('Horde', 'addScriptFile'), 'popup.js');
 104          }
 105  
 106          /* Get the type of message now. */
 107          $type = $this->_getSMIMEType();
 108          switch ($type) {
 109          case 'signed':
 110              $msg .= $this->_outputSMIMESigned();
 111              break;
 112  
 113          case 'encrypted':
 114              $msg .= $this->_outputSMIMEEncrypted();
 115              break;
 116          }
 117  
 118          return $msg;
 119      }
 120  
 121      /**
 122       * Generates HTML output for the S/MIME key in
 123       * 'application/pkcs7-signature' MIME_Parts.
 124       *
 125       * @access private
 126       *
 127       * @return string  The HTML output.
 128       */
 129      function _outputSMIMEKey()
 130      {
 131          if (!$GLOBALS['prefs']->getValue('use_smime')) {
 132              return _("S/MIME support is not enabled.");
 133          } else {
 134              $mime = &$this->mime_part;
 135              $signenc = $mime->getInformation('smime_signenc');
 136              $raw_text = $this->_getRawSMIMEText();
 137              if ($signenc && $mime->getInformation('smime_from')) {
 138                  $smime_from = $mime->getInformation('smime_from');
 139                  $raw_text = "From: $smime_from\n" . $raw_text;
 140              }
 141              $sig_result = $this->_impSmime->verifySignature($raw_text);
 142              return $this->_impSmime->certToHTML($sig_result->cert);
 143          }
 144      }
 145  
 146      /**
 147       * Generates HTML output for 'multipart/signed',
 148       * 'application/pkcs7-signature' and
 149       * 'application/x-pkcs7-signature' MIME_Parts.
 150       *
 151       * @access private
 152       *
 153       * @return string  The HTML output.
 154       */
 155      function _outputSMIMESigned()
 156      {
 157          if (Util::getFormData('viewkey')) {
 158              return $this->_outputSMIMEKey();
 159          }
 160  
 161          $cert = $text = '';
 162          $mime = &$this->mime_part;
 163          $mimetype = $mime->getType();
 164          $active = $GLOBALS['prefs']->getValue('use_smime');
 165  
 166          $signenc = $mime->getInformation('smime_signenc');
 167          if ($signenc) {
 168              $this->_status[] = _("This message has been encrypted via S/MIME.");
 169          }
 170  
 171          $this->_initStatus($this->getIcon($mimetype), _("S/MIME"));
 172          $this->_status[] = _("This message has been digitally signed via S/MIME.");
 173  
 174          if (!$active) {
 175              $this->_status[] = _("S/MIME support is not enabled so the digital signature is unable to be verified.");
 176          }
 177  
 178          /* Store S/MIME results in $sig_result. */
 179          $sig_result = null;
 180          if ($mimetype == 'multipart/signed') {
 181              if (!$signenc) {
 182                  if (($mimeID = $mime->getMIMEId())) {
 183                      $mime->setContents($this->_contents->getBodyPart($mimeID));
 184                  } else {
 185                      $mime->setContents($this->_contents->getBody());
 186                  }
 187                  $mime->splitContents();
 188              }
 189  
 190              /* Data that is signed appears in the first MIME subpart. */
 191              $signed_part = $mime->getPart($mime->getRelativeMIMEId(1));
 192              $signed_data = rtrim($signed_part->getCanonicalContents(), "\r");
 193              $mime_message = &MIME_Structure::parseTextMIMEMessage($signed_data);
 194  
 195              /* The S/MIME signature appears in the second MIME subpart. */
 196              $subpart = $mime->getPart($mime->getRelativeMIMEId(2));
 197              if (!$subpart ||
 198                  !in_array($subpart->getType(), array('application/pkcs7-signature', 'application/x-pkcs7-signature'))) {
 199                  $this->_status[] = _("This message does not appear to be in the correct S/MIME format.");
 200              }
 201          } elseif (!$active) {
 202              $this->_status[] = _("S/MIME support is not enabled so the contents of this signed message cannot be displayed.");
 203          }
 204  
 205          if ($active) {
 206              $raw_text = $this->_getRawSMIMEText();
 207              if ($signenc && $mime->getInformation('smime_from')) {
 208                  $smime_from = $mime->getInformation('smime_from');
 209                  $raw_text = "From: $smime_from\n" . $raw_text;
 210              }
 211              $sig_result = $this->_impSmime->verifySignature($raw_text);
 212              if (!isset($subpart)) {
 213                  $msg_data = $this->_impSmime->extractSignedContents($raw_text);
 214                  if (is_a($msg_data, 'PEAR_Error')) {
 215                      $this->_status[] = $msg_data->getMessage();
 216                      $mime_message = $mime;
 217                  } else {
 218                      $mime_message = &MIME_Structure::parseTextMIMEMessage($msg_data);
 219                  }
 220              }
 221  
 222              $text = $this->_outputStatus();
 223              $text .= $this->_outputSMIMESignatureTest($sig_result->result, $sig_result->email);
 224              if (!empty($sig_result->cert)) {
 225                  if (!isset($smime_from) && isset($this->_headers['from'])) {
 226                      $smime_from = $this->_headers['from'];
 227                  }
 228                  if (isset($smime_from) &&
 229                      $GLOBALS['registry']->hasMethod('contacts/addField') &&
 230                      $GLOBALS['prefs']->getValue('add_source')) {
 231                      $this->_status[] = sprintf(_("The S/MIME certificate of %s: "), @htmlspecialchars($smime_from, ENT_COMPAT, NLS::getCharset())) .
 232                          $this->_contents->linkViewJS($subpart, 'view_attach', _("View"), '', null, array('viewkey' => 1)) . '/' .
 233                          Horde::link('#', '', null, null, $this->_impSmime->savePublicKeyURL($sig_result->cert, $smime_from) . ' return false;') . _("Save in your Address Book") . '</a>';
 234                      $text .= $this->_outputStatus();
 235                  }
 236              }
 237          }
 238  
 239          if (isset($mime_message)) {
 240              /* We need to stick the output into a MIME_Contents object. */
 241              $mc = &new MIME_Contents($mime_message, array('download' => 'download_attach', 'view' => 'view_attach'), array(&$this->_contents));
 242              $mc->buildMessage();
 243  
 244              $text .= '<table cellpadding="0" cellspacing="0">' . $mc->getMessage(true) . '</table>';
 245          } else {
 246              $text = $this->_outputStatus();
 247          }
 248  
 249          return $text;
 250      }
 251  
 252      /**
 253       * Generates HTML output for 'multipart/encrypted',
 254       * 'application/pkcs7-mime' and
 255       * 'application/x-pkcs7-mime' MIME_Parts.
 256       *
 257       * @access private
 258       *
 259       * @return string  The HTML output.
 260       */
 261      function _outputSMIMEEncrypted()
 262      {
 263          $active = $GLOBALS['prefs']->getValue('use_smime');
 264          $mime = &$this->mime_part;
 265          $mimetype = $mime->getType();
 266          $msg = '';
 267  
 268          $this->_initStatus($this->getIcon($mime->getType()), _("S/MIME"));
 269          $this->_status[] = _("This message has been encrypted via S/MIME.");
 270  
 271          if (!$active) {
 272              $this->_status[] = _("S/MIME support is not currently enabled so the message is unable to be decrypted.");
 273              return $this->_outputStatus();
 274          }
 275  
 276          if (!$this->_impSmime->getPersonalPrivateKey()) {
 277              $this->_status[] = _("No personal private key exists so the message is unable to be decrypted.");
 278              return $this->_outputStatus();
 279          }
 280  
 281          /* Make sure we have a passphrase. */
 282          $passphrase = $this->_impSmime->getPassphrase();
 283          if ($passphrase === false) {
 284              $url = $this->_impSmime->getJSOpenWinCode('open_passphrase_dialog');
 285              $this->_status[] = Horde::link('#', _("You must enter the passphrase for your S/MIME private key to view this message"), null, null, $url . ' return false;') . '<em>' . _("You must enter the passphrase for your S/MIME private key to view this message") . '</em></a>.';
 286              $msg .= $this->_outputStatus() .
 287                  '<script type="text/javascript">' . $url . ';</script>';
 288              return $msg;
 289          }
 290  
 291          $raw_text = $this->_getRawSMIMEText();
 292          $decrypted_data = $this->_impSmime->decryptMessage($raw_text);
 293  
 294          if (is_a($decrypted_data, 'PEAR_Error')) {
 295              $this->_status[] = $decrypted_data->getMessage();
 296              return $this->_outputStatus();
 297          }
 298  
 299          /* We need to check if this is a signed/encrypted message. */
 300          $mime_message = &MIME_Structure::parseTextMIMEMessage($decrypted_data);
 301          if ($mime_message) {
 302              /* Check for signed and encoded data. */
 303              if (in_array($mime_message->getType(), array('multipart/signed', 'application/pkcs7-mime', 'application/x-pkcs7-mime'))) {
 304                  $mime_message->setContents($decrypted_data);
 305                  $mime_message->splitContents();
 306                  $mime_message->setInformation('smime_signenc', true);
 307                  if (isset($this->_headers['from'])) {
 308                      $mime_message->setInformation('smime_from', $this->_headers['from']);
 309                  }
 310              } else {
 311                  $msg .= $this->_outputStatus();
 312              }
 313  
 314              /* We need to stick the output into a MIME_Contents object. */
 315              $mc = &new MIME_Contents($mime_message, array('download' => 'download_attach', 'view' => 'view_attach'), array(&$this->_contents));
 316              $mc->buildMessage();
 317              $msg .= '<table cellpadding="0" cellspacing="0">' . $mc->getMessage(true) . '</table>';
 318          } else {
 319              require_once 'Horde/Text/Filter.php';
 320              $msg .= $this->_outputStatus() .
 321                  '<span class="fixed">' . Text_Filter::filter($decrypted_data, 'text2html', array('parselevel' => TEXT_HTML_SYNTAX)) . '</span>';
 322          }
 323  
 324          return $msg;
 325      }
 326  
 327      /**
 328       * Return text/html as the content-type.
 329       *
 330       * @return string  "text/html" constant.
 331       */
 332      function getType()
 333      {
 334          return 'text/html; charset=' . NLS::getCharset();
 335      }
 336  
 337      /**
 338       * Get the headers of the S/MIME message.
 339       *
 340       * @access private
 341       */
 342      function _getRawSMIMEText()
 343      {
 344          $mime = &$this->mime_part;
 345  
 346          $mime->setContents($this->_contents->getBody());
 347          if (is_a($this->_contents, 'IMP_Contents') &&
 348              (($mime->getMIMEId() == 0) ||
 349               ($mime->splitContents() == false))) {
 350              $imp_headers = &$this->_contents->getHeaderOb();
 351              $this->_headers = MIME_Structure::parseMIMEHeaders($imp_headers->getHeaderText(), true, true);
 352              return $this->_contents->fullMessageText();
 353          } else {
 354              require_once  IMP_BASE . '/lib/MIME/Headers.php';
 355              $header_text = $mime->getCanonicalContents();
 356              $header_text = substr($header_text, 0, strpos($header_text, "\r\n\r\n"));
 357              $this->_headers = MIME_Structure::parseMIMEHeaders($header_text, true, true);
 358  
 359              $imp_headers = new IMP_Headers();
 360              if (isset($this->_headers['content-type'])) {
 361                  $imp_headers->addHeader('Content-Type', $this->_headers['content-type']);
 362              }
 363              if (isset($this->_headers['from'])) {
 364                  $imp_headers->addHeader('From', $this->_headers['from']);
 365              }
 366              if (isset($this->_headers['to'])) {
 367                  $imp_headers->addHeader('To', $this->_headers['to']);
 368              }
 369  
 370              return $imp_headers->toString() . $mime->toCanonicalString();
 371          }
 372      }
 373  
 374      /* Various formatting helper functions. */
 375      function _initStatus($src, $alt = '')
 376      {
 377          if (is_null($this->_icon)) {
 378              $this->_icon = Horde::img($src, $alt, 'height="16" width="16"', '') . '&nbsp;';
 379          }
 380      }
 381  
 382      function _outputStatus()
 383      {
 384          $output = '';
 385          if (!empty($this->_status)) {
 386              $output = $this->_contents->formatStatusMsg($this->_status, $this->_icon);
 387          }
 388          $this->_icon = null;
 389          $this->_status = array();
 390          return $output;
 391      }
 392  
 393      /**
 394       * Generates HTML output for the S/MIME signature test.
 395       *
 396       * @access private
 397       *
 398       * @param string $result  Result string of the S/MIME output concerning
 399       *                        the signature test.
 400       * @param string $email   The email of the sender.
 401       *
 402       * @return string  The HTML output.
 403       */
 404      function _outputSMIMESignatureTest($result, $email)
 405      {
 406          $text = '';
 407  
 408          if (is_a($result, 'PEAR_Error')) {
 409              if ($result->getCode() == 'horde.warning') {
 410                  $this->_initStatus($GLOBALS['registry']->getImageDir('horde') . '/alerts/warning.png', _("Warning"));
 411              } else {
 412                  $this->_initStatus($GLOBALS['registry']->getImageDir('horde') . '/alerts/error.png', _("Error"));
 413              }
 414              $result = $result->getMessage();
 415          } else {
 416              $this->_initStatus($GLOBALS['registry']->getImageDir('horde') . '/alerts/success.png', _("Success"));
 417              /* This message has been verified but there was no output
 418                 from the PGP program. */
 419              if (empty($result) || ($result === true)) {
 420                 $email = (is_array($email)) ? implode(', ', $email): $email;
 421                 $result = sprintf(_("The message has been verified. Sender: %s."), htmlspecialchars($email));
 422              }
 423          }
 424  
 425          require_once 'Horde/Text/Filter.php';
 426  
 427          $this->_status[] = Text_Filter::filter($result, 'text2html', array('parselevel' => TEXT_HTML_NOHTML));
 428  
 429          return $this->_outputStatus();
 430      }
 431  
 432      /**
 433       * Render out attachment information.
 434       *
 435       * @param array $params  An array with a reference to a MIME_Contents
 436       *                       object.
 437       *
 438       * @return string  The rendered text in HTML.
 439       */
 440      function renderAttachmentInfo($params)
 441      {
 442          $this->_contents = &$params[0];
 443  
 444          $type = $this->_getSMIMEType();
 445          switch ($type) {
 446              case 'signed':
 447                  $this->_status[] = _("This message contains an attachment that has been digitally signed via S/MIME.");
 448                  break;
 449  
 450              case 'encrypted':
 451                  $this->_status[] = _("This message contains an attachment that has been encrypted via S/MIME.");
 452                  break;
 453          }
 454  
 455          $this->_status[] = sprintf(_("Click %s to view the attachment in a separate window."), $this->_contents->linkViewJS($this->mime_part, 'view_attach', _("HERE"), _("View attachment in a separate window")));
 456          $this->_initStatus($this->getIcon($this->mime_part->getType()), _("S/MIME"));
 457          return $this->_outputStatus();
 458      }
 459  
 460      /**
 461       * Deterimne the S/MIME type of the message.
 462       *
 463       * @access private
 464       *
 465       * @return string  Either 'encrypted' or 'signed'.
 466       */
 467      function _getSMIMEType()
 468      {
 469          $type = $this->mime_part->getType();
 470          if (in_array($type, array('application/pkcs7-mime', 'application/x-pkcs7-mime'))) {
 471              $smime_type = $this->mime_part->getContentTypeParameter('smime-type');
 472              if ($smime_type == 'signed-data') {
 473                  return 'signed';
 474              } elseif (!$smime_type || ($smime_type == 'enveloped-data')) {
 475                  return 'encrypted';
 476              }
 477          }
 478  
 479          switch ($type) {
 480          case 'multipart/signed':
 481          case 'application/pkcs7-signature':
 482          case 'application/x-pkcs7-signature':
 483              return 'signed';
 484          }
 485      }
 486  
 487  }


Généré le : Thu Nov 29 12:30:07 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics