Overview

Packages

  • IMP
  • None

Classes

  • IMP
  • IMP_Ajax_Application
  • IMP_Ajax_Imple_ContactAutoCompleter
  • IMP_Ajax_Imple_PassphraseDialog
  • IMP_Ajax_Queue
  • IMP_Api
  • IMP_Auth
  • IMP_Block_Newmail
  • IMP_Block_Summary
  • IMP_Compose
  • IMP_Compose_Exception
  • IMP_Compose_Stationery
  • IMP_Contents
  • IMP_Crypt_Pgp
  • IMP_Crypt_Smime
  • IMP_Dimp
  • IMP_Exception
  • IMP_Factory_AuthImap
  • IMP_Factory_Compose
  • IMP_Factory_Contents
  • IMP_Factory_Flags
  • IMP_Factory_Identity
  • IMP_Factory_Imap
  • IMP_Factory_Imaptree
  • IMP_Factory_Mail
  • IMP_Factory_Mailbox
  • IMP_Factory_MailboxList
  • IMP_Factory_MimeViewer
  • IMP_Factory_Pgp
  • IMP_Factory_Quota
  • IMP_Factory_Search
  • IMP_Factory_Sentmail
  • IMP_Factory_Smime
  • IMP_Filter
  • IMP_Flag_Base
  • IMP_Flag_Imap
  • IMP_Flag_Imap_Answered
  • IMP_Flag_Imap_Deleted
  • IMP_Flag_Imap_Draft
  • IMP_Flag_Imap_Flagged
  • IMP_Flag_Imap_Forwarded
  • IMP_Flag_Imap_Junk
  • IMP_Flag_Imap_NotJunk
  • IMP_Flag_Imap_Seen
  • IMP_Flag_System_Attachment
  • IMP_Flag_System_Encrypted
  • IMP_Flag_System_HighPriority
  • IMP_Flag_System_List
  • IMP_Flag_System_LowPriority
  • IMP_Flag_System_Match_Address
  • IMP_Flag_System_Match_Flag
  • IMP_Flag_System_Match_Header
  • IMP_Flag_System_Personal
  • IMP_Flag_System_Signed
  • IMP_Flag_System_Unseen
  • IMP_Flag_User
  • IMP_Flags
  • IMP_Imap
  • IMP_Imap_Acl
  • IMP_Imap_Exception
  • IMP_Imap_PermanentFlags
  • IMP_Imap_Thread
  • IMP_Imap_Tree
  • IMP_Indices
  • IMP_Indices_Form
  • IMP_LoginTasks_SystemTask_GarbageCollection
  • IMP_LoginTasks_SystemTask_Upgrade
  • IMP_LoginTasks_SystemTask_UpgradeAuth
  • IMP_LoginTasks_Task_Autocreate
  • IMP_LoginTasks_Task_DeleteAttachmentsMonthly
  • IMP_LoginTasks_Task_DeleteSentmailMonthly
  • IMP_LoginTasks_Task_FilterOnLogin
  • IMP_LoginTasks_Task_PurgeSentmail
  • IMP_LoginTasks_Task_PurgeSpam
  • IMP_LoginTasks_Task_PurgeTrash
  • IMP_LoginTasks_Task_RecoverDraft
  • IMP_LoginTasks_Task_RenameSentmailMonthly
  • IMP_Mailbox
  • IMP_Mailbox_List
  • IMP_Mailbox_List_Track
  • IMP_Maillog
  • IMP_Menu_Dimp
  • IMP_Message
  • IMP_Mime_Status
  • IMP_Mime_Viewer_Alternative
  • IMP_Mime_Viewer_Appledouble
  • IMP_Mime_Viewer_Audio
  • IMP_Mime_Viewer_Enriched
  • IMP_Mime_Viewer_Externalbody
  • IMP_Mime_Viewer_Html
  • IMP_Mime_Viewer_Images
  • IMP_Mime_Viewer_Itip
  • IMP_Mime_Viewer_Mdn
  • IMP_Mime_Viewer_Partial
  • IMP_Mime_Viewer_Pdf
  • IMP_Mime_Viewer_Pgp
  • IMP_Mime_Viewer_Plain
  • IMP_Mime_Viewer_Related
  • IMP_Mime_Viewer_Rfc822
  • IMP_Mime_Viewer_Smil
  • IMP_Mime_Viewer_Smime
  • IMP_Mime_Viewer_Status
  • IMP_Mime_Viewer_Vcard
  • IMP_Mime_Viewer_Video
  • IMP_Mime_Viewer_Zip
  • IMP_Notification_Event_Status
  • IMP_Notification_Handler_Decorator_ImapAlerts
  • IMP_Notification_Handler_Decorator_NewmailNotify
  • IMP_Notification_Listener_AjaxStatus
  • Imp_Prefs_Identity
  • IMP_Prefs_Ui
  • IMP_Quota
  • IMP_Quota_Base
  • IMP_Quota_Command
  • IMP_Quota_Hook
  • IMP_Quota_Imap
  • IMP_Quota_Maildir
  • IMP_Quota_Mdaemon
  • IMP_Quota_Mercury32
  • IMP_Quota_Null
  • IMP_Quota_Sql
  • IMP_Search
  • IMP_Search_Element
  • IMP_Search_Element_Attachment
  • IMP_Search_Element_Autogenerated
  • IMP_Search_Element_Bulk
  • IMP_Search_Element_Contacts
  • IMP_Search_Element_Date
  • IMP_Search_Element_Flag
  • IMP_Search_Element_Header
  • IMP_Search_Element_Mailinglist
  • IMP_Search_Element_Or
  • IMP_Search_Element_Personal
  • IMP_Search_Element_Recipient
  • IMP_Search_Element_Size
  • IMP_Search_Element_Text
  • IMP_Search_Element_Within
  • IMP_Search_Filter
  • IMP_Search_Filter_Attachment
  • IMP_Search_Filter_Autogenerated
  • IMP_Search_Filter_Builtin
  • IMP_Search_Filter_Bulk
  • IMP_Search_Filter_Contacts
  • IMP_Search_Filter_Mailinglist
  • IMP_Search_Filter_Personal
  • IMP_Search_Query
  • IMP_Search_Vfolder
  • IMP_Search_Vfolder_Builtin
  • IMP_Search_Vfolder_Vinbox
  • IMP_Search_Vfolder_Vtrash
  • IMP_Sentmail
  • IMP_Sentmail_Base
  • IMP_Sentmail_Null
  • IMP_Sentmail_Sql
  • IMP_Spam
  • IMP_Test
  • IMP_Tree_Flist
  • IMP_Tree_Jquerymobile
  • IMP_Tree_Simplehtml
  • IMP_Ui_Compose
  • IMP_Ui_Editor
  • IMP_Ui_Folder
  • IMP_Ui_Headers
  • IMP_Ui_Imageview
  • IMP_Ui_Mailbox
  • IMP_Ui_Message
  • IMP_Ui_Mimp
  • IMP_Ui_Search
  • IMP_Views_Compose
  • IMP_Views_ListMessages
  • IMP_Views_ShowMessage
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The IMP_Mime_Viewer_Pgp class allows viewing/decrypting of PGP
  4:  * formatted messages.  This class implements RFC 3156.
  5:  *
  6:  * This class handles the following MIME types:
  7:  *   - application/pgp-encrypted (in multipart/encrypted part)
  8:  *   - application/pgp-keys
  9:  *   - application/pgp-signature (in multipart/signed part)
 10:  *
 11:  * This driver may add the following parameters to the URL:
 12:  *   - pgp_verify_msg: (boolean) Do verification of PGP signed data.
 13:  *   - rawpgpkey: (boolean) Display the PGP Public Key in raw, text format?
 14:  *
 15:  * Copyright 2002-2012 Horde LLC (http://www.horde.org/)
 16:  *
 17:  * See the enclosed file COPYING for license information (GPL). If you
 18:  * did not receive this file, see http://www.horde.org/licenses/gpl.
 19:  *
 20:  * @author   Michael Slusarz <slusarz@horde.org>
 21:  * @category Horde
 22:  * @license  http://www.horde.org/licenses/gpl GPL
 23:  * @package  IMP
 24:  */
 25: class IMP_Mime_Viewer_Pgp extends Horde_Mime_Viewer_Base
 26: {
 27:     /* Metadata constants. */
 28:     const PGP_ARMOR = 'imp-pgp-armor';
 29:     const PGP_SIG = 'imp-pgp-signature';
 30:     const PGP_CHARSET = 'imp-pgp-charset';
 31: 
 32:     /**
 33:      * This driver's display capabilities.
 34:      *
 35:      * @var array
 36:      */
 37:     protected $_capability = array(
 38:         'full' => false,
 39:         'info' => false,
 40:         'inline' => true,
 41:         /* This driver *does* render raw data, but only for
 42:          * application/pgp-signature parts that have been processed by the
 43:          * text/plain driver. This is handled via the canRender() function. */
 44:         'raw' => false
 45:     );
 46: 
 47:     /**
 48:      * Metadata for the current viewer/data.
 49:      *
 50:      * @var array
 51:      */
 52:     protected $_metadata = array(
 53:         'compressed' => false,
 54:         'embedded' => true,
 55:         'forceinline' => true
 56:     );
 57: 
 58:     /**
 59:      * The address of the sender.
 60:      *
 61:      * @var string
 62:      */
 63:     protected $_address = null;
 64: 
 65:     /**
 66:      * Cached data.
 67:      *
 68:      * @var array
 69:      */
 70:     static protected $_cache = array();
 71: 
 72:     /**
 73:      * Return the full rendered version of the Horde_Mime_Part object.
 74:      *
 75:      * @return array  See parent::render().
 76:      */
 77:     protected function _renderRaw()
 78:     {
 79:         $id = $this->_mimepart->getMimeId();
 80: 
 81:         $ret = array(
 82:             $id => array(
 83:                 'data' => '',
 84:                 'type' => 'text/plain; charset=' . $this->getConfigParam('charset')
 85:             )
 86:         );
 87: 
 88:         $parts = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp')->parsePGPData($this->_mimepart->getContents());
 89:         foreach (array_keys($parts) as $key) {
 90:             if ($parts[$key]['type'] == Horde_Crypt_Pgp::ARMOR_SIGNATURE) {
 91:                 $ret[$id]['data'] = implode("\r\n", $parts[$key]['data']);
 92:                 break;
 93:             }
 94:         }
 95: 
 96:         return $ret;
 97:     }
 98: 
 99:     /**
100:      * Return the rendered inline version of the Horde_Mime_Part object.
101:      *
102:      * @return array  See parent::render().
103:      */
104:     protected function _renderInline()
105:     {
106:         $id = $this->_mimepart->getMimeId();
107: 
108:         if (Horde_Util::getFormData('rawpgpkey')) {
109:             return array(
110:                 $id => array(
111:                     'data' => $this->_mimepart->getContents(),
112:                     'type' => 'text/plain; charset=' . $this->_mimepart->getCharset()
113:                 )
114:             );
115:         }
116: 
117:         /* Determine the address of the sender. */
118:         if (is_null($this->_address)) {
119:             $headers = $this->getConfigParam('imp_contents')->getHeader();
120:             $this->_address = Horde_Mime_Address::bareAddress($headers->getValue('from'));
121:         }
122: 
123:         switch ($this->_mimepart->getType()) {
124:         case 'application/pgp-keys':
125:             return $this->_outputPGPKey();
126: 
127:         case 'multipart/signed':
128:             return $this->_outputPGPSigned();
129: 
130:         case 'multipart/encrypted':
131:             if (!isset($headers)) {
132:                 $headers = $this->getConfigParam('imp_contents')->getHeader();
133:             }
134: 
135:             $mid = $headers->getValue('message-id');
136:             if (isset(self::$_cache[$mid][$id])) {
137:                 return array_merge(array(
138:                     $id => array(
139:                         'data' => null,
140:                         'status' => self::$_cache[$mid][$id]['status'],
141:                         'type' => 'text/plain; charset=' . $this->getConfigParam('charset'),
142:                         'wrap' => self::$_cache[$mid][$id]['wrap']
143:                     )
144:                 ), self::$_cache[$mid][$id]['other']);
145:             }
146:             // Fall-through
147: 
148:         case 'application/pgp-encrypted':
149:         case 'application/pgp-signature':
150:         default:
151:             return array();
152:         }
153:     }
154: 
155:     /**
156:      * If this MIME part can contain embedded MIME part(s), and those part(s)
157:      * exist, return a representation of that data.
158:      *
159:      * @return mixed  A Horde_Mime_Part object representing the embedded data.
160:      *                Returns null if no embedded MIME part(s) exist.
161:      */
162:     protected function _getEmbeddedMimeParts()
163:     {
164:         if ($this->_mimepart->getType() != 'multipart/encrypted') {
165:             return null;
166:         }
167: 
168:         $mid = $this->getConfigParam('imp_contents')->getHeader()->getValue('message-id');
169: 
170:         $partlist = array_keys($this->_mimepart->contentTypeMap());
171:         $base_id = reset($partlist);
172:         $version_id = next($partlist);
173:         $data_id = Horde_Mime::mimeIdArithmetic($version_id, 'next');
174: 
175:         $status = new IMP_Mime_Status();
176:         $status->icon('mime/encryption.png', 'PGP');
177: 
178:         self::$_cache[$mid][$base_id] = array(
179:             'status' => array($status),
180:             'other' => array(
181:                 $version_id => null,
182:                 $data_id => null
183:             ),
184:             'wrap' => ''
185:         );
186: 
187:         /* Is PGP active? */
188:         if (empty($GLOBALS['conf']['gnupg']['path']) ||
189:             !$GLOBALS['prefs']->getValue('use_pgp')) {
190:             $status->addText(_("The data in this part has been encrypted via PGP, however, PGP support is disabled so the message cannot be decrypted."));
191:             return null;
192:         }
193: 
194:         /* PGP version information appears in the first MIME subpart. We
195:          * don't currently need to do anything with this information. The
196:          * encrypted data appears in the second MIME subpart. */
197:         $encrypted_part = $this->getConfigParam('imp_contents')->getMIMEPart($data_id);
198:         $encrypted_data = $encrypted_part->getContents();
199: 
200:         $symmetric_pass = $personal_pass = null;
201: 
202:         /* Check if this a symmetrically encrypted message. */
203:         try {
204:             $imp_pgp = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp');
205:             $symmetric = $imp_pgp->encryptedSymmetrically($encrypted_data);
206:             if ($symmetric) {
207:                 $symmetric_id = $this->_getSymmetricID();
208:                 $symmetric_pass = $imp_pgp->getPassphrase('symmetric', $symmetric_id);
209: 
210:                 if (is_null($symmetric_pass)) {
211:                     $status->addText(_("The data in this part has been encrypted via PGP."));
212: 
213:                     /* Ask for the correct passphrase if this is encrypted
214:                      * symmetrically. */
215:                     $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create(array('imp', 'PassphraseDialog'), array(
216:                         'params' => array(
217:                             'symmetricid' => $symmetric_id
218:                         ),
219:                         'type' => 'pgpSymmetric'
220:                     ));
221:                     $status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getPassphraseId())) . _("You must enter the passphrase used to encrypt this message to view it.") . '</a>');
222:                     return null;
223:                 }
224:             }
225:         } catch (Horde_Exception $e) {
226:             Horde::logMessage($e, 'INFO');
227:             return null;
228:         }
229: 
230:         /* Check if this is a literal compressed message. */
231:         try {
232:             $info = $imp_pgp->pgpPacketInformation($encrypted_data);
233:         } catch (Horde_Exception $e) {
234:             Horde::logMessage($e, 'INFO');
235:             return null;
236:         }
237: 
238:         $literal = !empty($info['literal']);
239:         if ($literal) {
240:             $status->addText(_("The data in this part has been compressed via PGP."));
241:         } else {
242:             $status->addText(_("The data in this part has been encrypted via PGP."));
243: 
244:             if (!$symmetric) {
245:                 if ($imp_pgp->getPersonalPrivateKey()) {
246:                     $personal_pass = $imp_pgp->getPassphrase('personal');
247:                     if (is_null($personal_pass)) {
248:                         /* Ask for the private key's passphrase if this is
249:                          * encrypted asymmetrically. */
250:                         $imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create(array('imp', 'PassphraseDialog'), array(
251:                             'type' => 'pgpPersonal'
252:                         ));
253:                         $status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getPassphraseId())) . _("You must enter the passphrase for your PGP private key to view this message.") . '</a>');
254:                         return null;
255:                     }
256:                 } else {
257:                     /* Output if there is no personal private key to decrypt
258:                      * with. */
259:                     $status->addText(_("However, no personal private key exists so the message cannot be decrypted."));
260:                     return null;
261:                 }
262:             }
263:         }
264: 
265:         try {
266:             if (!is_null($symmetric_pass)) {
267:                 $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'symmetric', $symmetric_pass);
268:             } elseif (!is_null($personal_pass)) {
269:                 $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'personal', $personal_pass);
270:             } else {
271:                 $decrypted_data = $imp_pgp->decryptMessage($encrypted_data, 'literal');
272:             }
273:         } catch (Horde_Exception $e) {
274:             $status->addText(_("The data in this part does not appear to be a valid PGP encrypted message. Error: ") . $e->getMessage());
275:             if (!is_null($symmetric_pass)) {
276:                 $imp_pgp->unsetPassphrase('symmetric', $this->_getSymmetricID());
277:                 return $this->_getEmbeddedMimeParts();
278:             }
279:             return null;
280:         }
281: 
282:         self::$_cache[$mid][$base_id]['wrap'] = 'mimePartWrapValid';
283: 
284:         /* Check for combined encryption/signature data. */
285:         if ($decrypted_data->result) {
286:             $sig_text = is_bool($decrypted_data->result)
287:                 ? _("The data in this part has been digitally signed via PGP.")
288:                 : $this->_textFilter($decrypted_data->result, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML));
289: 
290:             $status2 = new IMP_Mime_Status($sig_text);
291:             $status2->action(IMP_Mime_Status::SUCCESS);
292: 
293:             self::$_cache[$mid][$base_id]['status'][] = $status2;
294:         }
295: 
296:         /* Force armor data as text/plain data. */
297:         if ($this->_mimepart->getMetadata(self::PGP_ARMOR)) {
298:             $decrypted_data->message = "Content-Type: text/plain\n\n" .
299:                                        $decrypted_data->message;
300:         }
301: 
302:         return Horde_Mime_Part::parseMessage($decrypted_data->message, array(
303:             'forcemime' => true
304:         ));
305:     }
306: 
307:     /**
308:      * Generates output for 'application/pgp-keys' MIME_Parts.
309:      *
310:      * @return string  The HTML output.
311:      */
312:     protected function _outputPGPKey()
313:     {
314:         /* Is PGP active? */
315:         if (empty($GLOBALS['conf']['gnupg']['path']) ||
316:             !$GLOBALS['prefs']->getValue('use_pgp')) {
317:             return array();
318:         }
319: 
320:         /* Initialize status message. */
321:         $status = new IMP_Mime_Status(_("A PGP Public Key is attached to the message."));
322:         $status->icon('mime/encryption.png', 'PGP');
323: 
324:         $mime_id = $this->_mimepart->getMimeId();
325:         $imp_pgp = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp');
326: 
327:         if ($GLOBALS['prefs']->getValue('use_pgp') &&
328:             $GLOBALS['prefs']->getValue('add_source') &&
329:             $GLOBALS['registry']->hasMethod('contacts/addField')) {
330:             $status->addText(Horde::link('#', '', '', '', $imp_pgp->savePublicKeyURL($this->getConfigParam('imp_contents')->getMailbox(), $this->getConfigParam('imp_contents')->getUid(), $mime_id) . 'return false;') . _("Save the key to your address book.") . '</a>');
331:         }
332:         $status->addText($this->getConfigParam('imp_contents')->linkViewJS($this->_mimepart, 'view_attach', _("View the raw text of the Public Key."), array('jstext' => _("View Public Key"), 'params' => array('mode' => IMP_Contents::RENDER_INLINE, 'rawpgpkey' => 1))));
333: 
334:         try {
335:             $data = '<span class="fixed">' . nl2br(str_replace(' ', '&nbsp;', $imp_pgp->pgpPrettyKey($this->_mimepart->getContents()))) . '</span>';
336:         } catch (Horde_Exception $e) {
337:             $data = $e->getMessage();
338:         }
339: 
340:         return array(
341:             $mime_id => array(
342:                 'data' => $data,
343:                 'status' => $status,
344:                 'type' => 'text/html; charset=' . $this->getConfigParam('charset')
345:             )
346:         );
347:     }
348: 
349:     /**
350:      * Generates HTML output for 'multipart/signed' MIME parts.
351:      *
352:      * @return string  The HTML output.
353:      */
354:     protected function _outputPGPSigned()
355:     {
356:         $partlist = array_keys($this->_mimepart->contentTypeMap());
357:         $base_id = reset($partlist);
358:         $signed_id = next($partlist);
359:         $sig_id = Horde_Mime::mimeIdArithmetic($signed_id, 'next');
360: 
361:         $status = new IMP_Mime_Status();
362:         $status->icon('mime/encryption.png', 'PGP');
363: 
364:         $ret = array(
365:             $base_id => array(
366:                 'data' => '',
367:                 'nosummary' => true,
368:                 'status' => array($status),
369:                 'type' => 'text/html; charset=' . $this->getConfigParam('charset'),
370:                 'wrap' => 'mimePartWrap'
371:             ),
372:             $sig_id => null
373:         );
374: 
375:         if (!$GLOBALS['prefs']->getValue('use_pgp') ||
376:             empty($GLOBALS['conf']['gnupg']['path'])) {
377:             /* If PGP not active, hide signature data and output status
378:              * information. */
379:             $status->addText(_("The data in this part has been digitally signed via PGP, but the signature cannot be verified."));
380:             return $ret;
381:         }
382: 
383:         $status->addText(_("The data in this part has been digitally signed via PGP."));
384: 
385:         if ($GLOBALS['prefs']->getValue('pgp_verify') ||
386:             Horde_Util::getFormData('pgp_verify_msg')) {
387:             $sig_part = $this->getConfigParam('imp_contents')->getMIMEPart($sig_id);
388: 
389:             $status2 = new IMP_Mime_Status();
390: 
391:             try {
392:                 $imp_pgp = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp');
393:                 $sig_result = $sig_part->getMetadata(self::PGP_SIG)
394:                     ? $imp_pgp->verifySignature($sig_part->getContents(array('canonical' => true)), $this->_address, null, $sig_part->getMetadata(self::PGP_CHARSET))
395:                     : $imp_pgp->verifySignature($sig_part->replaceEOL($this->getConfigParam('imp_contents')->getBodyPart($signed_id, array('mimeheaders' => true)), Horde_Mime_Part::RFC_EOL), $this->_address, $sig_part->getContents());
396: 
397:                 $status2->action(IMP_Mime_Status::SUCCESS);
398:                 $sig_text = $sig_result->message;
399:                 $ret[$base_id]['wrap'] = 'mimePartWrapValid';
400:             } catch (Horde_Exception $e) {
401:                 $status2->action(IMP_Mime_Status::ERROR);
402:                 $sig_text = $e->getMessage();
403:                 $ret[$base_id]['wrap'] = 'mimePartWrapInvalid';
404:             }
405: 
406:             $status2->addText($this->_textFilter($sig_text, 'text2html', array(
407:                 'parselevel' => Horde_Text_Filter_Text2html::NOHTML
408:             )));
409:             $ret[$base_id]['status'][] = $status2;
410:         } else {
411:             switch (IMP::getViewMode()) {
412:             case 'imp':
413:                 $status->addText(Horde::link(IMP::selfUrl()->add(array('pgp_verify_msg' => 1))) . _("Click HERE to verify the message.") . '</a>');
414:                 break;
415: 
416:             case 'dimp':
417:                 $status->addText(Horde::link('#', '', 'pgpVerifyMsg') . _("Click HERE to verify the message.") . '</a>');
418:                 break;
419:             }
420:         }
421: 
422:         return $ret;
423:     }
424: 
425:     /**
426:      * Generates the symmetric ID for this message.
427:      *
428:      * @return string  Symmetric ID.
429:      */
430:     protected function _getSymmetricID()
431:     {
432:         return $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp')->getSymmetricID($this->getConfigParam('imp_contents')->getMailbox(), $this->getConfigParam('imp_contents')->getUid(), $this->_mimepart->getMimeId());
433:     }
434: 
435:     /**
436:      * Can this driver render the the data?
437:      *
438:      * @param string $mode  See parent::canRender().
439:      *
440:      * @return boolean  See parent::canRender().
441:      */
442:     public function canRender($mode)
443:     {
444:         return (($mode == 'raw') &&
445:                 ($this->_mimepart->getType() == 'application/pgp-signature') &&
446:                 $this->_mimepart->getMetadata(self::PGP_SIG))
447:             ? true
448:             : parent::canRender($mode);
449:     }
450: 
451: }
452: 
API documentation generated by ApiGen