mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-28 01:29:05 +01:00
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;
|
namespace EGroupware\Api\Mail;
|
||||||
|
|
||||||
use EGroupware\Api;
|
use EGroupware\Api;
|
||||||
use Horde_Crypt_Exception;
|
|
||||||
use Horde_Crypt_Translation;
|
|
||||||
use Horde_Crypt_Smime;
|
use Horde_Crypt_Smime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,13 +21,6 @@ use Horde_Crypt_Smime;
|
|||||||
class Smime extends Horde_Crypt_Smime
|
class Smime extends Horde_Crypt_Smime
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* openssl binary path
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $sslpath;
|
|
||||||
|
|
||||||
static $SMIME_TYPES = array (
|
static $SMIME_TYPES = array (
|
||||||
'application/pkcs8',
|
'application/pkcs8',
|
||||||
'application/pkcs7',
|
'application/pkcs7',
|
||||||
@ -37,7 +28,9 @@ class Smime extends Horde_Crypt_Smime
|
|||||||
'application/pkcs8',
|
'application/pkcs8',
|
||||||
'multipart/signed',
|
'multipart/signed',
|
||||||
'application/x-pkcs7-signature',
|
'application/x-pkcs7-signature',
|
||||||
'application/x-pkcs7-mime'
|
'application/x-pkcs7-mime',
|
||||||
|
'application/pkcs7-mime',
|
||||||
|
'application/pkcs7-signature',
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -47,8 +40,6 @@ class Smime extends Horde_Crypt_Smime
|
|||||||
public function __construct($params = array())
|
public function __construct($params = array())
|
||||||
{
|
{
|
||||||
parent::__construct($params);
|
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;
|
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'];
|
if (empty($rowsFetched['messages'])) $rowsFetched['messages'] = $rowsFetched['rowsFetched'];
|
||||||
|
|
||||||
//error_log(__METHOD__.__LINE__.' Rows fetched:'.$rowsFetched.' Data:'.array2string($sortResult));
|
//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]);
|
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);
|
$rows = $mail_ui->header2gridelements($sortResult['header'],$cols, $_folderName, $folderType=$toSchema);
|
||||||
//error_log(__METHOD__.__LINE__.array2string($rows));
|
//error_log(__METHOD__.__LINE__.array2string($rows));
|
||||||
@ -1878,6 +1878,16 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
|||||||
{
|
{
|
||||||
$data["bodypreview"] = $header['bodypreview'];
|
$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;
|
$rv[] = $data;
|
||||||
//error_log(__METHOD__.__LINE__.array2string($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
|
// we do NOT want to see those, that are embedded in the list of attachments
|
||||||
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
if ($htmlOptions !='always_display') $fetchEmbeddedImages = true;
|
||||||
$attachments = $this->mail_bo->getMessageAttachments($uid, $partID, null, $fetchEmbeddedImages,true,true,$mailbox);
|
$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));
|
//error_log(__METHOD__.__LINE__.array2string($attachments));
|
||||||
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
|
$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);
|
$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
|
* Build actions for display toolbar
|
||||||
*/
|
*/
|
||||||
@ -2500,6 +2567,15 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
|||||||
}
|
}
|
||||||
//Import failed, download content anyway
|
//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));
|
//error_log(__METHOD__.__LINE__.'->'.array2string($attachment));
|
||||||
$filename = ($attachment['name']?$attachment['name']:($attachment['filename']?$attachment['filename']:$mailbox.'_uid'.$uid.'_part'.$part));
|
$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%">
|
<hbox class="mailDisplayHeaders" align="right" width="30%">
|
||||||
<description value="Date"/>
|
<description value="Date"/>
|
||||||
<date-time id="mail_displaydate" readonly="true"/>
|
<date-time id="mail_displaydate" readonly="true"/>
|
||||||
|
<buttononly id="smimeSigBtn" image="smimeSignature" onclick="app.mail.smimeSigBtn"/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
<column width="30%"/>
|
<column width="30%"/>
|
||||||
<column width="30%"/>
|
<column width="30%"/>
|
||||||
<column width="80"/>
|
<column width="80"/>
|
||||||
|
<column width="80"/>
|
||||||
</columns>
|
</columns>
|
||||||
<rows>
|
<rows>
|
||||||
<row class="th">
|
<row class="th">
|
||||||
@ -96,6 +97,7 @@
|
|||||||
<nextmatch-sortheader label="to" id="toaddress"/>
|
<nextmatch-sortheader label="to" id="toaddress"/>
|
||||||
<nextmatch-sortheader label="from" id="fromaddress"/>
|
<nextmatch-sortheader label="from" id="fromaddress"/>
|
||||||
<nextmatch-sortheader align="center" label="size" id="size"/>
|
<nextmatch-sortheader align="center" label="size" id="size"/>
|
||||||
|
<nextmatch-header statustext="security" label="Security" id="security"/>
|
||||||
</row>
|
</row>
|
||||||
<row class="$row_cont[class]">
|
<row class="$row_cont[class]">
|
||||||
<description span="1" class="status_img"/>
|
<description span="1" class="status_img"/>
|
||||||
@ -110,6 +112,9 @@
|
|||||||
<url-email id="${row}[toaddress]" contact_plus = "true" readonly="true"/>
|
<url-email id="${row}[toaddress]" contact_plus = "true" readonly="true"/>
|
||||||
<url-email id="${row}[fromaddress]" 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"/>
|
<vfs-size align="right" id="${row}[size]" no_lang="1" readonly="true"/>
|
||||||
|
<vbox>
|
||||||
|
<buttononly id="smimeSigBtn" image="smimeSignature" disabled="!@$row_cont[smimeSigUrl]"/>
|
||||||
|
</vbox>
|
||||||
</row>
|
</row>
|
||||||
</rows>
|
</rows>
|
||||||
</grid>
|
</grid>
|
||||||
|
Loading…
Reference in New Issue
Block a user