summaryrefslogtreecommitdiffstats
path: root/etc/inc/xmlrpc_client.inc
diff options
context:
space:
mode:
authorBill Marquette <billm@pfsense.org>2005-07-04 23:57:31 +0000
committerBill Marquette <billm@pfsense.org>2005-07-04 23:57:31 +0000
commit605938e5d037ba81982bfdd94e14000047901593 (patch)
tree2c30b8a35e904b985b903f4a6aadafca7464b8e1 /etc/inc/xmlrpc_client.inc
parent247c58ada314d1a5fb9938c95d856d32c6767892 (diff)
downloadpfsense-605938e5d037ba81982bfdd94e14000047901593.zip
pfsense-605938e5d037ba81982bfdd94e14000047901593.tar.gz
Import PEAR XMLRPC 1.3.1 - this includes the security fix for:
http://www.gulftech.org/?node=research&article_id=00088-07022005
Diffstat (limited to 'etc/inc/xmlrpc_client.inc')
-rw-r--r--etc/inc/xmlrpc_client.inc290
1 files changed, 191 insertions, 99 deletions
diff --git a/etc/inc/xmlrpc_client.inc b/etc/inc/xmlrpc_client.inc
index 10ed4ac..f33c8cd 100644
--- a/etc/inc/xmlrpc_client.inc
+++ b/etc/inc/xmlrpc_client.inc
@@ -1,4 +1,5 @@
<?php
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/* $Id$ */
@@ -31,28 +32,43 @@
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
* @author Daniel Convissor <danielc@php.net>
- * @copyright 1999-2001 Edd Dumbill
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
* @version CVS: $Id$
* @link http://pear.php.net/package/XML_RPC
*/
if (!function_exists('xml_parser_create')) {
- // Win 32 fix. From: "Leo West" <lwest@imaginet.fr>
- if ($WINDIR) {
- dl('php_xml.dll');
- } else {
- dl('xml.so');
- }
+ PEAR::loadExtension('xml');
}
/**#@+
* Error constants
*/
-define('XML_RPC_ERROR_INVALID_TYPE', 101);
-define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
-define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
+/**
+ * Parameter values don't match parameter types
+ */
+define('XML_RPC_ERROR_INVALID_TYPE', 101);
+/**
+ * Parameter declared to be numeric but the values are not
+ */
+define('XML_RPC_ERROR_NON_NUMERIC_FOUND', 102);
+/**
+ * Communication error
+ */
+define('XML_RPC_ERROR_CONNECTION_FAILED', 103);
+/**
+ * The array or struct has already been started
+ */
define('XML_RPC_ERROR_ALREADY_INITIALIZED', 104);
+/**
+ * Incorrect parameters submitted
+ */
+define('XML_RPC_ERROR_INCORRECT_PARAMS', 105);
+/**
+ * Programming error by developer
+ */
+define('XML_RPC_ERROR_PROGRAMMING', 106);
/**#@-*/
@@ -138,6 +154,7 @@ $GLOBALS['XML_RPC_err'] = array(
'incorrect_params' => 3,
'introspect_unknown' => 4,
'http_error' => 5,
+ 'not_response_object' => 6,
);
/**
@@ -150,6 +167,7 @@ $GLOBALS['XML_RPC_str'] = array(
'incorrect_params' => 'Incorrect parameters passed to method',
'introspect_unknown' => 'Can\'t introspect: method unknown',
'http_error' => 'Didn\'t receive 200 OK from remote server.',
+ 'not_response_object' => 'The requested method didn\'t return an XML_RPC_Response object.',
);
@@ -220,7 +238,7 @@ function XML_RPC_se($parser_resource, $name, $attrs)
break;
case 'NAME':
- $XML_RPC_xh[$parser]['st'] .= "'";
+ $XML_RPC_xh[$parser]['st'] .= '"';
$XML_RPC_xh[$parser]['ac'] = '';
break;
@@ -303,7 +321,7 @@ function XML_RPC_ee($parser_resource, $name)
break;
case 'NAME':
- $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . "' => ";
+ $XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'] . '" => ';
break;
case 'BOOLEAN':
@@ -328,8 +346,8 @@ function XML_RPC_ee($parser_resource, $name)
// we use double quotes rather than single so backslashification works OK
$XML_RPC_xh[$parser]['st'] .= '"' . $XML_RPC_xh[$parser]['ac'] . '"';
} elseif ($XML_RPC_xh[$parser]['qt'] == 2) {
- $XML_RPC_xh[$parser]['st'] .= "base64_decode('"
- . $XML_RPC_xh[$parser]['ac'] . "')";
+ $XML_RPC_xh[$parser]['st'] .= 'base64_decode("'
+ . $XML_RPC_xh[$parser]['ac'] . '")';
} elseif ($name == 'BOOLEAN') {
$XML_RPC_xh[$parser]['st'] .= $XML_RPC_xh[$parser]['ac'];
} else {
@@ -384,20 +402,10 @@ function XML_RPC_ee($parser_resource, $name)
break;
case 'METHODNAME':
+ case 'RPCMETHODNAME':
$XML_RPC_xh[$parser]['method'] = ereg_replace("^[\n\r\t ]+", '',
$XML_RPC_xh[$parser]['ac']);
break;
-
- case 'BOOLEAN':
- // special case here: we translate boolean 1 or 0 into PHP
- // constants true or false
- if ($XML_RPC_xh[$parser]['ac'] == '1') {
- $XML_RPC_xh[$parser]['ac'] = 'true';
- } else {
- $XML_RPC_xh[$parser]['ac'] = 'false';
- }
-
- $XML_RPC_xh[$parser]['vt'] = strtolower($name);
}
// if it's a valid type name, set the type
@@ -440,17 +448,16 @@ function XML_RPC_cd($parser_resource, $data)
}
/**
- * Base class
- *
- * This class provides common functions for all of the XML_RPC classes.
+ * The common methods and properties for all of the XML_RPC classes
*
* @category Web Services
* @package XML_RPC
* @author Edd Dumbill <edd@usefulinc.com>
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
- * @copyright 1999-2001 Edd Dumbill
- * @version Release: @package_version@
+ * @author Daniel Convissor <danielc@php.net>
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version Release: 1.3.1
* @link http://pear.php.net/package/XML_RPC
*/
class XML_RPC_Base {
@@ -486,7 +493,7 @@ class XML_RPC_Base {
}
/**
- *
+ * The methods and properties for submitting XML RPC requests
*
* @category Web Services
* @package XML_RPC
@@ -494,8 +501,8 @@ class XML_RPC_Base {
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
* @author Daniel Convissor <danielc@php.net>
- * @copyright 1999-2001 Edd Dumbill
- * @version Release: @package_version@
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version Release: 1.3.1
* @link http://pear.php.net/package/XML_RPC
*/
class XML_RPC_Client extends XML_RPC_Base {
@@ -594,6 +601,12 @@ class XML_RPC_Client extends XML_RPC_Base {
*/
var $debug = 0;
+ /**
+ * The HTTP headers for the current request.
+ * @var string
+ */
+ var $headers = '';
+
/**
* Sets the object's properties
@@ -730,6 +743,12 @@ class XML_RPC_Client extends XML_RPC_Base {
*/
function send($msg, $timeout = 0)
{
+ if (strtolower(get_class($msg)) != 'xml_rpc_message') {
+ $this->errstr = 'send()\'s $msg parameter must be an'
+ . ' XML_RPC_Message object.';
+ $this->raiseError($this->errstr, XML_RPC_ERROR_PROGRAMMING);
+ return 0;
+ }
$msg->debug = $this->debug;
return $this->sendPayloadHTTP10($msg, $this->server, $this->port,
$timeout, $this->username,
@@ -753,6 +772,7 @@ class XML_RPC_Client extends XML_RPC_Base {
* @return object an XML_RPC_Response object. 0 is returned if any
* problems happen.
*
+ * @access protected
* @see XML_RPC_Client::send()
*/
function sendPayloadHTTP10($msg, $server, $port, $timeout = 0,
@@ -808,60 +828,99 @@ class XML_RPC_Client extends XML_RPC_Base {
return 0;
}
+ if ($timeout) {
+ stream_set_timeout($fp, $timeout);
+ }
+
+ // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly
+ if ($username != $this->username) {
+ $this->setCredentials($username, $password);
+ }
+
// Only create the payload if it was not created previously
if (empty($msg->payload)) {
$msg->createPayload();
}
+ $this->createHeaders($msg);
- // thanks to Grant Rauscher <grant7@firstworld.net> for this
- $credentials = '';
- if ($username != '') {
- $credentials = 'Authorization: Basic ' .
- base64_encode($username . ':' . $password) . "\r\n";
+ $op = $this->headers . "\r\n\r\n";
+ $op .= $msg->payload;
+
+ if (!fputs($fp, $op, strlen($op))) {
+ $this->errstr = 'Write error';
+ return 0;
}
+ $resp = $msg->parseResponseFile($fp);
+
+ $meta = stream_get_meta_data($fp);
+ if ($meta['timed_out']) {
+ fclose($fp);
+ $this->errstr = 'RPC server did not send response before timeout.';
+ $this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
+ return 0;
+ }
+
+ fclose($fp);
+ return $resp;
+ }
+ /**
+ * Determines the HTTP headers and puts it in the $headers property
+ *
+ * @param object $msg the XML_RPC_Message object
+ *
+ * @return boolean TRUE if okay, FALSE if the message payload isn't set.
+ *
+ * @access protected
+ */
+ function createHeaders($msg)
+ {
+ if (empty($msg->payload)) {
+ return false;
+ }
if ($this->proxy) {
- $op = 'POST ' . $this->protocol . $server;
+ $this->headers = 'POST ' . $this->protocol . $this->server;
if ($this->proxy_port) {
- $op .= ':' . $this->port;
+ $this->headers .= ':' . $this->port;
}
} else {
- $op = 'POST ';
+ $this->headers = 'POST ';
}
-
- $op .= $this->path. " HTTP/1.0\r\n" .
- "User-Agent: PEAR XML_RPC\r\n" .
- 'Host: ' . $server . "\r\n";
- if ($this->proxy && $this->proxy_user != '') {
- $op .= 'Proxy-Authorization: Basic ' .
- base64_encode($this->proxy_user . ':' . $this->proxy_pass) .
- "\r\n";
+ $this->headers .= $this->path. " HTTP/1.0\r\n";
+
+ $this->headers .= "User-Agent: PEAR XML_RPC\r\n";
+ $this->headers .= 'Host: ' . $this->server . "\r\n";
+
+ if ($this->proxy && $this->proxy_user) {
+ $this->headers .= 'Proxy-Authorization: Basic '
+ . base64_encode("$this->proxy_user:$this->proxy_pass")
+ . "\r\n";
}
- $op .= $credentials .
- "Content-Type: text/xml\r\n" .
- 'Content-Length: ' . strlen($msg->payload) . "\r\n\r\n" .
- $msg->payload;
- if (!fputs($fp, $op, strlen($op))) {
- $this->errstr = 'Write error';
- return 0;
+ // thanks to Grant Rauscher <grant7@firstworld.net> for this
+ if ($this->username) {
+ $this->headers .= 'Authorization: Basic '
+ . base64_encode("$this->username:$this->password")
+ . "\r\n";
}
- $resp = $msg->parseResponseFile($fp);
- fclose($fp);
- return $resp;
+
+ $this->headers .= "Content-Type: text/xml\r\n";
+ $this->headers .= 'Content-Length: ' . strlen($msg->payload);
+ return true;
}
}
/**
- *
+ * The methods and properties for interpreting responses to XML RPC requests
*
* @category Web Services
* @package XML_RPC
* @author Edd Dumbill <edd@usefulinc.com>
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
- * @copyright 1999-2001 Edd Dumbill
- * @version Release: @package_version@
+ * @author Daniel Convissor <danielc@php.net>
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version Release: 1.3.1
* @link http://pear.php.net/package/XML_RPC
*/
class XML_RPC_Response extends XML_RPC_Base
@@ -943,7 +1002,7 @@ class XML_RPC_Response extends XML_RPC_Base
}
/**
- *
+ * The methods and properties for composing XML RPC messages
*
* @category Web Services
* @package XML_RPC
@@ -951,8 +1010,8 @@ class XML_RPC_Response extends XML_RPC_Base
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
* @author Daniel Convissor <danielc@php.net>
- * @copyright 1999-2001 Edd Dumbill
- * @version Release: @package_version@
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version Release: 1.3.1
* @link http://pear.php.net/package/XML_RPC
*/
class XML_RPC_Message extends XML_RPC_Base
@@ -1082,11 +1141,27 @@ class XML_RPC_Message extends XML_RPC_Base
}
/**
- * @return void
+ * Obtains an XML_RPC_Value object for the given parameter
+ *
+ * @param int $i the index number of the parameter to obtain
+ *
+ * @return object the XML_RPC_Value object.
+ * If the parameter doesn't exist, an XML_RPC_Response object.
+ *
+ * @since Returns XML_RPC_Response object on error since Release 1.3.0
*/
function getParam($i)
{
- return $this->params[$i];
+ global $XML_RPC_err, $XML_RPC_str;
+
+ if (isset($this->params[$i])) {
+ return $this->params[$i];
+ } else {
+ $this->raiseError('The submitted request did not contain this parameter',
+ XML_RPC_ERROR_INCORRECT_PARAMS);
+ return new XML_RPC_Response(0, $XML_RPC_err['incorrect_params'],
+ $XML_RPC_str['incorrect_params']);
+ }
}
/**
@@ -1191,10 +1266,12 @@ class XML_RPC_Message extends XML_RPC_Base
print "\n---END---\n</PRE>";
}
- // see if we got an HTTP 200 OK, else bomb
- // but only do this if we're using the HTTP protocol.
+ // See if response is a 200 or a 100 then a 200, else raise error.
+ // But only do this if we're using the HTTP protocol.
if (ereg('^HTTP', $data) &&
- !ereg('^HTTP/[0-9\.]+ 200 ', $data)) {
+ !ereg('^HTTP/[0-9\.]+ 200 ', $data) &&
+ !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Za-z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
+ {
$errstr = substr($data, 0, strpos($data, "\n") - 1);
error_log('HTTP error, got response: ' . $errstr);
$r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
@@ -1206,7 +1283,7 @@ class XML_RPC_Message extends XML_RPC_Base
// gotta get rid of headers here
- if ((!$hdrfnd) && ($brpos = strpos($data,"\r\n\r\n"))) {
+ if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
$XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
$data = substr($data, $brpos + 4);
$hdrfnd = 1;
@@ -1221,7 +1298,7 @@ class XML_RPC_Message extends XML_RPC_Base
if (!xml_parse($parser_resource, $data, sizeof($data))) {
// thanks to Peter Kocks <peter.kocks@baygate.com>
- if ((xml_get_current_line_number($parser_resource)) == 1) {
+ if (xml_get_current_line_number($parser_resource) == 1) {
$errstr = 'XML error at line 1, check URL';
} else {
$errstr = sprintf('XML error: %s at line %d',
@@ -1263,15 +1340,16 @@ class XML_RPC_Message extends XML_RPC_Base
}
/**
- *
+ * The methods and properties that represent data in XML RPC format
*
* @category Web Services
* @package XML_RPC
* @author Edd Dumbill <edd@usefulinc.com>
* @author Stig Bakken <stig@php.net>
* @author Martin Jansen <mj@php.net>
- * @copyright 1999-2001 Edd Dumbill
- * @version Release: @package_version@
+ * @author Daniel Convissor <danielc@php.net>
+ * @copyright 1999-2001 Edd Dumbill, 2001-2005 The PHP Group
+ * @version Release: 1.3.1
* @link http://pear.php.net/package/XML_RPC
*/
class XML_RPC_Value extends XML_RPC_Base
@@ -1387,11 +1465,11 @@ class XML_RPC_Value extends XML_RPC_Base
function dump($ar)
{
reset($ar);
- while (list($key, $val) = each($ar)) {
- echo "$key => $val<br>";
+ foreach ($ar as $key => $val) {
+ echo "$key => $val<br />";
if ($key == 'array') {
- while (list($key2, $val2) = each($val)) {
- echo "-- $key2 => $val2<br>";
+ foreach ($val as $key2 => $val2) {
+ echo "-- $key2 => $val2<br />";
}
}
}
@@ -1434,7 +1512,7 @@ class XML_RPC_Value extends XML_RPC_Base
// struct
$rs .= "<struct>\n";
reset($val);
- while (list($key2, $val2) = each($val)) {
+ foreach ($val as $key2 => $val2) {
$rs .= "<member><name>${key2}</name>\n";
$rs .= $this->serializeval($val2);
$rs .= "</member>\n";
@@ -1460,7 +1538,6 @@ class XML_RPC_Value extends XML_RPC_Base
$rs .= "<${typ}>" . ($val ? '1' : '0') . "</${typ}>";
break;
case $XML_RPC_String:
- if(is_array($val)) $val = 'array';
$rs .= "<${typ}>" . htmlspecialchars($val). "</${typ}>";
break;
default:
@@ -1520,12 +1597,13 @@ class XML_RPC_Value extends XML_RPC_Base
/**
* @return mixed the current value
*/
- function getval() {
+ function getval()
+ {
// UNSTABLE
global $XML_RPC_BOOLEAN, $XML_RPC_Base64;
reset($this->me);
- list($a, $b) = each($this->me);
+ $b = current($this->me);
// contributed by I Sofer, 2001-03-24
// add support for nested arrays to scalarval
@@ -1560,8 +1638,7 @@ class XML_RPC_Value extends XML_RPC_Base
{
global $XML_RPC_Boolean, $XML_RPC_Base64;
reset($this->me);
- list($a, $b) = each($this->me);
- return $b;
+ return current($this->me);
}
/**
@@ -1571,7 +1648,7 @@ class XML_RPC_Value extends XML_RPC_Base
{
global $XML_RPC_I4, $XML_RPC_Int;
reset($this->me);
- list($a, $b) = each($this->me);
+ $a = key($this->me);
if ($a == $XML_RPC_I4) {
$a = $XML_RPC_Int;
}
@@ -1595,6 +1672,21 @@ class XML_RPC_Value extends XML_RPC_Base
list($a, $b) = each($this->me);
return sizeof($b);
}
+
+ /**
+ * Determines if the item submitted is an XML_RPC_Value object
+ *
+ * @param mixed $val the variable to be evaluated
+ *
+ * @return bool TRUE if the item is an XML_RPC_Value object
+ *
+ * @static
+ * @since Method available since Release 1.3.0
+ */
+ function isValue($val)
+ {
+ return (strtolower(get_class($val)) == 'xml_rpc_value');
+ }
}
/**
@@ -1610,7 +1702,8 @@ class XML_RPC_Value extends XML_RPC_Base
*
* @return string the formatted date
*/
-function XML_RPC_iso8601_encode($timet, $utc = 0) {
+function XML_RPC_iso8601_encode($timet, $utc = 0)
+{
if (!$utc) {
$t = strftime('%Y%m%dT%H:%M:%S', $timet);
} else {
@@ -1638,7 +1731,8 @@ function XML_RPC_iso8601_encode($timet, $utc = 0) {
*
* @return int the unix timestamp of the date submitted
*/
-function XML_RPC_iso8601_decode($idate, $utc = 0) {
+function XML_RPC_iso8601_decode($idate, $utc = 0)
+{
$t = 0;
if (ereg('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) {
if ($utc) {
@@ -1651,12 +1745,11 @@ function XML_RPC_iso8601_decode($idate, $utc = 0) {
}
/**
- * Takes a message in PHP XML_RPC object format and translates it into
- * native PHP types
+ * Converts an XML_RPC_Value object into native PHP types
*
- * @return mixed
+ * @param object $XML_RPC_val the XML_RPC_Value object to decode
*
- * @author Dan Libby <dan@libby.com>
+ * @return mixed the PHP values
*/
function XML_RPC_decode($XML_RPC_val)
{
@@ -1684,17 +1777,16 @@ function XML_RPC_decode($XML_RPC_val)
}
/**
- * Takes native php types and encodes them into XML_RPC PHP object format
- *
- * Feature creep -- could support more types via optional type argument.
+ * Converts native PHP types into an XML_RPC_Value object
*
- * @return string
+ * @param mixed $php_val the PHP value or variable you want encoded
*
- * @author Dan Libby <dan@libby.com>
+ * @return object the XML_RPC_Value object
*/
-function XML_RPC_encode($php_val) {
+function XML_RPC_encode($php_val)
+{
global $XML_RPC_Boolean, $XML_RPC_Int, $XML_RPC_Double, $XML_RPC_String,
- $XML_RPC_Array, $XML_RPC_Struct;
+ $XML_RPC_Array, $XML_RPC_Struct;
$type = gettype($php_val);
$XML_RPC_val = new XML_RPC_Value;
OpenPOWER on IntegriCloud