function fetch_remote_list($base_url) { global $request; $result = array(); $list_url = $base_url . '?action=list'; printf("Fetching timezone list\n", $list_url); $raw_xml = file_get_contents($list_url); $xml_parser = xml_parser_create_ns('UTF-8'); $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, $raw_xml, $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)); $request->PreconditionFailed(400, 'invalid-xml', sprintf('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))); } xml_parser_free($xml_parser); $position = 0; return BuildXMLTree($xml_tags, $position); }
* @copyright Morphoss Ltd - http://www.morphoss.com/ * @license http://gnu.org/copyleft/gpl.html GNU GPL v2 or later */ dbg_error_log('MKTICKET', 'method handler'); require_once 'DAVResource.php'; $request->NeedPrivilege('DAV::bind'); require_once 'XMLDocument.php'; $reply = new XMLDocument(array('DAV:' => '', 'http://www.xythos.com/namespaces/StorageServer' => 'T')); $target = new DAVResource($request->path); if (!$target->Exists()) { $request->XMLResponse(404, new XMLElement('error', new XMLElement('resource-must-not-be-null'), $reply->GetXmlNsArray())); } if (!isset($request->xml_tags)) { $request->XMLResponse(400, new XMLElement('error', new XMLElement('missing-xml-for-request'), $reply->GetXmlNsArray())); } $xmltree = BuildXMLTree($request->xml_tags, $position); if ($xmltree->GetTag() != 'http://www.xythos.com/namespaces/StorageServer:ticketinfo' && $xmltree->GetTag() != 'DAV::ticketinfo') { $request->XMLResponse(400, new XMLElement('error', new XMLElement('invalid-xml-for-request'), $reply->GetXmlNsArray())); } $ticket_timeout = 'Seconds-3600'; $ticket_privs_array = array('read-free-busy'); foreach ($xmltree->GetContent() as $k => $v) { // <!ELEMENT ticketinfo (id?, owner?, timeout, visits, privilege)> switch ($v->GetTag()) { case 'DAV::timeout': case 'http://www.xythos.com/namespaces/StorageServer:timeout': $ticket_timeout = $v->GetContent(); break; case 'DAV::privilege': case 'http://www.xythos.com/namespaces/StorageServer:privilege': $ticket_privs_array = $v->GetElements();
/** * send request to remote server * $address should be an email address or an array of email addresses all with the same domain * $type should be in the format COMPONENT/METHOD eg (VFREEBUSY, VEVENT/REQUEST, VEVENT/REPLY, etc. ) * $data is the vcalendar data N.B. must already be rendered into text format */ function sendRequest($address, $type, $data) { global $session; if (empty($this->scheduling_dkim_domain)) { return false; } if (is_array($address)) { list($user, $domain) = explode('@', $address[0]); } else { list($user, $domain) = explode('@', $address); } if (!$this->getCapabilities($domain)) { dbg_error_log('ischedule', $domain . ' did not have iSchedule capabilities for ' . $type); return false; } dbg_error_log('ischedule', $domain . ' trying with iSchedule capabilities for ' . $type); if ($this->queryCapabilities($type)) { dbg_error_log('ischedule', $domain . ' trying with iSchedule capabilities for ' . $type . ' OK'); list($component, $method) = explode('/', $type); $headers = array(); $headers['iSchedule-Version'] = '1.0'; $headers['Originator'] = 'mailto:' . $session->email; if (is_array($address)) { $headers['Recipient'] = implode(', ', $address); } else { $headers['Recipient'] = $address; } $headers['Content-Type'] = 'text/calendar; component=' . $component; if ($method) { $headers['Content-Type'] .= '; method=' . $method; } $headers['DKIM-Signature'] = $this->signDKIM($headers, $body); if ($headers['DKIM-Signature'] == false) { return false; } $request_headers = array(); foreach ($headers as $k => $v) { $request_headers[] = $k . ': ' . $v; } $curl = curl_init($this->remote_url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array()); // start with no headers set curl_setopt($curl, CURLOPT_HTTPHEADER, $request_headers); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); $xmlresponse = curl_exec($curl); $info = curl_getinfo($curl); curl_close($curl); if ($info['http_code'] >= 400) { dbg_error_log('ischedule', 'remote server returned error (%s)', $info['http_code']); return false; } error_log('remote response ' . $xmlresponse . print_r($info, true)); $xml_parser = xml_parser_create_ns('UTF-8'); $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, $xmlresponse, $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; } $xmltree = BuildXMLTree($xml_tags); xml_parser_free($xml_parser); if (!is_object($xmltree)) { dbg_error_log('ERROR', 'iSchedule RESPONSE body is not valid XML data!'); return false; } $resp = $xmltree->GetPath('/*/urn:ietf:params:xml:ns:ischedule:response'); $result = array(); foreach ($resp as $r) { $recipient = $r->GetElements('urn:ietf:params:xml:ns:ischedule:recipient'); $status = $r->GetElements('urn:ietf:params:xml:ns:ischedule:request-status'); $calendardata = $r->GetElements('urn:ietf:params:xml:ns:ischedule:calendar-data'); if (count($recipient) < 1) { continue; } // this should be an error if (count($calendardata) > 0) { $result[$recipient[0]->GetContent()] = $calendardata[0]->GetContent(); } else { $result[$recipient[0]->GetContent()] = $status[0]->GetContent(); } } if (count($result) < 1) { return false; } else { return $result; } } else { return false; } }
/** * Rebuild an XML tree in our own style from the parsed XML tags using * a tail-recursive approach. * * @param array $xmltags An array of XML tags we get from using the PHP XML parser * @param intref &$start_from A pointer to our current integer offset into $xmltags * @return mixed Either a single XMLElement, or an array of XMLElement objects. */ function BuildXMLTree($xmltags, &$start_from) { $content = array(); if (!isset($start_from)) { $start_from = 0; } for ($i = 0; $i < 50000 && isset($xmltags[$start_from]); $i++) { $tagdata = $xmltags[$start_from++]; if (!isset($tagdata) || !isset($tagdata['tag']) || !isset($tagdata['type'])) { break; } if ($tagdata['type'] == "close") { break; } $attributes = isset($tagdata['attributes']) ? $tagdata['attributes'] : false; if ($tagdata['type'] == "open") { $subtree = BuildXMLTree($xmltags, $start_from); $content[] = new XMLElement($tagdata['tag'], $subtree, $attributes); } else { if ($tagdata['type'] == "complete") { $value = isset($tagdata['value']) ? $tagdata['value'] : false; $content[] = new XMLElement($tagdata['tag'], $value, $attributes); } } } /** * If there is only one element, return it directly, otherwise return the * array of them */ if (count($content) == 1) { return $content[0]; } return $content; }
/** * get capabilities from remote server */ function getCapabilities() { $remote_capabilities = file_get_contents('http' . ($this->remote_ssl ? 's' : '') . '://' . $this->remote_server . ':' . $this->remote_port . '/.well-known/ischedule?query=capabilities'); $xmltree = BuildXMLTree($request->xml_tags, $position); if (!is_object($xmltree)) { $request->DoResponse(406, translate("REPORT body is not valid XML data!")); } }
public static function BuildDeadPropertyXML($property_name, $raw_string) { if (!preg_match('{^\\s*<.*>\\s*$}s', $raw_string)) { return $raw_string; } $xmlns = null; if (preg_match('{^(.*):([^:]+)$}', $property_name, $matches)) { $xmlns = $matches[1]; $property_name = $matches[2]; } $xml = sprintf('<%s%s>%s</%s>', $property_name, isset($xmlns) ? ' xmlns="' . $xmlns . '"' : '', $raw_string, $property_name); $xml_parser = xml_parser_create_ns('UTF-8'); $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, $xml, $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)); dbg_error_log('ERROR', "Error occurred in:\n%s\n", $xml); return $raw_string; } xml_parser_free($xml_parser); $position = 0; $xmltree = BuildXMLTree($xml_tags, $position); return $xmltree->GetContent(); }