Passphrase dialogs now use redbox.js to display.
$imp_pgp = &Horde_Crypt::singleton(array('imp', 'pgp'));
Horde::addScriptFile('popup.js', 'imp', true);
if ($pgp_passphrase_dialog) {
- $notification->push($imp_pgp->getJSOpenWinCode('open_passphrase_dialog', "opener.focus();opener.uniqSubmit('send_message');"), 'javascript');
+ $notification->push(IMP::passphraseDialogJS('PGPPersonal', 'uniqSubmit(\'send_message\')'), 'javascript');
} else {
- $notification->push($imp_pgp->getJSOpenWinCode('open_symmetric_passphrase_dialog', "opener.focus();opener.uniqSubmit('send_message');", array('symmetricid' => 'imp_compose_' . $composeCacheID)), 'javascript');
+ $notification->push(IMP::passphraseDialogJS('PGPSymmetric', 'uniqSubmit(\'send_message\')', array('symmetricid' => 'imp_compose_' . $composeCacheID)), 'javascript');
}
} elseif ($smime_passphrase_dialog) {
$imp_smime = &Horde_Crypt::singleton(array('imp', 'smime'));
v5.0-cvs
--------
+[mms] PGP functions now work in DIMP (Bug #5388).
[mms] Encrypted bodytext now appears when replying/forwarding a message
(Request #1345).
[mms] When deleting/emptying a folder, display message count (Request #7424).
// encoding.
ob_start();
+$notify = true;
$result = false;
/* We know we are going to be exclusively dealing with this mailbox, so
$imp_ui = new IMP_UI_Message();
$imp_ui->MDNCheck(reset($fetch_ret[$index]['headertext']), true);
break;
+
+case 'PGPSymmetric':
+case 'PGPPersonal':
+ $imp_pgp = &Horde_Crypt::singleton(array('imp', 'pgp'));
+ $secure_check = $imp_pgp->requireSecureConnection();
+
+ $symmetricid = Util::getFormData('symmetricid');
+ $passphrase = Util::getFormData('passphrase');
+
+ $result = new stdClass;
+ $result->success = false;
+
+ if (is_a($secure_check, 'PEAR_Error')) {
+ $result->error = $secure_check->getMessage();
+ } elseif ($passphrase) {
+ if ($imp_pgp->storePassphrase(($action == 'PGPSymmetric') ? 'symmetric' : 'personal', $passphrase, $symmetricid)) {
+ $result->success = true;
+ } else {
+ $result->error = _("Invalid passphrase entered.");
+ }
+ } else {
+ $result->error = _("No passphrase entered.");
+ }
+
+ /* TODO - This code will eventually be moved to the API. But this function
+ * may be called by IMP so explicitly include DIMP.php. */
+ require_once IMP_BASE . '/lib/DIMP.php';
+ $notify = false;
+
+ print_r($_SESSION['imp']['cache']);
+ break;
}
// Clear the output buffer that we started above, and log any unexpected
}
// Send the final result.
-IMP::sendHTTPResponse(DIMP::prepareResponse($result), 'json');
+IMP::sendHTTPResponse(DIMP::prepareResponse($result, $notify), 'json');
array('popup.js', 'imp', true)
);
+/* Load necessary files for PGP or S/MIME passphrase input. */
+if ((!empty($GLOBALS['conf']['utils']['gnupg']) &&
+ $GLOBALS['prefs']->getValue('use_pgp')) ||
+ ($GLOBALS['prefs']->getValue('use_smime') &&
+ Util::extensionExists('openssl'))) {
+ $scripts[] = array('encrypt.js', 'imp', true);
+}
+
/* Get site specific menu items. */
$js_code = $site_menu = array();
if (is_readable(IMP_BASE . '/config/menu.php')) {
--- /dev/null
+var IMPEncrypt={display:function(A){A=decodeURIComponent(A).evalJSON(true);this.action=A.action;this.params=A.params;this.uri=A.uri;var B=new Element("FORM",{action:"#",id:"RB_confirm"}).insert(new Element("P").insert(A.text)).insert(new Element("INPUT",{type:"text",size:15})).insert(new Element("INPUT",{type:"button",className:"button",value:A.ok_text}).observe("click",this._onClick.bind(this))).insert(new Element("INPUT",{type:"button",className:"button",value:A.cancel_text}).observe("click",this._close.bind(this))).observe("keydown",function(C){if((C.keyCode||C.charCode)==Event.KEY_RETURN){C.stop();this._onClick(C)}}.bind(this));RedBox.overlay=true;RedBox.onDisplay=Form.focusFirstElement.curry(B);RedBox.showHtml(B)},_close:function(){var A=RedBox.getWindowContents();[A,A.descendants()].flatten().compact().invoke("stopObserving");RedBox.close()},_onClick:function(A){params=this.params||{};params.passphrase=$F(A.findElement("form").down("input"));new Ajax.Request(this.uri,{parameters:params,onSuccess:this._onSuccess.bind(this),onFailure:this._onFailure.bind(this)})},_onSuccess:function(A){try{A=A.responseText.evalJSON(true)}catch(B){}if(A.response.success){this._close();if(this.action){this.action()}else{location.reload()}}else{if(A.response.error){alert(A.response.error)}}},_onFailure:function(A){}};
\ No newline at end of file
--- /dev/null
+/**
+ * Javascript code used to display a RedBox pasphrase dialog.
+ *
+ * Copyright 2008 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (GPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ *
+ * @author Michael Slusarz <slusarz@curecanti.org>
+ */
+
+var IMPEncrypt = {
+
+ display: function(data)
+ {
+ data = decodeURIComponent(data).evalJSON(true);
+ this.action = data.action;
+ this.params = data.params;
+ this.uri = data.uri;
+
+ var n = new Element('FORM', { action: '#', id: 'RB_confirm' }).insert(
+ new Element('P').insert(data.text)
+ ).insert(
+ new Element('INPUT', { type: 'text', size: 15 })
+ ).insert(
+ new Element('INPUT', { type: 'button', className: 'button', value: data.ok_text }).observe('click', this._onClick.bind(this))
+ ).insert(
+ new Element('INPUT', { type: 'button', className: 'button', value: data.cancel_text }).observe('click', this._close.bind(this))
+ ).observe('keydown', function(e) { if ((e.keyCode || e.charCode) == Event.KEY_RETURN) { e.stop(); this._onClick(e); } }.bind(this));
+
+ RedBox.overlay = true;
+ RedBox.onDisplay = Form.focusFirstElement.curry(n);
+ RedBox.showHtml(n);
+ },
+
+ _close: function()
+ {
+ var c = RedBox.getWindowContents();
+ [ c, c.descendants()].flatten().compact().invoke('stopObserving');
+ RedBox.close();
+ },
+
+ _onClick: function(e)
+ {
+ params = this.params || {};
+ params.passphrase = $F(e.findElement('form').down('input'));
+
+ new Ajax.Request(this.uri, { parameters: params, onSuccess: this._onSuccess.bind(this), onFailure: this._onFailure.bind(this) });
+ },
+
+ _onSuccess: function(r)
+ {
+ try {
+ r = r.responseText.evalJSON(true);
+ } catch (e) {}
+
+ if (r.response.success) {
+ this._close();
+ if (this.action) {
+ this.action();
+ } else {
+ location.reload();
+ }
+ } else if (r.response.error) {
+ alert(r.response.error);
+ }
+ },
+
+ _onFailure: function(r)
+ {
+ }
+
+};
/**
* 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)
+ public function unsetPassphrase($type, $id = null)
{
- unset($_SESSION['imp']['cache']['pgp'][$type]);
+ if (($type == 'symmetric') && !is_null($id)) {
+ unset($_SESSION['imp']['cache']['pgp']['symmetric'][$id]);
+ } else {
+ unset($_SESSION['imp']['cache']['pgp'][$type]);
+ }
}
/**
*/
public function savePublicKeyURL($mailbox, $uid, $id)
{
- return $this->getJSOpenWinCode('save_attachment_public_key', false, array('mailbox' => $mailbox, 'uid' => $uid, 'mime_id' => $id));
- }
-
- /**
- * Print out the link for the javascript PGP popup.
- *
- * @param string $actionid The ActionID to perform.
- * @param mixed $reload If true, reload base window on close. If text,
- * run this JS on close. If false, don't do
- * anything on close.
- * @param array $params Additional parameters needed for the popup
- * page.
- *
- * @return string The javascript link.
- */
- public function getJSOpenWinCode($actionid, $reload = true,
- $params = array())
- {
- $params['actionID'] = $actionid;
- if (!empty($reload)) {
- if (is_bool($reload)) {
- $params['reload'] = html_entity_decode(Util::removeParameter(Horde::selfUrl(true), array('actionID')));
- } else {
- require_once 'Horde/SessionObjects.php';
- $cacheSess = &Horde_SessionObjects::singleton();
- $params['passphrase_action'] = $cacheSess->storeOid($reload, false);
- }
- }
-
+ $params = array(
+ 'actionID' => 'save_attachment_public_key',
+ 'uid' => $uid,
+ 'mime_id' => $id
+ );
return IMP::popupIMPString('pgp.php', $params, 450, 200);
}
}
/**
+ * Do necessary escaping to output JSON in a HTML parameter.
+ *
+ * @param mixed $json The data to JSON-ify.
+ *
+ * @return string The escaped string.
+ */
+ static public function escapeJSON($json)
+ {
+ return '/*-secure-' . rawurlencode(Horde_Serialize::serialize($json, SERIALIZE_JSON, NLS::getCharset())) . '*/';
+ }
+
+ /**
* Log login related message.
*
* @param string $status Either 'login', 'logout', or 'failed'.
return $cache;
}
+
+ /**
+ * Generate the JS code necessary to open a passphrase dialog. Adds the
+ * necessary JS files to open the dialog.
+ *
+ * @param string $type The dialog type.
+ * @param string $action The JS code to run after success. Defaults to
+ * reloading the current window.
+ * @param array $params Any additiona parameters to pass.
+ *
+ * @return string The generated JS code.
+ */
+ static public function passphraseDialogJS($type, $action = null,
+ $params = array())
+ {
+ Horde::addScriptFile('prototype.js', 'horde', true);
+ Horde::addScriptFile('effects.js', 'horde', true);
+ Horde::addScriptFile('encrypt.js', 'imp', true);
+ Horde::addScriptFile('redbox.js', 'imp', true);
+
+ switch ($type) {
+ case 'PGPPersonal':
+ $text = _("Enter your personal PGP passphrase.");
+ break;
+
+ case 'PGPSymmetric':
+ $text = _("Enter the passphrase used to encrypt this message.");
+ break;
+ }
+
+ $js_params = array(
+ 'action' => $action ? 'function() {' . $action . '}' : '',
+ 'uri' => Horde::applicationUrl('imp-dimp.php', true, -1) . '/' . $type,
+ 'params' => $params,
+ 'text' => $text,
+ 'ok_text' => _("OK"),
+ 'cancel_text' => _("Cancel")
+ );
+
+ return 'IMPEncrypt.display(\'' . IMP::escapeJSON($js_params) . '\')';
+ }
}
$this->_address = Horde_Mime_Address::bareAddress($headers->getValue('from'));
}
- /* We need to insert JS code if PGP support is active. */
- if (!empty($this->_imppgp) && $GLOBALS['prefs']->getValue('use_pgp')) {
- Horde::addScriptFile('prototype.js', 'horde', true);
- Horde::addScriptFile('popup.js', 'imp', true);
- }
-
switch ($this->_mimepart->getType()) {
case 'application/pgp-keys':
return $this->_outputPGPKey();
$data_id = Horde_Mime::mimeIdArithmetic($version_id, 'next');
/* Initialize inline data. */
+ $resymmetric = isset(self::$_inlinecache[$base_id]);
self::$_inlinecache[$base_id] = array(
$base_id => array(
'data' => '',
'status' => array(
array(
'icon' => Horde::img('mime/encryption.png', 'PGP'),
- 'text' => array()
+ 'text' => $resymmetric ? self::$_inlinecache[$base_id][$base_id]['status'][0]['text'] : array()
)
),
'type' => 'text/html; charset=' . NLS::getCharset()
/* Check if this a symmetrically encrypted message. */
$symmetric = $this->_imppgp->encryptedSymmetrically($encrypted_data);
if ($symmetric) {
- $symmetric_id = $this->_imppgp->getSymmetricID($this->_params['contents']->getMailbox(), $this->_params['contents']->getIndex(), $this->_mimepart->getMimeId());
+ $symmetric_id = $this->_getSymmetricID();
$symmetric_pass = $this->_imppgp->getPassphrase('symmetric', $symmetric_id);
if (is_null($symmetric_pass)) {
- if ($_SESSION['imp']['view'] == 'imp') {
- // TODO: Fix to work with DIMP
+ $js_action = '';
+
+ switch ($_SESSION['imp']['view']) {
+ case 'dimp':
+ $js_action = 'DimpCore.reloadMessage({});';
+ // Fall through
+
+ case 'imp':
/* Ask for the correct passphrase if this is encrypted
* symmetrically. */
- $status[] = Horde::link('#', _("The message below has been encrypted with PGP. You must enter the passphrase that was used to encrypt this message."), null, null, $this->_imppgp->getJSOpenWinCode('open_symmetric_passphrase_dialog', true, array('symmetricid' => $symmetric_id)) . ' return false;') . _("You must enter the passphrase that was used to encrypt this message.") . '</a>';
+ if (!$resymmetric) {
+ $status[] = _("The message below has been encrypted with PGP.");
+ }
+ $status[] = Horde::link('#', '', null, null, IMP::passphraseDialogJS('PGPSymmetric', $js_action, array('symmetricid' => $symmetric_id)) . ';return false;') . _("You must enter the passphrase used to encrypt this message to view it.") . '</a>';
+ break;
+
+ case 'mimp':
+ $status[] = _("The message has been encrypted with PGP.");
+ break;
}
return null;
}
$personal_pass = $this->_imppgp->getPassphrase('personal');
if (is_null($personal_pass)) {
- if ($_SESSION['imp']['view'] == 'imp') {
- // TODO: Fix to work with DIMP
+ $js_action = '';
+
+ switch ($_SESSION['imp']['view']) {
+ case 'dimp':
+ $js_action = 'DimpCore.reloadMessage({});';
+ // Fall through
+
+ case 'imp':
/* Ask for the private key's passphrase if this is
* encrypted asymmetrically. */
- $status[] = Horde::link('#', _("The message below has been encrypted with PGP. You must enter the passphrase for your PGP private key before it can be decrypted."), null, null, $this->_imppgp->getJSOpenWinCode('open_passphrase_dialog') . ' return false;') . _("You must enter the passphrase for your PGP private key to view this message.") . '</a>';
+ $status[] = _("The message below has been encrypted with PGP.");
+ $status[] = Horde::link('#', '', null, null, IMP::passphraseDialogJS('PGPPersonal', $js_action) . ';return false;') . _("You must enter the passphrase for your PGP private key to view this message.") . '</a>';
+ break;
+
+ case 'mimp':
+ $status[] = _("The message has been encrypted with PGP.");
+ break;
}
return null;
}
if (is_a($decrypted_data, 'PEAR_Error')) {
$status[] = _("The message below does not appear to be a valid PGP encrypted message. Error: ") . $decrypted_data->getMessage();
+ if (!is_null($symmetric_pass)) {
+ $this->_imppgp->unsetPassphrase('symmetric', $this->_getSymmetricID());
+ return $this->_getEmbeddedMimeParts();
+ }
return null;
}
? self::$_inlinecache[$id]
: array();
}
+
+ /**
+ * Generates the symmetric ID for this message.
+ *
+ * @return string Symmetric ID.
+ */
+ protected function _getSymmetricID()
+ {
+ return $this->_imppgp->getSymmetricID($this->_params['contents']->getMailbox(), $this->_params['contents']->getIndex(), $this->_mimepart->getMimeId());
+ }
}
_textWindowOutput('PGP Key Information', empty($key_info) ? _("Invalid key") : $key_info);
}
-function _outputPassphraseDialog($secure_check, $symmetricid = null)
-{
- if (is_a($secure_check, 'PEAR_Error')) {
- $GLOBALS['notification']->push($secure_check, 'horde.warning');
- }
-
- $title = _("PGP Passphrase Input");
- require IMP_TEMPLATES . '/common-header.inc';
- IMP::status();
-
- if (is_a($secure_check, 'PEAR_Error')) {
- return;
- }
-
- $t = new IMP_Template();
- $t->setOption('gettext', true);
- $t->set('symmetricid', $symmetricid);
- $t->set('submit_url', Util::addParameter(Horde::applicationUrl('pgp.php'), 'actionID', $symmetricid ? 'process_symmetric_passphrase_dialog' : 'process_passphrase_dialog'));
- $t->set('reload', htmlspecialchars(Util::getFormData('reload')));
- $t->set('action', Util::getFormData('passphrase_action'));
- $t->set('locked_img', Horde::img('locked.png', _("PGP"), null, $GLOBALS['registry']->getImageDir('horde')));
- echo $t->fetch(IMP_TEMPLATES . '/pgp/passphrase.html');
-}
-
function _importKeyDialog($target)
{
$title = _("Import PGP Key");
}
exit;
-case 'open_passphrase_dialog':
- if ($imp_pgp->getPassphrase('personal')) {
- Util::closeWindowJS();
- } else {
- _outputPassphraseDialog($secure_check);
- }
- exit;
-
-case 'open_symmetric_passphrase_dialog':
- $symmetricid = Util::getFormData('symmetricid');
- if ($imp_pgp->getPassphrase('symmetric', $symmetricid)) {
- Util::closeWindowJS();
- } else {
- _outputPassphraseDialog($secure_check, $symmetricid);
- }
- exit;
-
-case 'process_passphrase_dialog':
-case 'process_symmetric_passphrase_dialog':
- $symmetric = $actionID == 'process_symmetric_passphrase_dialog';
- $symmetricid = Util::getFormData('symmetricid');
- $passphrase = Util::getFormData('passphrase');
- if (is_a($secure_check, 'PEAR_Error')) {
- _outputPassphraseDialog($secure_check, $symmetricid);
- } elseif ($passphrase) {
- $success = $imp_pgp->storePassphrase($symmetric ? 'symmetric' : 'personal', $passphrase, $symmetricid);
-
- if ($success) {
- if (Util::getFormData('passphrase_action')) {
- $oid = Util::getFormData('passphrase_action');
- $cacheSess = &Horde_SessionObjects::singleton();
- $cacheSess->setPruneFlag($oid, true);
- Util::closeWindowJS($cacheSess->query($oid));
- } elseif (Util::getFormData('reload')) {
- Util::closeWindowJS('opener.focus();opener.location.href="' . Util::getFormData('reload') . '";');
- } else {
- Util::closeWindowJS();
- }
- } else {
- $notification->push("Invalid passphrase entered.", 'horde.error');
- _outputPassphraseDialog($secure_check, $symmetricid);
- }
- } else {
- $notification->push("No passphrase entered.", 'horde.error');
- _outputPassphraseDialog($secure_check, $symmetricid);
- }
- exit;
-
case 'unset_passphrase':
$imp_pgp->unsetPassphrase('personal');
$notification->push(_("Passphrase successfully unloaded."), 'horde.success');
$t->set('sendkey', Horde::link(Util::addParameter($selfURL, 'actionID', 'send_public_key'), _("Send Key to Public Keyserver")));
$t->set('personalkey-public-help', Help::link('imp', 'pgp-personalkey-public'));
$passphrase = $imp_pgp->getPassphrase('personal');
- $t->set('passphrase', (empty($passphrase)) ? Horde::link('#', _("Enter Passphrase"), null, null, htmlspecialchars($imp_pgp->getJSOpenWinCode('open_passphrase_dialog')) . ' return false;') . _("Enter Passphrase") : Horde::link(Util::addParameter($selfURL, 'actionID', 'unset_passphrase'), _("Unload Passphrase")) . _("Unload Passphrase"));
+ $t->set('passphrase', (empty($passphrase)) ? Horde::link('#', _("Enter Passphrase"), null, null, IMP::passphraseDialogJS('PGPPersonal') . ';return false;') . _("Enter Passphrase") : Horde::link(Util::addParameter($selfURL, 'actionID', 'unset_passphrase'), _("Unload Passphrase")) . _("Unload Passphrase"));
$t->set('viewprivate', Horde::link(Util::addParameter($selfURL, 'actionID', 'view_personal_private_key'), _("View Personal Private Key"), null, 'view_key'));
$t->set('infoprivate', Horde::link(Util::addParameter($selfURL, 'actionID', 'info_personal_private_key'), _("Information on Personal Private Key"), null, 'info_key'));
$t->set('personalkey-private-help', Help::link('imp', 'pgp-personalkey-private'));
+++ /dev/null
-<form method="post" name="passphrase_dialog" action="<tag:submit_url />">
-<if:reload>
-<input type="hidden" name="reload" value="<tag:reload />" />
-</if:reload>
-<if:action>
-<input type="hidden" name="passphrase_action" value="<tag:action />" />
-</if:action>
-<if:symmetricid>
-<input type="hidden" name="symmetricid" value="<tag:symmetricid />" />
-</if:symmetricid>
-
-<div class="header">
- <tag:locked_img />
- <if:symmetricid>
- <gettext>Please enter the passphrase for this message. You will only need to enter this passphrase once per session.</gettext>
- <else:symmetricid>
- <gettext>Please enter the passphrase for your PGP private key. You will only need to enter this passphrase once per session.</gettext>
- </else:symmetricid></if:symmetricid>
-</div>
-
-<div class="nowrap padded">
- <label for="passphrase"><strong><gettext>Passphrase:</gettext></strong></label>
- <input type="password" id="passphrase" name="passphrase" size="15" maxlength="60" />
- <input type="submit" name="submit" class="button" value="<gettext>Submit</gettext>" />
- <input type="button" class="button" onclick="window.close();" value="<gettext>Cancel</gettext>" />
-</div>
-
-</form>
-
-<script type="text/javascript">
-document.passphrase_dialog.passphrase.focus();
-</script>