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
* *
@ -89,10 +89,10 @@ class iSchedule
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
@ -104,6 +104,8 @@ class iSchedule
} }
if ( isset ( $this->parsed [ 'g' ] ) ) if ( isset ( $this->parsed [ 'g' ] ) )
$this->remote_user_rule = $this->parsed [ 'g' ]; $this->remote_user_rule = $this->parsed [ 'g' ];
else
$this->remote_user_rule = '*';
if ( isset ( $this->parsed [ 'p' ] ) ) if ( isset ( $this->parsed [ 'p' ] ) )
{ {
$data = "-----BEGIN PUBLIC KEY-----\n" . implode ("\n",str_split ( preg_replace ( '/_/', '', $this->parsed [ 'p' ] ), 64 )) . "\n-----END PUBLIC KEY-----"; $data = "-----BEGIN PUBLIC KEY-----\n" . implode ("\n",str_split ( preg_replace ( '/_/', '', $this->parsed [ 'p' ] ), 64 )) . "\n-----END PUBLIC KEY-----";
@ -160,13 +162,29 @@ class iSchedule
$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 )
return false;
$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) ) { if ( !is_object($xmltree) ) {
$request->DoResponse( 406, translate("REPORT body is not valid XML data!") ); $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
* *
@ -178,15 +196,45 @@ class iSchedule
$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"; {
$b .= $value . "\n";
}
$h = implode ( ':', array_keys ( $headers ) );
$dk['s'] = $this->selector; $dk['s'] = $this->selector;
$dk['d'] = $this->domain; $dk['d'] = $this->domain;
$dk['c'] = 'simple-http'; $dk['c'] = 'simple-http';
$dk['i'] = '@' . $_SERVER['SERVER_NAME']; //optional
$dk['q'] = 'dns/txt'; $dk['q'] = 'dns/txt';
$dk['l'] = strlen ( $body ); //optional
$dk['bh'] = base64_encode ( hash ( 'sha256', $body , true ) ); $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 //a=rsa-sha1; d=caveman.name; s=cal; c=simple-http; q=dns/txt; h=Originator:Recipient:Host:Content-Type; b
// XXX finish me // 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'
} }
/** /**
@ -289,6 +337,12 @@ class iSchedule
$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";
if ( ! isset ( $_SERVER['HTTP_ORIGINATOR'] ) || stripos ( $signed, 'Originator' ) !== false ) //required header, must be signed
return false;
if ( ! isset ( $_SERVER['HTTP_RECIPIENT'] ) || stripos ( $signed, 'Recipient' ) !== false ) //required header, must be signed
return false;
if ( ! isset ( $_SERVER['HTTP_ISCHEDULE_VERSION'] ) || $_SERVER['HTTP_ISCHEDULE_VERSION'] != '1' ) //required header and we only speak version 1 for now
return false;
$body = $request->raw_post; $body = $request->raw_post;
if ( ! isset ( $this->signed_length ) ) if ( ! isset ( $this->signed_length ) )
$this->signed_length = strlen ( $body ); $this->signed_length = strlen ( $body );
@ -320,7 +374,10 @@ class iSchedule
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 )
@ -340,6 +397,6 @@ class iSchedule
$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.
} }