diff --git a/api/templates/default/password.xet b/api/templates/default/password.xet
new file mode 100644
index 0000000000..6a26757a20
--- /dev/null
+++ b/api/templates/default/password.xet
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mail/inc/class.mail_compose.inc.php b/mail/inc/class.mail_compose.inc.php
index 1d2aefcda0..832ecaa3f3 100644
--- a/mail/inc/class.mail_compose.inc.php
+++ b/mail/inc/class.mail_compose.inc.php
@@ -212,13 +212,21 @@ class mail_compose
'onExecute' => 'javaScript:app.mail.compose_saveDraft2fm',
'hint' => 'Save the drafted message as eml file into VFS'
),
- 'sign' => array (
+ 'smime_sign' => array (
'caption' => 'Sign',
'icon' => 'smimeSignature',
'group' => ++$group,
'onExecute' => 'javaScript:app.mail.compose_setToggle',
'checkbox' => true,
'hint' => 'Sign your message with smime certificate'
+ ),
+ 'smime_encrypt' => array (
+ 'caption' => 'SMIME',
+ 'icon' => 'smimeEncryption',
+ 'group' => ++$group,
+ 'onExecute' => 'javaScript:app.mail.compose_setToggle',
+ 'checkbox' => true,
+ 'hint' => 'Encrypt your message with smime certificate'
)
);
foreach (self::$priorities as $key => $priority)
@@ -2346,61 +2354,60 @@ class mail_compose
*/
if ($_formData['attachments'] && $_formData['filemode'] != Vfs\Sharing::ATTACH && !$_autosaving)
{
- $attachment_links = $this->getAttachmentLinks($_formData['attachments'], $_formData['filemode'],
+ $attachment_links = $this->_getAttachmentLinks($_formData['attachments'], $_formData['filemode'],
$_formData['mimeType'] == 'html',
array_unique(array_merge((array)$_formData['to'], (array)$_formData['cc'], (array)$_formData['bcc'])),
$_formData['expiration'], $_formData['password']);
}
- if($_formData['mimeType'] == 'html')
+ switch ($_formData['mimeType'])
{
- $body = $_formData['body'];
- if ($attachment_links)
- {
- if (strpos($body, '') !== false)
+ case 'html':
+ $body = $_formData['body'];
+ if ($attachment_links)
{
- $body = str_replace('', $attachment_links.'', $body);
+ if (strpos($body, '') !== false)
+ {
+ $body = str_replace('', $attachment_links.'', $body);
+ }
+ else
+ {
+ $body .= $attachment_links;
+ }
+ }
+ if(!empty($signature))
+ {
+ $_mailObject->setBody($this->convertHTMLToText($body, true, true).
+ ($disableRuler ? "\r\n" : "\r\n-- \r\n").
+ $this->convertHTMLToText($signature, true, true));
+
+ $body .= ($disableRuler ?'
':'
').$signature;
}
else
{
- $body .= $attachment_links;
+ $_mailObject->setBody($this->convertHTMLToText($body, true, true));
}
- }
- if(!empty($signature))
- {
- $_mailObject->setBody($this->convertHTMLToText($body, true, true).
- ($disableRuler ? "\r\n" : "\r\n-- \r\n").
- $this->convertHTMLToText($signature, true, true));
+ // convert URL Images to inline images - if possible
+ if (!$_autosaving) $inline_images = Mail::processURL2InlineImages($_mailObject, $body, $mail_bo);
+ if (strpos($body,"")!==false)
+ {
+ $body = str_replace(array('',''),'',$body);
+ }
+ $_mailObject->setHtmlBody($body, null, false); // false = no automatic alternative, we called setBody()
+ break;
+ case 'openpgp':
+ $_mailObject->setOpenPgpBody($_formData['body']);
+ break;
+ default:
+ $body = $this->convertHTMLToText($_formData['body'],false);
- $body .= ($disableRuler ?'
':'
').$signature;
- }
- else
- {
- $_mailObject->setBody($this->convertHTMLToText($body, true, true));
- }
- // convert URL Images to inline images - if possible
- if (!$_autosaving) $inline_images = Mail::processURL2InlineImages($_mailObject, $body, $mail_bo);
- if (strpos($body,"")!==false)
- {
- $body = str_replace(array('',''),'',$body);
- }
- $_mailObject->setHtmlBody($body, null, false); // false = no automatic alternative, we called setBody()
- }
- elseif ($_formData['mimeType'] == 'openpgp')
- {
- $_mailObject->setOpenPgpBody($_formData['body']);
- }
- else
- {
- $body = $this->convertHTMLToText($_formData['body'],false);
+ if ($attachment_links) $body .= $attachment_links;
- if ($attachment_links) $body .= $attachment_links;
-
- #$_mailObject->Body = $_formData['body'];
- if(!empty($signature)) {
- $body .= ($disableRuler ?"\r\n":"\r\n-- \r\n").
- $this->convertHTMLToText($signature,true,true);
- }
- $_mailObject->setBody($body);
+ #$_mailObject->Body = $_formData['body'];
+ if(!empty($signature)) {
+ $body .= ($disableRuler ?"\r\n":"\r\n-- \r\n").
+ $this->convertHTMLToText($signature,true,true);
+ }
+ $_mailObject->setBody($body);
}
//error_log(__METHOD__.__LINE__.array2string($_formData['attachments']));
// add the attachments
@@ -2499,7 +2506,7 @@ class mail_compose
* @param string $password =null
* @return string might be empty if no file attachments found
*/
- protected function getAttachmentLinks(array $attachments, $filemode, $html, $recipients=array(), $expiration=null, $password=null)
+ protected function _getAttachmentLinks(array $attachments, $filemode, $html, $recipients=array(), $expiration=null, $password=null)
{
if ($filemode == Vfs\Sharing::ATTACH) return '';
@@ -2783,6 +2790,8 @@ class mail_compose
$this->sessionData['to_infolog'] = $_formData['to_infolog'];
$this->sessionData['to_tracker'] = $_formData['to_tracker'];
$this->sessionData['attachments'] = $_formData['attachments'];
+ $this->sessionData['smime_sign'] = $_formData['smime_sign'];
+ $this->sessionData['smime_encrypt'] = $_formData['smime_encrypt'];
if (isset($_formData['lastDrafted']) && !empty($_formData['lastDrafted']))
{
@@ -2966,6 +2975,43 @@ class mail_compose
#error_log($this->errorInfo);
return false;
}
+ // SMIME SIGN/ENCRYPTION
+ if ($_formData['smime_sign'] == 'on' || $_formData['smime_encrypt'] == 'on' )
+ {
+ try {
+ if ($_formData['smime_sign'] == 'on')
+ {
+ $smime_part = $this->_encrypt(
+ '',//TODO
+ $_formData['smime_encrypt'] == 'on'? Mail\Smime::TYPE_SIGN_ENCRYPT: Mail\Smime::TYPE_SIGN,
+ $_formData['to'],
+ $identity['ident_email'],
+ $_formData['smime_passphrase']
+ );
+ if ($smime_part['smime_pass_require'])
+ {
+ $response = Api\Json\Response::get();
+ $response->call('app.mail.smimePassDialog');
+ return false;
+ }
+ }
+ elseif ($_formData['smime_sign'] == 'off' && $_formData['smime_encrypt'] == 'on')
+ {
+ $smime_part = $this->_encrypt(
+ '',//TODO
+ Mail\Smime::TYPE_ENCRYPT,
+ $_formData['to'],
+ $identity['ident_email']
+ );
+ }
+
+ //TODO Set signed or encrypted mime part
+ }
+ catch (Exception $ex)
+ {
+ throw new Api\Exception\WrongUserinput($ex->getMessage());
+ }
+ }
// set a higher timeout for big messages
@set_time_limit(120);
@@ -3581,30 +3627,35 @@ class mail_compose
* @return Horde_Mime_Part returns encrypted message
* @throws Api\Exception\WrongUserinput if no certificate found
*/
- function _encrypt(Horde_Mime_part $message, $type, $recipients, $sender)
+ protected function _encrypt(Horde_Mime_part $message, $type, $recipients, $sender, $passphrase='')
{
$AB = new addressbook_bo();
-
+ $smime = new Mail\Smime();
if (isset($sender) && ($type == Mail\Smime::TYPE_SIGN || $type == Mail\Smime::TYPE_SIGN_ENCRYPT))
{
$sender_cert = $AB->get_smime_keys($sender);
- $smime = new Mail\Smime();
if ($sender_cert)
{
- $senderPubKey = $smime->get_publickey($sender_cert[$sender]);
+ $senderPubKey = $sender_cert[$sender];
}
else
{
throw new Api\Exception\WrongUserinput('no certificate found to sign the messase');
}
+ $credents = Mail\Credentials::read($this->mail_bo->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
+ $privkey = $credents['acc_smime_password'];
+
+ if (!$smime->verifyPassphrase($privkey, $passphrase))
+ {
+ return array('smime_pass_require' => true);
+ }
}
if (isset($recipients) && ($type == Mail\Smime::TYPE_ENCRYPT || $type == Mail\Smime::TYPE_SIGN_ENCRYPT))
{
$recipients_certs = $AB->get_smime_keys($recipients);
- $recipientsPubKeys = array_Map(array ($smime, 'get_publickey'), $recipients_certs);
if (!$recipients_certs) throw new Api\Exception\WrongUserinput('no certificate found from the recipients to sign/encrypt the messase');
}
@@ -3612,15 +3663,15 @@ class mail_compose
$sign_params = array(
'type' => 'signature',
'pubkey' => $senderPubKey,
- 'prikey' => '',
- 'passphrase'=> '',
+ 'privkey' => $privkey,
+ 'passphrase'=> $passphrase,
'sigtype' => 'detach',
'certs' => ''
);
// parameters to pass on for encrypt mime part
$encrypt_params = array(
'type' => 'message',
- 'pubkey' => $recipientsPubKeys
+ 'pubkey' => $recipients_certs
);
switch ($type)
{
diff --git a/mail/js/app.js b/mail/js/app.js
index ea6e843a11..9ad31c4757 100644
--- a/mail/js/app.js
+++ b/mail/js/app.js
@@ -5528,5 +5528,33 @@ app.classes.mail = AppJS.extend(
url = this.et2.getArrayMgr("content").getEntry('smimeSigUrl');
}
window.egw.openPopup(url,'700','400');
+ },
+
+ /**
+ * smime password dialog
+ */
+ smimePassDialog: function ()
+ {
+ var self = this;
+ et2_createWidget("dialog",
+ {
+ callback: function(_button_id, _value)
+ {
+ if (_button_id && _value)
+ {
+ var pass = self.et2.getWidgetById('smime_passphrase');
+ pass.set_value(_value.value);
+ }
+ },
+ title: egw.lang('Request for passphrase'),
+ buttons: et2_dialog.BUTTONS_OK_CANCEL,
+ value:{
+ content:{
+ value: '',
+ message: self.egw.lang('Looks like your certificate is password protected. Please enter your passphrase and try to send again.')
+ }},
+ template: egw.webserverUrl+'/api/templates/default/password.xet',
+ resizable: false
+ }, et2_dialog._create_parent('mail'));
}
});
diff --git a/mail/templates/default/compose.xet b/mail/templates/default/compose.xet
index e422576cba..ae22e11031 100644
--- a/mail/templates/default/compose.xet
+++ b/mail/templates/default/compose.xet
@@ -12,6 +12,9 @@
+
+
+