include/lib/swiftmailer/classes/Swift/Signers/OpenDKIMSigner.php
<?php
/*
* This file is part of SwiftMailer.
* (c) 2004-2009 Chris Corbyn
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* DKIM Signer used to apply DKIM Signature to a message
* Takes advantage of pecl extension
*
* @package Swift
* @subpackage Signatures
* @author Xavier De Cock <xdecock@gmail.com>
*/
class Swift_Signers_OpenDKIMSigner extends Swift_Signers_DKIMSigner
{
private $_peclLoaded = false;
private $_dkimHandler = null;
private $dropFirstLF = true;
const CANON_RELAXED = 1;
const CANON_SIMPLE = 2;
const SIG_RSA_SHA1 = 3;
const SIG_RSA_SHA256 = 4;
public function __construct($privateKey, $domainName, $selector)
{
if (extension_loaded('opendkim')) {
$this->_peclLoaded = true;
} else {
throw new Swift_SwiftException('php-opendkim extension not found');
}
parent::__construct($privateKey, $domainName, $selector);
}
public static function newInstance($privateKey, $domainName, $selector)
{
return new static($privateKey, $domainName, $selector);
}
public function addSignature(Swift_Mime_HeaderSet $headers)
{
$header = new Swift_Mime_Headers_OpenDKIMHeader('DKIM-Signature');
$headerVal=$this->_dkimHandler->getSignatureHeader();
if (!$headerVal) {
throw new Swift_SwiftException('OpenDKIM Error: '.$this->_dkimHandler->getError());
}
$header->setValue($headerVal);
$headers->set($header);
return $this;
}
public function setHeaders(Swift_Mime_HeaderSet $headers)
{
$bodyLen = $this->_bodyLen;
if (is_bool($bodyLen)) {
$bodyLen = - 1;
}
$hash = ($this->_hashAlgorithm == 'rsa-sha1') ? OpenDKIMSign::ALG_RSASHA1 : OpenDKIMSign::ALG_RSASHA256;
$bodyCanon = ($this->_bodyCanon == 'simple') ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED;
$headerCanon = ($this->_headerCanon == 'simple') ? OpenDKIMSign::CANON_SIMPLE : OpenDKIMSign::CANON_RELAXED;
$this->_dkimHandler = new OpenDKIMSign($this->_privateKey, $this->_selector, $this->_domainName, $headerCanon, $bodyCanon, $hash, $bodyLen);
// Hardcode signature Margin for now
$this->_dkimHandler->setMargin(78);
if (!is_numeric($this->_signatureTimestamp)) {
OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, time());
} else {
if (!OpenDKIM::setOption(OpenDKIM::OPTS_FIXEDTIME, $this->_signatureTimestamp)) {
throw new Swift_SwiftException('Unable to force signature timestamp ['.openssl_error_string().']');
}
}
if (isset($this->_signerIdentity)) {
$this->_dkimHandler->setSigner($this->_signerIdentity);
}
$listHeaders = $headers->listAll();
foreach ($listHeaders as $hName) {
// Check if we need to ignore Header
if (! isset($this->_ignoredHeaders[strtolower($hName)])) {
$tmp = $headers->getAll($hName);
if ($headers->has($hName)) {
foreach ($tmp as $header) {
if ($header->getFieldBody() != '') {
$htosign = $header->toString();
$this->_dkimHandler->header($htosign);
$this->_signedHeaders[] = $header->getFieldName();
}
}
}
}
}
return $this;
}
public function startBody()
{
if (! $this->_peclLoaded) {
return parent::startBody();
}
$this->dropFirstLF = true;
$this->_dkimHandler->eoh();
return $this;
}
public function endBody()
{
if (! $this->_peclLoaded) {
return parent::endBody();
}
$this->_dkimHandler->eom();
return $this;
}
public function reset()
{
$this->_dkimHandler = null;
parent::reset();
return $this;
}
/**
* Set the signature timestamp
*
* @param timestamp $time
* @return Swift_Signers_DKIMSigner
*/
public function setSignatureTimestamp($time)
{
$this->_signatureTimestamp = $time;
return $this;
}
/**
* Set the signature expiration timestamp
*
* @param timestamp $time
* @return Swift_Signers_DKIMSigner
*/
public function setSignatureExpiration($time)
{
$this->_signatureExpiration = $time;
return $this;
}
/**
* Enable / disable the DebugHeaders
*
* @param boolean $debug
* @return Swift_Signers_DKIMSigner
*/
public function setDebugHeaders($debug)
{
$this->_debugHeaders = (bool) $debug;
return $this;
}
// Protected
protected function _canonicalizeBody($string)
{
if (! $this->_peclLoaded) {
return parent::_canonicalizeBody($string);
}
if (false && $this->dropFirstLF === true) {
if ($string[0]=="\r" && $string[1]=="\n") {
$string=substr($string, 2);
}
}
$this->dropFirstLF = false;
if (strlen($string)) {
$this->_dkimHandler->body($string);
}
}
}