forked from extern/egroupware
W.I.P of SMIME support for mail application:
- Resolve smime p7b attachment and translate it to PEM format - Assign a button to show the message is signed plus handler for showing the certificate - Fix Smime class to only use php openssl extension
This commit is contained in:
parent
845a1ec3e7
commit
a3562129b0
@ -13,8 +13,6 @@
|
||||
namespace EGroupware\Api\Mail;
|
||||
|
||||
use EGroupware\Api;
|
||||
use Horde_Crypt_Exception;
|
||||
use Horde_Crypt_Translation;
|
||||
use Horde_Crypt_Smime;
|
||||
|
||||
/**
|
||||
@ -23,13 +21,6 @@ use Horde_Crypt_Smime;
|
||||
class Smime extends Horde_Crypt_Smime
|
||||
{
|
||||
|
||||
/**
|
||||
* openssl binary path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sslpath;
|
||||
|
||||
static $SMIME_TYPES = array (
|
||||
'application/pkcs8',
|
||||
'application/pkcs7',
|
||||
@ -37,7 +28,9 @@ class Smime extends Horde_Crypt_Smime
|
||||
'application/pkcs8',
|
||||
'multipart/signed',
|
||||
'application/x-pkcs7-signature',
|
||||
'application/x-pkcs7-mime'
|
||||
'application/x-pkcs7-mime',
|
||||
'application/pkcs7-mime',
|
||||
'application/pkcs7-signature',
|
||||
);
|
||||
/**
|
||||
* Constructor.
|
||||
@ -47,8 +40,6 @@ class Smime extends Horde_Crypt_Smime
|
||||
public function __construct($params = array())
|
||||
{
|
||||
parent::__construct($params);
|
||||
$mailconfig = Api\Config::read('mail');
|
||||
$this->sslpath = $mailconfig['opensslpath']? $mailconfig['opensslpath']: '';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,41 +69,4 @@ class Smime extends Horde_Crypt_Smime
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Certificates from given PKCS7 data
|
||||
*
|
||||
* @param string $pkcs7
|
||||
* @return string returns
|
||||
* @throws Horde_Crypt_Exception
|
||||
*/
|
||||
public function extractCerticatesFromPKCS7 ($pkcs7)
|
||||
{
|
||||
$this->checkForOpenSSL();
|
||||
|
||||
// Create temp file for input
|
||||
$input = $this->_createTempFile('smime-pkcs7');
|
||||
$output = $this->_createTempFile('smime-pkcs7-out');
|
||||
/* Write text to file. */
|
||||
file_put_contents($input, $pkcs7);
|
||||
|
||||
exec($this->sslpath . ' pkcs7 -print_certs -inform der -in ' . $input . ' -outform PEM -out ' . $output);
|
||||
|
||||
$ret = file_get_contents($output);
|
||||
|
||||
if ($ret) return $ret;
|
||||
throw new Horde_Crypt_Exception(Horde_Crypt_Translation::t("OpenSSL error: Could not extract certificates from pkcs7 part."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the contents from signed S/MIME data.
|
||||
*
|
||||
* @param string $data The signed S/MIME data.
|
||||
*
|
||||
* @return string The contents embedded in the signed data.
|
||||
* @throws Horde_Crypt_Exception
|
||||
*/
|
||||
public function extractSignedContents ($data) {
|
||||
return parent::extractSignedContents($data, $this->sslpath);
|
||||
}
|
||||
}
|
||||
|
@ -1546,7 +1546,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
if (empty($rowsFetched['messages'])) $rowsFetched['messages'] = $rowsFetched['rowsFetched'];
|
||||
|
||||
//error_log(__METHOD__.__LINE__.' Rows fetched:'.$rowsFetched.' Data:'.array2string($sortResult));
|
||||
$cols = array('row_id','uid','status','attachments','subject','address','toaddress','fromaddress','ccaddress','additionaltoaddress','date','size','modified','bodypreview');
|
||||
$cols = array('row_id','uid','status','attachments','subject','address','toaddress','fromaddress','ccaddress','additionaltoaddress','date','size','modified','bodypreview', 'security');
|
||||
if ($GLOBALS['egw_info']['user']['preferences']['common']['select_mode']=='EGW_SELECTMODE_TOGGLE') unset($cols[0]);
|
||||
$rows = $mail_ui->header2gridelements($sortResult['header'],$cols, $_folderName, $folderType=$toSchema);
|
||||
//error_log(__METHOD__.__LINE__.array2string($rows));
|
||||
@ -1878,6 +1878,16 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
{
|
||||
$data["bodypreview"] = $header['bodypreview'];
|
||||
}
|
||||
if (is_array($data['attachmentsBlock']))
|
||||
{
|
||||
foreach ($data['attachmentsBlock'] as &$attch)
|
||||
{
|
||||
if (Mail\Smime::isSmime($attch['mimetype']))
|
||||
{
|
||||
$data['smimeSigUrl'] = $attch['mime_url'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$rv[] = $data;
|
||||
//error_log(__METHOD__.__LINE__.array2string($data));
|
||||
}
|
||||
@ -1996,6 +2006,22 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
// we do NOT want to see those, that are embedded in the list of attachments
|
||||
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
||||
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, null, $fetchEmbeddedImages,true,true,$mailbox);
|
||||
|
||||
$smimeData = $this->resolveSmimeAttachment ($attachments, $uid, $partID, $mailbox, $rowID);
|
||||
if (is_array($smimeData))
|
||||
{
|
||||
$error_msg[] = $smimeData['msg'];
|
||||
$linkData = array
|
||||
(
|
||||
'menuaction' => 'mail.mail_ui.getAttachment',
|
||||
'id' => $rowID,
|
||||
'part' => $smimeData['partID'],
|
||||
'is_winmail' => false,
|
||||
'mailbox' => base64_encode($mailbox)
|
||||
);
|
||||
$content['smimeSigUrl'] = Egw::link('/index.php',$linkData);
|
||||
}
|
||||
|
||||
//error_log(__METHOD__.__LINE__.array2string($attachments));
|
||||
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
|
||||
|
||||
@ -2065,6 +2091,47 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
$etpl->exec('mail.mail_ui.displayMessage',$content,$sel_options,$readonlys,$preserv,2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve certificate from smime attachment
|
||||
*
|
||||
* @param array &$attachments
|
||||
* @param int $_uid
|
||||
* @param int $_partID
|
||||
* @param string $_mailbox
|
||||
* @return array
|
||||
*/
|
||||
function resolveSmimeAttachment (&$attachments, $_uid, $_partID, $_mailbox)
|
||||
{
|
||||
$smime = new Mail\Smime;
|
||||
|
||||
foreach ($attachments as $key => $attachment)
|
||||
{
|
||||
if (Mail\Smime::isSmime($attachment['mimeType']))
|
||||
{
|
||||
$message = $this->mail_bo->getMessageRawBody($_uid,$_partID,$_mailbox);
|
||||
$cert = $smime->verify($message);
|
||||
$data = array (
|
||||
'verify' => $cert->verify,
|
||||
'cert' => $cert->cert,
|
||||
'msg' => $cert->msg,
|
||||
'certHtml' => $smime->certToHTML($cert->cert),
|
||||
'partID' => $attachment['partID']
|
||||
);
|
||||
unset ($attachments[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function getSmimeCert ()
|
||||
{
|
||||
if (isset($_GET['id'])) $id = $_GET['id'];
|
||||
if (isset($_GET['partID'])) $partID = $_GET['partid'];
|
||||
$cert = $this->resolveSmimeAttachment($attachments, $id, $partID, $mailbox);
|
||||
echo ($cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build actions for display toolbar
|
||||
*/
|
||||
@ -2500,6 +2567,15 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
}
|
||||
//Import failed, download content anyway
|
||||
}
|
||||
// Display smime certificate
|
||||
if (Mail\Smime::isSmime($attachment['type']))
|
||||
{
|
||||
$smimeAttachments = array ( array('mimeType' => $attachment['type'] ));
|
||||
$smime = $this->resolveSmimeAttachment($smimeAttachments, $uid, 0, $mailbox);
|
||||
Api\Header\Content::safe($smime['certHtml'], '', $attachment['type'], $size=0, false, true);
|
||||
echo $smime['certHtml'];
|
||||
exit();
|
||||
}
|
||||
}
|
||||
//error_log(__METHOD__.__LINE__.'->'.array2string($attachment));
|
||||
$filename = ($attachment['name']?$attachment['name']:($attachment['filename']?$attachment['filename']:$mailbox.'_uid'.$uid.'_part'.$part));
|
||||
|
@ -5504,5 +5504,18 @@ app.classes.mail = AppJS.extend(
|
||||
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Open smime certificate
|
||||
*
|
||||
* @param {type} egw
|
||||
* @param {type} widget
|
||||
* @returns {undefined}
|
||||
*/
|
||||
smimeSigBtn: function (egw, widget)
|
||||
{
|
||||
var url = this.et2.getArrayMgr("content").getEntry('smimeSigUrl');
|
||||
window.egw.openPopup(url,'700','400');
|
||||
}
|
||||
});
|
||||
|
@ -17,6 +17,7 @@
|
||||
<hbox class="mailDisplayHeaders" align="right" width="30%">
|
||||
<description value="Date"/>
|
||||
<date-time id="mail_displaydate" readonly="true"/>
|
||||
<buttononly id="smimeSigBtn" image="smimeSignature" onclick="app.mail.smimeSigBtn"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
||||
|
@ -84,6 +84,7 @@
|
||||
<column width="30%"/>
|
||||
<column width="30%"/>
|
||||
<column width="80"/>
|
||||
<column width="80"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
@ -96,6 +97,7 @@
|
||||
<nextmatch-sortheader label="to" id="toaddress"/>
|
||||
<nextmatch-sortheader label="from" id="fromaddress"/>
|
||||
<nextmatch-sortheader align="center" label="size" id="size"/>
|
||||
<nextmatch-header statustext="security" label="Security" id="security"/>
|
||||
</row>
|
||||
<row class="$row_cont[class]">
|
||||
<description span="1" class="status_img"/>
|
||||
@ -110,6 +112,9 @@
|
||||
<url-email id="${row}[toaddress]" contact_plus = "true" readonly="true"/>
|
||||
<url-email id="${row}[fromaddress]" contact_plus = "true" readonly="true"/>
|
||||
<vfs-size align="right" id="${row}[size]" no_lang="1" readonly="true"/>
|
||||
<vbox>
|
||||
<buttononly id="smimeSigBtn" image="smimeSignature" disabled="!@$row_cont[smimeSigUrl]"/>
|
||||
</vbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
Loading…
Reference in New Issue
Block a user