From: martinlanghoff Date: Thu, 4 Jan 2007 03:36:24 +0000 (+0000) Subject: mnet/xmlrpc/client & parser: Diff time between servers and break if it's X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=f0e4c2701ce7edfd9aa5c7d9b9988781c81ecb53;p=moodle.git mnet/xmlrpc/client & parser: Diff time between servers and break if it's too large Author: Donal McMullan --- diff --git a/mnet/xmlrpc/client.php b/mnet/xmlrpc/client.php index 245d3a9cb2..85079177c8 100644 --- a/mnet/xmlrpc/client.php +++ b/mnet/xmlrpc/client.php @@ -174,9 +174,13 @@ class mnet_xmlrpc_client { curl_setopt($ch, CURLOPT_POSTFIELDS, $rq); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8")); + $timestamp_send = time(); $this->rawresponse = curl_exec($ch); + $timestamp_receive = time(); + if ($this->rawresponse == false) { $this->error[] = array(curl_errno($ch), curl_error($ch)); + return false; } $crypt_parser = new mnet_encxml_parser(); @@ -211,6 +215,32 @@ class mnet_xmlrpc_client { return false; } + // Margin of error is the time it took the request to complete. + $margin_of_error = $timestamp_receive - $timestamp_send; + + // Guess the time gap between sending the request and the remote machine + // executing the time() function. Marginally better than nothing. + $hysteresis = ($margin_of_error) / 2; + + $remote_timestamp = $sig_parser->remote_timestamp - $hysteresis; + $time_offset = $remote_timestamp - $timestamp_send; + if ($time_offset > 0) { + $result = get_field('config_plugins', 'value', 'plugin', 'mnet', 'name', 'drift_threshold'); + if(empty($result)) { + // We decided 15 seconds was a pretty good arbitrary threshold + // for time-drift between servers, but you can customize this in + // the config_plugins table. It's not advised though. + set_config('drift_threshold', 15, 'mnet'); + $threshold = 15; + } else { + $threshold = $result; + } + if ($time_offset > $threshold) { + $this->error[] = 'Time gap with '.$mnet_peer->name.' ('.$time_offset.' seconds) is greater than the permitted maximum of '.$threshold.' seconds'; + return false; + } + } + $this->xmlrpcresponse = base64_decode($sig_parser->data_object); $this->response = xmlrpc_decode($this->xmlrpcresponse); curl_close($ch); diff --git a/mnet/xmlrpc/xmlparser.php b/mnet/xmlrpc/xmlparser.php index 97069b5d40..af958d2f8a 100644 --- a/mnet/xmlrpc/xmlparser.php +++ b/mnet/xmlrpc/xmlparser.php @@ -35,6 +35,7 @@ class mnet_encxml_parser { $this->tag_number = 0; // Just a unique ID for each tag $this->digest = ''; + $this->remote_timestamp = ''; $this->remote_wwwroot = ''; $this->signature = ''; $this->data_object = ''; @@ -130,6 +131,9 @@ class mnet_encxml_parser { case 'RETRIEVALMETHOD': $this->key_URI = $attrs['URI']; break; + case 'TIMESTAMP': + $handler = 'parse_timestamp'; + break; case 'WWWROOT': $handler = 'parse_wwwroot'; break; @@ -144,6 +148,18 @@ class mnet_encxml_parser { return true; } + /** + * Add the next chunk of character data to the remote_timestamp string + * + * @param mixed $parser The XML parser + * @param string $data The content of the current tag (1024 byte chunk) + * @return bool True + */ + function parse_timestamp($parser, $data) { + $this->remote_timestamp .= $data; + return true; + } + /** * Add the next chunk of character data to the cipher string for that tag *