Merge branch 'sched' of boxacle.net:/var/www/cave-man.org/htdocs/projects/davical into sched

This commit is contained in:
Rob Ostensen 2012-01-16 14:49:11 -06:00
commit e1e357d342

View File

@ -1,4 +1,4 @@
<?PHP <?php
/** /**
* Functions that are needed for iScheduling requests * Functions that are needed for iScheduling requests
* *
@ -24,322 +24,379 @@ require_once("XMLDocument.php");
*/ */
class iSchedule class iSchedule
{ {
public $parsed; public $parsed;
public $selector; public $selector;
public $domain; public $domain;
private $dk; private $dk;
private $DKSig; private $DKSig;
private $try_anyway = false; private $try_anyway = false;
private $failed = false; private $failed = false;
private $failOnError = true; private $failOnError = true;
private $subdomainsOK = true; private $subdomainsOK = true;
private $remote_public_key ; private $remote_public_key ;
function __construct ( ) function __construct ( )
{ {
$this->selector = 'cal'; $this->selector = 'cal';
if ( is_object ( $c ) && isset ( $c->scheduling_dkim_selector ) ) if ( is_object ( $c ) && isset ( $c->scheduling_dkim_selector ) )
$this->scheduling_dkim_selector = $c->scheduling_dkim_selector ; $this->scheduling_dkim_selector = $c->scheduling_dkim_selector ;
} }
/** /**
* gets the domainkey TXT record from DNS * gets the domainkey TXT record from DNS
*/ */
function getTxt () function getTxt ()
{ {
// TODO handle parents of subdomains and procuration records // TODO handle parents of subdomains and procuration records
$dkim = dns_get_record ( $this->remote_selector . '._domainkey.' . $this->remote_server , DNS_TXT ); $dkim = dns_get_record ( $this->remote_selector . '._domainkey.' . $this->remote_server , DNS_TXT );
if ( count ( $dkim ) > 0 ) if ( count ( $dkim ) > 0 )
$this->dk = $dkim [ 0 ] [ 'txt' ]; $this->dk = $dkim [ 0 ] [ 'txt' ];
else else
{ {
$this->failed = true; $this->failed = true;
return false; return false;
} }
return true; return true;
} }
/** /**
* parses DNS TXT record from domainkey lookup * parses DNS TXT record from domainkey lookup
*/ */
function parseTxt ( ) function parseTxt ( )
{ {
if ( $this->failed == true ) if ( $this->failed == true )
return false; return false;
$clean = preg_replace ( '/[\s\t]*([;=])[\s\t]*/', '$1', $this->dk ); $clean = preg_replace ( '/[\s\t]*([;=])[\s\t]*/', '$1', $this->dk );
$pairs = preg_split ( '/;/', $clean ); $pairs = preg_split ( '/;/', $clean );
$this->parsed = array(); $this->parsed = array();
foreach ( $pairs as $v ) foreach ( $pairs as $v )
{ {
list($key,$value) = preg_split ( '/=/', $v, 2 ); list($key,$value) = preg_split ( '/=/', $v, 2 );
if ( preg_match ( '/(g|k|n|p|s|t|v)/', $key ) ) if ( preg_match ( '/(g|k|n|p|s|t|v)/', $key ) )
$this->parsed [ $key ] = $value; $this->parsed [ $key ] = $value;
else else
$this->parsed_ignored [ $key ] = $value; $this->parsed_ignored [ $key ] = $value;
} }
return true; return true;
} }
/** /**
* validates that domainkey is acceptable for the current request * validates that domainkey is acceptable for the current request
*/ */
function validateKey ( ) function validateKey ( )
{ {
$this->failed = true; $this->failed = true;
if ( isset ( $this->parsed [ 's' ] ) ) if ( isset ( $this->parsed [ 's' ] ) )
{ {
if ( ! preg_match ( '/(\*|calendar)/', $this->parsed [ 's' ] ) ) if ( ! preg_match ( '/(\*|calendar)/', $this->parsed [ 's' ] ) )
return 'foo'; return false; // not a wildcard or calendar key
} }
if ( isset ( $this->parsed [ 'k' ] ) && $this->parsed [ 'k' ] != 'rsa' ) if ( isset ( $this->parsed [ 'k' ] ) && $this->parsed [ 'k' ] != 'rsa' )
return false; return false; // we only speak rsa for now
if ( isset ( $this->parsed [ 't' ] ) && ! preg_match ( '/^[y:s]+$/', $this->parsed [ 't' ] ) ) if ( isset ( $this->parsed [ 't' ] ) && ! preg_match ( '/^[y:s]+$/', $this->parsed [ 't' ] ) )
return false; return false;
else else
{ {
if ( preg_match ( '/y/', $this->parsed [ 't' ] ) ) if ( preg_match ( '/y/', $this->parsed [ 't' ] ) )
$this->failOnError = false; $this->failOnError = false;
if ( preg_match ( '/s/', $this->parsed [ 't' ] ) ) if ( preg_match ( '/s/', $this->parsed [ 't' ] ) )
$this->subdomainsOK = false; $this->subdomainsOK = false;
} }
if ( isset ( $this->parsed [ 'g' ] ) ) if ( isset ( $this->parsed [ 'g' ] ) )
$this->remote_user_rule = $this->parsed [ 'g' ]; $this->remote_user_rule = $this->parsed [ 'g' ];
if ( isset ( $this->parsed [ 'p' ] ) ) else
{ $this->remote_user_rule = '*';
$data = "-----BEGIN PUBLIC KEY-----\n" . implode ("\n",str_split ( preg_replace ( '/_/', '', $this->parsed [ 'p' ] ), 64 )) . "\n-----END PUBLIC KEY-----"; if ( isset ( $this->parsed [ 'p' ] ) )
if ( $data === false ) {
return false; $data = "-----BEGIN PUBLIC KEY-----\n" . implode ("\n",str_split ( preg_replace ( '/_/', '', $this->parsed [ 'p' ] ), 64 )) . "\n-----END PUBLIC KEY-----";
$this->remote_public_key = $data; if ( $data === false )
} return false;
else $this->remote_public_key = $data;
return false; }
$this->failed = false; else
return true; return false;
} $this->failed = false;
return true;
}
/** /**
* finds a remote calendar server via DNS SRV records * finds a remote calendar server via DNS SRV records
*/ */
function getServer ( ) function getServer ( )
{ {
$this->remote_ssl = false; $this->remote_ssl = false;
$r = dns_get_record ( '_ischedules._tcp.' . $this->domain , DNS_SRV ); $r = dns_get_record ( '_ischedules._tcp.' . $this->domain , DNS_SRV );
if ( 0 < count ( $r ) ) if ( 0 < count ( $r ) )
{ {
$remote_server = $r [ 0 ] [ 'target' ]; $remote_server = $r [ 0 ] [ 'target' ];
$remote_port = $r [ 0 ] [ 'port' ]; $remote_port = $r [ 0 ] [ 'port' ];
$this->remote_ssl = true; $this->remote_ssl = true;
} }
if ( ! isset ( $remote_server ) ) if ( ! isset ( $remote_server ) )
{ {
$r = dns_get_record ( '_ischedule._tcp.' . $this->domain , DNS_SRV ); $r = dns_get_record ( '_ischedule._tcp.' . $this->domain , DNS_SRV );
if ( 0 < count ( $r ) ) if ( 0 < count ( $r ) )
{ {
$remote_server = $r [ 0 ] [ 'target' ]; $remote_server = $r [ 0 ] [ 'target' ];
$remote_port = $r [ 0 ] [ 'port' ]; $remote_port = $r [ 0 ] [ 'port' ];
} }
} }
elseif ( $this->try_anyway == true ) elseif ( $this->try_anyway == true )
{ {
if ( ! isset ( $remote_server ) ) if ( ! isset ( $remote_server ) )
$remote_server = $this->domain; $remote_server = $this->domain;
if ( ! isset ( $remote_port ) ) if ( ! isset ( $remote_port ) )
$remote_port = 80; $remote_port = 80;
} }
if ( ! isset ( $remote_server ) ) if ( ! isset ( $remote_server ) )
return false; return false;
$this->remote_server = $remote_server; $this->remote_server = $remote_server;
$this->remote_port = $remote_port; $this->remote_port = $remote_port;
} }
/** /**
* get capabilities from remote server * get capabilities from remote server
*/ */
function getCapabilities ( ) function getCapabilities ( )
{ {
$remote_capabilities = file_get_contents ( 'http'. ( $this->remote_ssl ? 's' : '' ) . '://' . $remote_capabilities = file_get_contents ( 'http'. ( $this->remote_ssl ? 's' : '' ) . '://' .
$this->remote_server . ':' . $this->remote_port . $this->remote_server . ':' . $this->remote_port .
'/.well-known/ischedule?query=capabilities' ); '/.well-known/ischedule?query=capabilities' );
$xmltree = BuildXMLTree( $request->xml_tags, $position); if ( $remote_capabilities === false )
if ( !is_object($xmltree) ) { return false;
$request->DoResponse( 406, translate("REPORT body is not valid XML data!") ); $xml_parser = xml_parser_create_ns('UTF-8');
} $this->xml_tags = array();
} xml_parser_set_option ( $xml_parser, XML_OPTION_SKIP_WHITE, 1 );
xml_parser_set_option ( $xml_parser, XML_OPTION_CASE_FOLDING, 0 );
$rc = xml_parse_into_struct( $xml_parser, $remote_capabilities, $this->xml_tags );
if ( $rc == false ) {
dbg_error_log( 'ERROR', 'XML parsing error: %s at line %d, column %d',
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser), xml_get_current_column_number($xml_parser) );
return false;
}
xml_parser_free($xml_parser);
$xmltree = BuildXMLTree( $this->xml_tags );
if ( !is_object($xmltree) ) {
$request->DoResponse( 406, translate("REPORT body is not valid XML data!") );
return false;
}
$this->capbilities_xml = $xmltree;
return true;
}
/** /**
* signs a POST body and headers * signs a POST body and headers
* *
* @param string $body the body of the POST * @param string $body the body of the POST
* @param array $headers the headers to sign as passed to header (); * @param array $headers the headers to sign as passed to header ();
*/ */
function signDKIM ( $body, $headers ) function signDKIM ( $body, $headers )
{ {
$b = ''; $b = '';
if ( ! is_array ( $headers ) ) if ( ! is_array ( $headers ) )
return false; return false;
foreach ( $headers as $v ) foreach ( $headers as $value )
$b .= $v . "\n"; {
$dk['s'] = $this->selector; $b .= $value . "\n";
$dk['d'] = $this->domain; }
$dk['c'] = 'simple-http'; $h = implode ( ':', array_keys ( $headers ) );
$dk['q'] = 'dns/txt'; $dk['s'] = $this->selector;
$dk['bh'] = base64_encode ( hash ( 'sha256', $body , true ) ); $dk['d'] = $this->domain;
//a=rsa-sha1; d=caveman.name; s=cal; c=simple-http; q=dns/txt; h=Originator:Recipient:Host:Content-Type; b $dk['c'] = 'simple-http';
// XXX finish me $dk['i'] = '@' . $_SERVER['SERVER_NAME']; //optional
} $dk['q'] = 'dns/txt';
$dk['l'] = strlen ( $body ); //optional
$dk['bh'] = base64_encode ( hash ( 'sha256', $body , true ) );
//a=rsa-sha1; d=caveman.name; s=cal; c=simple-http; q=dns/txt; h=Originator:Recipient:Host:Content-Type; b
// XXX finish me
$value = 'DKIM-Signature: ';
foreach ( $dk as $key => $val )
$value = "$value$key=$val; ";
$value = $value . 'b=';
$value .= base64_encode ( hash ( 'sha256', $b . $value, true ) ) ;
header ( $value );
}
/**
* send request to remote server
*/
function sendRequest ( $address, $type, $data )
{
$this->domain = $address;
if ( ! $this->getServer ( ) )
{
$request->DoResponse( 403, translate('Server not found') );
return false;
}
if ( ! $this->getCapabilities ( ) )
{
$request->DoResponse( 403, translate('Server not found') );
return false;
}
// find names on 'urn:ietf:params:xml:ns:ischedule::supported-scheduling-message-set' comp name='vevent' method name='request'
}
/** /**
* parses and validates DK header * parses and validates DK header
* *
* @param string $sig the value of the DKIM-Signature header * @param string $sig the value of the DKIM-Signature header
*/ */
function parseDKIM ( $sig ) function parseDKIM ( $sig )
{ {
$this->failed = true; $this->failed = true;
$tags = preg_split ( '/;[\s\t]/', $sig ); $tags = preg_split ( '/;[\s\t]/', $sig );
foreach ( $tags as $v ) foreach ( $tags as $v )
{ {
list($key,$value) = preg_split ( '/=/', $v, 2 ); list($key,$value) = preg_split ( '/=/', $v, 2 );
$dkim[$key] = $value; $dkim[$key] = $value;
} }
// the canonicalization method is currently undefined as of draft-01 of the iSchedule spec // the canonicalization method is currently undefined as of draft-01 of the iSchedule spec
// but it does define the value, it should be simple-http. RFC4871 also defines two methods // but it does define the value, it should be simple-http. RFC4871 also defines two methods
// simple and relaxed, simple is probably the same as simple http // simple and relaxed, simple is probably the same as simple http
// relaxed allows for header case folding and whitespace folding, see section 3.4.4 or RFC4871 // relaxed allows for header case folding and whitespace folding, see section 3.4.4 or RFC4871
if ( ! preg_match ( '{(simple|simple-http|relaxed)(/(simple|simple-http|relaxed))?}', $dkim['c'], $matches ) ) // canonicalization method if ( ! preg_match ( '{(simple|simple-http|relaxed)(/(simple|simple-http|relaxed))?}', $dkim['c'], $matches ) ) // canonicalization method
return 'bad canonicalization:' . $dkim['c'] ; return 'bad canonicalization:' . $dkim['c'] ;
if ( count ( $matches ) > 2 ) if ( count ( $matches ) > 2 )
$this->body_cannon = $matches[2]; $this->body_cannon = $matches[2];
else else
$this->body_cannon = $matches[1]; $this->body_cannon = $matches[1];
$this->header_cannon = $matches[1]; $this->header_cannon = $matches[1];
// signing algorythm REQUIRED // signing algorythm REQUIRED
if ( $dkim['a'] != 'rsa-sha1' && $dkim['a'] != 'rsa-sha256' ) if ( $dkim['a'] != 'rsa-sha1' && $dkim['a'] != 'rsa-sha256' )
return 'bad signing algorythm:' . $dkim['a'] ; return 'bad signing algorythm:' . $dkim['a'] ;
// query method to retrieve public key, could/should we add https to the spec? REQUIRED // query method to retrieve public key, could/should we add https to the spec? REQUIRED
if ( $dkim['q'] != 'dns/txt' ) if ( $dkim['q'] != 'dns/txt' )
return 'bad query method'; return 'bad query method';
// domain of the signing entity REQUIRED // domain of the signing entity REQUIRED
if ( ! isset ( $dkim['d'] ) ) if ( ! isset ( $dkim['d'] ) )
return 'missing signing domain'; return 'missing signing domain';
$this->remote_server = $dkim['d']; $this->remote_server = $dkim['d'];
// identity of signing agent, OPTIONAL // identity of signing agent, OPTIONAL
if ( isset ( $dkim['i'] ) ) if ( isset ( $dkim['i'] ) )
// if present, domain of the signing agent must be a match or a subdomain of the signing domain // if present, domain of the signing agent must be a match or a subdomain of the signing domain
if ( ! stristr ( $dkim['i'], $dkim['d'] ) ) // RFC4871 does not specify a case match requirement if ( ! stristr ( $dkim['i'], $dkim['d'] ) ) // RFC4871 does not specify a case match requirement
return 'signing domain mismatch'; return 'signing domain mismatch';
// grab the local part of the signing agent if it's an email address // grab the local part of the signing agent if it's an email address
if ( strstr ( $dkim [ 'i' ], '@' ) ) if ( strstr ( $dkim [ 'i' ], '@' ) )
$this->remote_user = substr ( $dkim [ 'i' ], 0, strpos ( $dkim [ 'i' ], '@' ) - 1 ); $this->remote_user = substr ( $dkim [ 'i' ], 0, strpos ( $dkim [ 'i' ], '@' ) - 1 );
// selector used to retrieve public key REQUIRED // selector used to retrieve public key REQUIRED
if ( ! isset ( $dkim['s'] ) ) if ( ! isset ( $dkim['s'] ) )
return 'missing selector'; return 'missing selector';
$this->remote_selector = $dkim['s']; $this->remote_selector = $dkim['s'];
// signed header fields, colon seperated REQUIRED // signed header fields, colon seperated REQUIRED
if ( ! isset ( $dkim['h'] ) ) if ( ! isset ( $dkim['h'] ) )
return 'missing list of signed headers'; return 'missing list of signed headers';
$this->signed_headers = preg_split ( '/:/', $dkim['h'] ); $this->signed_headers = preg_split ( '/:/', $dkim['h'] );
foreach ( $this->signed_headers as $h ) foreach ( $this->signed_headers as $h )
// signed header fields MUST actually be present in the request // signed header fields MUST actually be present in the request
// DKIM Signature is NOT allowed in signed header fields per RFC4871 // DKIM Signature is NOT allowed in signed header fields per RFC4871
if ( ( ! isset ( $_SERVER['HTTP_' . strtr ( strtoupper ( $h ), '-', '_' ) ] ) && if ( ( ! isset ( $_SERVER['HTTP_' . strtr ( strtoupper ( $h ), '-', '_' ) ] ) &&
! isset ( $_SERVER[ strtr ( strtoupper ( $h ), '-', '_' ) ] ) ) ! isset ( $_SERVER[ strtr ( strtoupper ( $h ), '-', '_' ) ] ) )
|| strtolower ( $h ) == 'dkim-signature' ) || strtolower ( $h ) == 'dkim-signature' )
return "header $h is signed but missing from request"; return "header $h is signed but missing from request";
// body hash REQUIRED // body hash REQUIRED
if ( ! isset ( $dkim['bh'] ) ) if ( ! isset ( $dkim['bh'] ) )
return 'missing body signature'; return 'missing body signature';
// signed header hash REQUIRED // signed header hash REQUIRED
if ( ! isset ( $dkim['b'] ) ) if ( ! isset ( $dkim['b'] ) )
return 'missing signature in b field'; return 'missing signature in b field';
// length of body used for signing // length of body used for signing
if ( isset ( $dkim['l'] ) ) if ( isset ( $dkim['l'] ) )
$this->signed_length = $dkim['l']; $this->signed_length = $dkim['l'];
$this->failed = false; $this->failed = false;
$this->DKSig = $dkim; $this->DKSig = $dkim;
return true; return true;
} }
/** /**
* split up a mailto uri into domain and user components * split up a mailto uri into domain and user components
*/ */
function parseURI ( $uri ) function parseURI ( $uri )
{ {
if ( preg_match ( '/^mailto:([^@]+)@([^\s\t\n]+)/', $uri, $matches ) ) if ( preg_match ( '/^mailto:([^@]+)@([^\s\t\n]+)/', $uri, $matches ) )
{ {
$this->remote_user = $matches[1]; $this->remote_user = $matches[1];
$this->domain = $matches[2]; $this->domain = $matches[2];
} }
else else
return false; return false;
} }
/** /**
* verifies parsed DKIM header is valid for current message with a signature from the public key in DNS * verifies parsed DKIM header is valid for current message with a signature from the public key in DNS
*/ */
function verifySignature ( ) function verifySignature ( )
{ {
global $request,$c; global $request,$c;
$this->failed = true; $this->failed = true;
$signed = ''; $signed = '';
foreach ( $this->signed_headers as $h ) foreach ( $this->signed_headers as $h )
if ( isset ( $_SERVER['HTTP_' . strtoupper ( strtr ( $h, '-', '_' ) ) ] ) ) if ( isset ( $_SERVER['HTTP_' . strtoupper ( strtr ( $h, '-', '_' ) ) ] ) )
$signed .= "$h: " . $_SERVER['HTTP_' . strtoupper ( strtr ( $h, '-', '_' ) ) ] . "\n"; $signed .= "$h: " . $_SERVER['HTTP_' . strtoupper ( strtr ( $h, '-', '_' ) ) ] . "\n";
else else
$signed .= "$h: " . $_SERVER[ strtoupper ( strtr ( $h, '-', '_' ) ) ] . "\n"; $signed .= "$h: " . $_SERVER[ strtoupper ( strtr ( $h, '-', '_' ) ) ] . "\n";
$body = $request->raw_post; if ( ! isset ( $_SERVER['HTTP_ORIGINATOR'] ) || stripos ( $signed, 'Originator' ) !== false ) //required header, must be signed
if ( ! isset ( $this->signed_length ) ) return false;
$this->signed_length = strlen ( $body ); if ( ! isset ( $_SERVER['HTTP_RECIPIENT'] ) || stripos ( $signed, 'Recipient' ) !== false ) //required header, must be signed
else return false;
$body = substr ( $body, 0, $this->signed_length ); if ( ! isset ( $_SERVER['HTTP_ISCHEDULE_VERSION'] ) || $_SERVER['HTTP_ISCHEDULE_VERSION'] != '1' ) //required header and we only speak version 1 for now
if ( isset ( $this->remote_user_rule ) ) return false;
if ( $this->remote_user_rule != '*' && ! stristr ( $this->remote_user, $this->remote_user_rule ) ) $body = $request->raw_post;
return false; if ( ! isset ( $this->signed_length ) )
$body_hash = base64_encode ( hash ( preg_replace ( '/^.*(sha[1256]+).*/','$1', $this->DKSig['a'] ), $body , true ) ); $this->signed_length = strlen ( $body );
if ( $this->DKSig['bh'] != $body_hash ) else
return false; $body = substr ( $body, 0, $this->signed_length );
$sig = $_SERVER['HTTP_DKIM_SIGNATURE']; if ( isset ( $this->remote_user_rule ) )
$sig = preg_replace ( '/ b=[^;\s\n\t]+/', ' b=', $sig ); if ( $this->remote_user_rule != '*' && ! stristr ( $this->remote_user, $this->remote_user_rule ) )
$sig = preg_replace ( '/[\r\n]*$/', '', $sig ); return false;
$signed .= 'DKIM-Signature: ' . $sig; $body_hash = base64_encode ( hash ( preg_replace ( '/^.*(sha[1256]+).*/','$1', $this->DKSig['a'] ), $body , true ) );
$verify = openssl_verify ( $signed, base64_decode ( $this->DKSig['b'] ), $this->remote_public_key ); if ( $this->DKSig['bh'] != $body_hash )
if ( $verify != 1 ) return false;
return false; $sig = $_SERVER['HTTP_DKIM_SIGNATURE'];
$this->failed = false; $sig = preg_replace ( '/ b=[^;\s\n\t]+/', ' b=', $sig );
return true; $sig = preg_replace ( '/[\r\n]*$/', '', $sig );
} $signed .= 'DKIM-Signature: ' . $sig;
$verify = openssl_verify ( $signed, base64_decode ( $this->DKSig['b'] ), $this->remote_public_key );
if ( $verify != 1 )
return false;
$this->failed = false;
return true;
}
/** /**
* checks that current request has a valid DKIM signature signed by a currently valid key from DNS * checks that current request has a valid DKIM signature signed by a currently valid key from DNS
*/ */
function validateRequest ( ) function validateRequest ( )
{ {
global $request; global $request;
if ( isset ( $_SERVER['HTTP_DKIM_SIGNATURE'] ) ) if ( isset ( $_SERVER['HTTP_DKIM_SIGNATURE'] ) )
$sig = $_SERVER['HTTP_DKIM_SIGNATURE']; $sig = $_SERVER['HTTP_DKIM_SIGNATURE'];
else else
$request->DoResponse( 403, translate('DKIM signature missing') ); {
$request->DoResponse( 403, translate('DKIM signature missing') );
return false;
}
$err = $this->parseDKIM ( $sig ); $err = $this->parseDKIM ( $sig );
if ( $err !== true || $this->failed ) if ( $err !== true || $this->failed )
$request->DoResponse( 403, translate('DKIM signature invalid ' ) . "\n" . $err . "\n" . $sig ); $request->DoResponse( 403, translate('DKIM signature invalid ' ) . "\n" . $err . "\n" . $sig );
if ( ! $this->getTxt () || $this->failed ) if ( ! $this->getTxt () || $this->failed )
$request->DoResponse( 403, translate('DKIM signature validation failed(DNS ERROR)') ); $request->DoResponse( 403, translate('DKIM signature validation failed(DNS ERROR)') );
if ( ! $this->parseTxt () || $this->failed ) if ( ! $this->parseTxt () || $this->failed )
$request->DoResponse( 403, translate('DKIM signature validation failed(KEY Parse ERROR)') ); $request->DoResponse( 403, translate('DKIM signature validation failed(KEY Parse ERROR)') );
if ( ! $this->validateKey () || $this->failed ) if ( ! $this->validateKey () || $this->failed )
$request->DoResponse( 403, translate('DKIM signature validation failed(KEY Validation ERROR)') ); $request->DoResponse( 403, translate('DKIM signature validation failed(KEY Validation ERROR)') );
if ( ! $this->verifySignature () || $this->failed ) if ( ! $this->verifySignature () || $this->failed )
$request->DoResponse( 403, translate('DKIM signature validation failed(Signature verification ERROR)') . $this->verifySignature() ); $request->DoResponse( 403, translate('DKIM signature validation failed(Signature verification ERROR)') . $this->verifySignature() );
return true; return true;
} }
} }
$d = new iSchedule (); $d = new iSchedule ();
if ( $d->validateRequest ( ) ) if ( $d->validateRequest ( ) )
{ {
include ( 'caldav-POST.php' ); //include ( 'caldav-POST.php' );
// @todo handle request. // @todo handle request.
} }