| [ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * @package evocore 4 * @subpackage xmlrpc {@link http://xmlrpc.usefulinc.com/doc/} 5 * @copyright Edd Dumbill <edd@usefulinc.com> (C) 1999-2002 6 */ 7 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 8 9 // by Edd Dumbill (C) 1999-2002 10 // <edd@usefulinc.com> 11 // $Id: _xmlrpcs.php,v 1.3 2007/09/11 20:57:52 fplanque Exp $ 12 13 // Copyright (c) 1999,2000,2002 Edd Dumbill. 14 // All rights reserved. 15 // 16 // Redistribution and use in source and binary forms, with or without 17 // modification, are permitted provided that the following conditions 18 // are met: 19 // 20 // * Redistributions of source code must retain the above copyright 21 // notice, this list of conditions and the following disclaimer. 22 // 23 // * Redistributions in binary form must reproduce the above 24 // copyright notice, this list of conditions and the following 25 // disclaimer in the documentation and/or other materials provided 26 // with the distribution. 27 // 28 // * Neither the name of the "XML-RPC for PHP" nor the names of its 29 // contributors may be used to endorse or promote products derived 30 // from this software without specific prior written permission. 31 // 32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 36 // REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 37 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 39 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 42 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 43 // OF THE POSSIBILITY OF SUCH DAMAGE. 44 45 // XML RPC Server class 46 // requires: _xmlrpc.php 47 48 if( CANUSEXMLRPC !== TRUE ) 49 { 50 return; 51 } 52 53 global $xmlrpcI4; 54 global $xmlrpcInt; 55 global $xmlrpcDouble; 56 global $xmlrpcBoolean; 57 global $xmlrpcString; 58 global $xmlrpcDateTime; 59 global $xmlrpcBase64; 60 global $xmlrpcArray; 61 global $xmlrpcStruct; 62 63 global $xmlrpcTypes; 64 global $xmlrpc_valid_parents; 65 global $xmlEntities; 66 global $xmlrpcerr; 67 global $xmlrpcstr; 68 global $xmlrpc_defencoding; 69 global $xmlrpc_internalencoding; 70 global $xmlrpcName; 71 global $xmlrpcVersion; 72 global $xmlrpcerruser; 73 global $xmlrpcerrxml; 74 global $xmlrpc_backslash; 75 global $_xh; 76 77 // listMethods: either a string, or nothing 78 $_xmlrpcs_listMethods_sig = array(array($xmlrpcArray, $xmlrpcString), array($xmlrpcArray)); 79 $_xmlrpcs_listMethods_doc = 'This method lists all the methods that the XML-RPC server knows how to dispatch'; 80 /** 81 * listMethods: either a string, or nothing 82 */ 83 function _xmlrpcs_listMethods($server, $m) 84 { 85 global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; 86 $v=new xmlrpcval(); 87 $dmap=$server->dmap; 88 $outAr=array(); 89 for(reset($dmap); list($key, $val)=each($dmap); ) 90 { 91 $outAr[]=new xmlrpcval($key, 'string'); 92 } 93 $dmap=$_xmlrpcs_dmap; 94 for(reset($dmap); list($key, $val)=each($dmap); ) 95 { 96 $outAr[]=new xmlrpcval($key, 'string'); 97 } 98 $v->addArray($outAr); 99 return new xmlrpcresp($v); 100 } 101 102 $_xmlrpcs_methodSignature_sig=array(array($xmlrpcArray, $xmlrpcString)); 103 $_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)'; 104 /** 105 * 106 */ 107 function _xmlrpcs_methodSignature($server, $m) 108 { 109 global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; 110 111 $methName=$m->getParam(0); 112 $methName=$methName->scalarval(); 113 if (ereg("^system\.", $methName)) 114 { 115 $dmap=$_xmlrpcs_dmap; $sysCall=1; 116 } 117 else 118 { 119 $dmap=$server->dmap; $sysCall=0; 120 } 121 // print "<!-- ${methName} -->\n"; 122 if (isset($dmap[$methName])) 123 { 124 if ($dmap[$methName]['signature']) 125 { 126 $sigs=array(); 127 $thesigs=$dmap[$methName]['signature']; 128 for($i=0; $i<sizeof($thesigs); $i++) 129 { 130 $cursig=array(); 131 $inSig=$thesigs[$i]; 132 for($j=0; $j<sizeof($inSig); $j++) 133 { 134 $cursig[]=new xmlrpcval($inSig[$j], 'string'); 135 } 136 $sigs[]=new xmlrpcval($cursig, 'array'); 137 } 138 $r=new xmlrpcresp(new xmlrpcval($sigs, 'array')); 139 } 140 else 141 { 142 $r=new xmlrpcresp(new xmlrpcval('undef', 'string')); 143 } 144 } 145 else 146 { 147 $r=new xmlrpcresp(0,$xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']); 148 } 149 return $r; 150 } 151 152 $_xmlrpcs_methodHelp_sig=array(array($xmlrpcString, $xmlrpcString)); 153 $_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string'; 154 function _xmlrpcs_methodHelp($server, $m) 155 { 156 global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; 157 158 $methName=$m->getParam(0); 159 $methName=$methName->scalarval(); 160 if (ereg("^system\.", $methName)) 161 { 162 $dmap=$_xmlrpcs_dmap; $sysCall=1; 163 } 164 else 165 { 166 $dmap=$server->dmap; $sysCall=0; 167 } 168 // print "<!-- ${methName} -->\n"; 169 if (isset($dmap[$methName])) 170 { 171 if ($dmap[$methName]['docstring']) 172 { 173 $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string'); 174 } 175 else 176 { 177 $r=new xmlrpcresp(new xmlrpcval('', 'string')); 178 } 179 } 180 else 181 { 182 $r=new xmlrpcresp(0, $xmlrpcerr['introspect_unknown'], $xmlrpcstr['introspect_unknown']); 183 } 184 return $r; 185 } 186 187 $_xmlrpcs_multicall_sig = array(array($xmlrpcArray, $xmlrpcArray)); 188 $_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details'; 189 190 function _xmlrpcs_multicall_error($err) 191 { 192 if (is_string($err)) 193 { 194 global $xmlrpcerr, $xmlrpcstr; 195 $str = $xmlrpcstr["multicall_$err}"]; 196 $code = $xmlrpcerr["multicall_$err}"]; 197 } 198 else 199 { 200 $code = $err->faultCode(); 201 $str = $err->faultString(); 202 } 203 $struct['faultCode'] = new xmlrpcval($code, 'int'); 204 $struct['faultString'] = new xmlrpcval($str, 'string'); 205 return new xmlrpcval($struct, 'struct'); 206 } 207 208 function _xmlrpcs_multicall_do_call($server, $call) 209 { 210 if ($call->kindOf() != 'struct') 211 { 212 return _xmlrpcs_multicall_error('notstruct'); 213 } 214 $methName = $call->structmem('methodName'); 215 if (!$methName) 216 { 217 return _xmlrpcs_multicall_error('nomethod'); 218 } 219 if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string') 220 { 221 return _xmlrpcs_multicall_error('notstring'); 222 } 223 if ($methName->scalarval() == 'system.multicall') 224 { 225 return _xmlrpcs_multicall_error('recursion'); 226 } 227 228 $params = $call->structmem('params'); 229 if (!$params) 230 { 231 return _xmlrpcs_multicall_error('noparams'); 232 } 233 if ($params->kindOf() != 'array') 234 { 235 return _xmlrpcs_multicall_error('notarray'); 236 } 237 $numParams = $params->arraysize(); 238 239 $msg = new xmlrpcmsg($methName->scalarval()); 240 for ($i = 0; $i < $numParams; $i++) 241 { 242 $msg->addParam($params->arraymem($i)); 243 } 244 245 $result = $server->execute($msg); 246 247 if ($result->faultCode() != 0) 248 { 249 return _xmlrpcs_multicall_error($result); // Method returned fault. 250 } 251 252 return new xmlrpcval(array($result->value()), 'array'); 253 } 254 255 function _xmlrpcs_multicall($server, $m) 256 { 257 $calls = $m->getParam(0); 258 $numCalls = $calls->arraysize(); 259 $result = array(); 260 261 for ($i = 0; $i < $numCalls; $i++) 262 { 263 $call = $calls->arraymem($i); 264 $result[$i] = _xmlrpcs_multicall_do_call($server, $call); 265 } 266 267 return new xmlrpcresp(new xmlrpcval($result, 'array')); 268 } 269 270 $_xmlrpcs_dmap=array( 271 'system.listMethods' => array( 272 'function' => '_xmlrpcs_listMethods', 273 'signature' => $_xmlrpcs_listMethods_sig, 274 'docstring' => $_xmlrpcs_listMethods_doc), 275 'system.methodHelp' => array( 276 'function' => '_xmlrpcs_methodHelp', 277 'signature' => $_xmlrpcs_methodHelp_sig, 278 'docstring' => $_xmlrpcs_methodHelp_doc), 279 'system.methodSignature' => array( 280 'function' => '_xmlrpcs_methodSignature', 281 'signature' => $_xmlrpcs_methodSignature_sig, 282 'docstring' => $_xmlrpcs_methodSignature_doc), 283 'system.multicall' => array( 284 'function' => '_xmlrpcs_multicall', 285 'signature' => $_xmlrpcs_multicall_sig, 286 'docstring' => $_xmlrpcs_multicall_doc 287 ) 288 ); 289 290 /** 291 * Register a debugging message to be sent back in output 292 * 293 * evocore addition: make debug output optional 294 */ 295 $_xmlrpc_debuginfo=''; 296 function xmlrpc_debugmsg($m) 297 { 298 global $_xmlrpc_debuginfo; 299 $_xmlrpc_debuginfo=$_xmlrpc_debuginfo . $m . "\n"; 300 } 301 302 /** 303 * @package evocore 304 * @subpackage xmlrpc 305 */ 306 class xmlrpc_server 307 { 308 var $dmap=array(); 309 310 /* 311 * Constructor: 312 */ 313 function xmlrpc_server($dispMap='', $serviceNow=1) 314 { 315 global $HTTP_RAW_POST_DATA; 316 // dispMap is a dispatch array of methods 317 // mapped to function names and signatures 318 // if a method 319 // doesn't appear in the map then an unknown 320 // method error is generated 321 /* milosch - changed to make passing dispMap optional. 322 * instead, you can use the class add_to_map() function 323 * to add functions manually (borrowed from SOAPX4) 324 */ 325 if($dispMap) 326 { 327 $this->dmap = $dispMap; 328 if($serviceNow) 329 { 330 $this->service(); 331 } 332 } 333 } 334 335 function serializeDebug() 336 { 337 global $_xmlrpc_debuginfo; 338 if ($_xmlrpc_debuginfo!='') 339 { 340 return "<!-- DEBUG INFO:\n\n" . xmlrpc_encode_entitites($_xmlrpc_debuginfo) . "\n-->\n"; 341 } 342 else 343 { 344 return ''; 345 } 346 } 347 348 function service() 349 { 350 //global $xmlrpc_defencoding; 351 352 $r=$this->parseRequest(); 353 //$payload='<?xml version="1.0" encoding="' . $xmlrpc_defencoding . '"?' . '>' . "\n" 354 // TODO: charset: encoding=\"iso-8859-1\" 355 $payload='<?xml version="1.0" ?' . '>' . "\n" 356 . $this->serializeDebug() // Include debug info as comments 357 . $r->serialize(); 358 header('Content-Type: text/xml'); 359 header('Content-Length: ' . (int)strlen($payload)); 360 361 logIO( 'O', "service() response:\n".$payload ); 362 363 print $payload; 364 } 365 366 /** 367 * add a method to the dispatch map 368 */ 369 function add_to_map($methodname,$function,$sig,$doc) 370 { 371 $this->dmap[$methodname] = array( 372 'function' => $function, 373 'signature' => $sig, 374 'docstring' => $doc 375 ); 376 } 377 378 function verifySignature($in, $sig) 379 { 380 for($i=0; $i<sizeof($sig); $i++) 381 { 382 // check each possible signature in turn 383 $cursig=$sig[$i]; 384 if (sizeof($cursig)==$in->getNumParams()+1) 385 { 386 $itsOK=1; 387 for($n=0; $n<$in->getNumParams(); $n++) 388 { 389 $p=$in->getParam($n); 390 // print "<!-- $p -->\n"; 391 if ($p->kindOf() == 'scalar') 392 { 393 $pt=$p->scalartyp(); 394 } 395 else 396 { 397 $pt=$p->kindOf(); 398 } 399 // $n+1 as first type of sig is return type 400 if ($pt != $cursig[$n+1]) 401 { 402 $itsOK=0; 403 $pno=$n+1; $wanted=$cursig[$n+1]; $got=$pt; 404 break; 405 } 406 } 407 if ($itsOK) 408 { 409 return array(1,''); 410 } 411 } 412 } 413 if (isset($wanted)) 414 return array(0, "Wanted $wanted}, got $got} at param $pno})"); 415 else 416 return array(0, "No method signature matches number of parameters"); 417 } 418 419 /** 420 * 421 */ 422 function parseRequest($data='') 423 { 424 global $_xh,$HTTP_RAW_POST_DATA; 425 global $xmlrpcerr, $xmlrpcstr, $xmlrpcerrxml, $xmlrpc_defencoding, 426 $_xmlrpcs_dmap, $xmlrpc_internalencoding; 427 428 if ($data=='') 429 { 430 $data=$HTTP_RAW_POST_DATA; 431 } 432 // xmlrpc_debugmsg( 'Data received: ['.$data.']' ); 433 434 // G. Giunta 2005/02/13: we do NOT expect to receive html entities 435 // so we do not try to convert them into xml character entities 436 //$data = xmlrpc_html_entity_xlate($data); 437 $parser = xml_parser_create($xmlrpc_defencoding); 438 439 $_xh[$parser]=array(); 440 //$_xh[$parser]['st']=''; 441 //$_xh[$parser]['cm']=0; 442 $_xh[$parser]['isf']=0; 443 $_xh[$parser]['isf_reason']=''; 444 $_xh[$parser]['params']=array(); 445 $_xh[$parser]['stack']=array(); 446 $_xh[$parser]['valuestack'] = array(); 447 $_xh[$parser]['method']=''; 448 449 // decompose incoming XML into request structure 450 451 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); 452 // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell 453 // the xml parser to give us back data in the expected charset 454 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $xmlrpc_internalencoding); 455 456 xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); 457 xml_set_character_data_handler($parser, 'xmlrpc_cd'); 458 xml_set_default_handler($parser, 'xmlrpc_dh'); 459 if (!xml_parse($parser, $data, 1)) 460 { 461 // return XML error as a faultCode 462 $r=new xmlrpcresp(0, 463 $xmlrpcerrxml+xml_get_error_code($parser), 464 sprintf('XML error: %s at line %d', 465 xml_error_string(xml_get_error_code($parser)), 466 xml_get_current_line_number($parser))); 467 xml_parser_free($parser); 468 } 469 else 470 if ($_xh[$parser]['isf']) 471 { 472 xml_parser_free($parser); 473 $r=new xmlrpcresp(0, 474 $xmlrpcerr['invalid_request'], 475 $xmlrpcstr['invalid_request'] . ' ' . $_xh[$parser]['isf_reason']); 476 } 477 else 478 { 479 xml_parser_free($parser); 480 481 $m=new xmlrpcmsg($_xh[$parser]['method']); 482 // now add parameters in 483 // fp> commented out because it is commented out below: $plist=''; 484 //$allOK = 1; 485 for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) 486 { 487 //print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n"; 488 // dh> commented out for PHP 5.2: $plist.="$i - " . $_xh[$parser]['params'][$i]. ";\n"; 489 //$allOK = 0; 490 //@eval('$m->addParam(' . $_xh[$parser]['params'][$i]. '); $allOK=1;'); 491 @$m->addParam($_xh[$parser]['params'][$i]); 492 //if (!$allOK) 493 //{ 494 // break; 495 //} 496 } 497 // uncomment this to really see what the server's getting! 498 // xmlrpc_debugmsg($plist); 499 //if (!$allOK) 500 //{ 501 // $r = new xmlrpcresp(0, 502 // $xmlrpcerr['incorrect_params'], 503 // $xmlrpcstr['incorrect_params'] . ": xml error in param " . $i); 504 //} 505 //else 506 //{ 507 $r = $this->execute($m); 508 //} 509 } 510 return $r; 511 } 512 513 function execute ($m) 514 { 515 global $xmlrpcerr, $xmlrpcstr, $_xmlrpcs_dmap; 516 // now to deal with the method 517 $methName = $m->method(); 518 logIO( 'I', 'Called method:'.$methName ); 519 $sysCall = ereg("^system\.", $methName); 520 $dmap = $sysCall ? $_xmlrpcs_dmap : $this->dmap; 521 522 if (!isset($dmap[$methName]['function'])) 523 { 524 // No such method 525 logIO( 'O', 'No such method:'.$methName ); 526 return new xmlrpcresp(0, 527 $xmlrpcerr['unknown_method'], 528 $xmlrpcstr['unknown_method']); 529 } 530 531 // Check signature. 532 if (isset($dmap[$methName]['signature'])) 533 { 534 $sig = $dmap[$methName]['signature']; 535 list($ok, $errstr) = $this->verifySignature($m, $sig); 536 if(!$ok) 537 { 538 // Didn't match. 539 logIO( 'O', 'Invalid signature.' ); 540 return new xmlrpcresp( 541 0, 542 $xmlrpcerr['incorrect_params'], 543 $xmlrpcstr['incorrect_params'] . ": $errstr}" 544 ); 545 } 546 } 547 548 $func = $dmap[$methName]['function']; 549 550 if ($sysCall) 551 { 552 return call_user_func($func, $this, $m); 553 } 554 else 555 { 556 return call_user_func($func, $m); 557 } 558 } 559 560 function echoInput() 561 { 562 global $HTTP_RAW_POST_DATA; 563 564 // a debugging routine: just echos back the input 565 // packet as a string value 566 567 $r=new xmlrpcresp; 568 $r->xv=new xmlrpcval( "'Aha said I: '" . $HTTP_RAW_POST_DATA, 'string'); 569 print $r->serialize(); 570 } 571 } 572 573 /* 574 * $Log: _xmlrpcs.php,v $ 575 * Revision 1.3 2007/09/11 20:57:52 fplanque 576 * minor fixes 577 * 578 * Revision 1.2 2007/06/26 02:40:54 fplanque 579 * security checks 580 * 581 * Revision 1.1 2007/06/25 10:59:17 fplanque 582 * MODULES (refactored MVC) 583 * 584 * Revision 1.7 2006/12/03 00:06:39 fplanque 585 * minor 586 * 587 */ 588 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 23:58:50 2007 | par Balluche grâce à PHPXref 0.7 |
|