123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- <?php
- class PHPRPC_Server {
- var $callback;
- var $charset;
- var $encode;
- var $ref;
- var $encrypt;
- var $enableGZIP;
- var $debug;
- var $keylen;
- var $key;
- var $errno;
- var $errstr;
- var $functions;
- var $cid;
- var $buffer;
-
- function addJsSlashes($str, $flag) {
- if ($flag) {
- $str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177..\377");
- }
- else {
- $str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177");
- }
- return str_replace(array(chr(7), chr(11)), array('\007', '\013'), $str);
- }
- function encodeString($str, $flag = true) {
- if ($this->encode) {
- return base64_encode($str);
- }
- else {
- return $this->addJsSlashes($str, $flag);
- }
- }
- function encryptString($str, $level) {
- if ($this->encrypt >= $level) {
- $str = xxtea_encrypt($str, $this->key);
- }
- return $str;
- }
- function decryptString($str, $level) {
- if ($this->encrypt >= $level) {
- $str = xxtea_decrypt($str, $this->key);
- }
- return $str;
- }
- function sendHeader() {
- header("HTTP/1.1 200 OK");
- header("Content-Type: text/plain; charset={$this->charset}");
- header("X-Powered-By: PHPRPC Server/3.0");
- header('P3P: CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"');
- header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
- header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
- }
- function getRequestURL() {
- if (!isset($_SERVER['HTTPS']) ||
- $_SERVER['HTTPS'] == 'off' ||
- $_SERVER['HTTPS'] == '') {
- $scheme = 'http';
- }
- else {
- $scheme = 'https';
- }
- $host = $_SERVER['SERVER_NAME'];
- $port = $_SERVER['SERVER_PORT'];
- $path = $_SERVER['SCRIPT_NAME'];
- return $scheme . '://' . $host . (($port == 80) ? '' : ':' . $port) . $path;
- }
- function sendURL() {
- if (SID != "") {
- $url = $this->getRequestURL();
- if (count($_GET) > 0) {
- $url .= '?' . strip_tags(SID);
- foreach ($_GET as $key => $value) {
- if (strpos(strtolower($key), 'phprpc_') !== 0) {
- $url .= '&' . $key . '=' . urlencode($value);
- }
- }
- }
- $this->buffer .= "phprpc_url=\"" . $this->encodeString($url) . "\";\r\n";
- }
- }
- function gzip($buffer) {
- $len = strlen($buffer);
- if ($this->enableGZIP && strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip,deflate')) {
- $gzbuffer = gzencode($buffer);
- $gzlen = strlen($gzbuffer);
- if ($len > $gzlen) {
- header("Content-Length: $gzlen");
- header("Content-Encoding: gzip");
- return $gzbuffer;
- }
- }
- header("Content-Length: $len");
- return $buffer;
- }
- function sendCallback() {
- $this->buffer .= $this->callback;
- echo $this->gzip($this->buffer);
- ob_end_flush();
- restore_error_handler();
- if (function_exists('restore_exception_handler')) {
- restore_exception_handler();
- }
- exit();
- }
- function sendFunctions() {
- $this->buffer .= "phprpc_functions=\"" . $this->encodeString(serialize_fix(array_keys($this->functions))) . "\";\r\n";
- $this->sendCallback();
- }
- function sendOutput($output) {
- if ($this->encrypt >= 3) {
- $this->buffer .= "phprpc_output=\"" . $this->encodeString(xxtea_encrypt($output, $this->key)) . "\";\r\n";
- }
- else {
- $this->buffer .= "phprpc_output=\"" . $this->encodeString($output, false) . "\";\r\n";
- }
- }
- function sendError($output = NULL) {
- if (is_null($output)) {
- $output = ob_get_clean();
- }
- $this->buffer .= "phprpc_errno=\"{$this->errno}\";\r\n";
- $this->buffer .= "phprpc_errstr=\"" . $this->encodeString($this->errstr, false) . "\";\r\n";
- $this->sendOutput($output);
- $this->sendCallback();
- }
- function fatalErrorHandler($buffer) {
- if (preg_match('/<b>(.*?) error<\/b>:(.*?)<br/', $buffer, $match)) {
- if ($match[1] == 'Fatal') {
- $errno = E_ERROR;
- }
- else {
- $errno = E_COMPILE_ERROR;
- }
- if ($this->debug) {
- $errstr = preg_replace('/<.*?>/', '', $match[2]);
- }
- else {
- $errstr = preg_replace('/ in <b>.*<\/b>$/', '', $match[2]);
- }
- $buffer = "phprpc_errno=\"{$errno}\";\r\n" .
- "phprpc_errstr=\"" . $this->encodeString(trim($errstr), false) . "\";\r\n" .
- "phprpc_output=\"\";\r\n" .
- $this->callback;
- $buffer = $this->gzip($buffer);
- }
- return $buffer;
- }
- function errorHandler($errno, $errstr, $errfile, $errline) {
- if ($this->debug) {
- $errstr .= " in $errfile on line $errline";
- }
- if (($errno == E_ERROR) or ($errno == E_CORE_ERROR) or
- ($errno == E_COMPILE_ERROR) or ($errno == E_USER_ERROR)) {
- $this->errno = $errno;
- $this->errstr = $errstr;
- $this->sendError();
- }
- else {
- if (($errno == E_NOTICE) or ($errno == E_USER_NOTICE)) {
- if ($this->errno == 0) {
- $this->errno = $errno;
- $this->errstr = $errstr;
- }
- }
- else {
- if (($this->errno == 0) or
- ($this->errno == E_NOTICE) or
- ($this->errno == E_USER_NOTICE)) {
- $this->errno = $errno;
- $this->errstr = $errstr;
- }
- }
- }
- return true;
- }
- function exceptionHandler($exception) {
- $this->errno = $exception->getCode();
- $this->errstr = $exception->getMessage();
- if ($this->debug) {
- $this->errstr .= "\nfile: " . $exception->getFile() .
- "\nline: " . $exception->getLine() .
- "\ntrace: " . $exception->getTraceAsString();
- }
- $this->sendError();
- }
- function initErrorHandler() {
- $this->errno = 0;
- $this->errstr = "";
- set_error_handler(array(&$this, 'errorHandler'));
- if (function_exists('set_exception_handler')) {
- set_exception_handler(array(&$this, 'exceptionHandler'));
- }
- }
- function call($function, &$args) {
- if ($this->ref) {
- $arguments = array();
- for ($i = 0; $i < count($args); $i++) {
- $arguments[$i] = &$args[$i];
- }
- }
- else {
- $arguments = $args;
- }
- return call_user_func_array($function, $arguments);
- }
- function getRequest($name) {
- $result = $_REQUEST[$name];
- if (get_magic_quotes_gpc()) {
- $result = stripslashes($result);
- }
- return $result;
- }
- function getBooleanRequest($name) {
- $var = true;
- if (isset($_REQUEST[$name])) {
- $var = strtolower($this->getRequest($name));
- if ($var == "false") {
- $var = false;
- }
- }
- return $var;
- }
- function initEncode() {
- $this->encode = $this->getBooleanRequest('phprpc_encode');
- }
- function initRef() {
- $this->ref = $this->getBooleanRequest('phprpc_ref');
- }
- function initCallback() {
- if (isset($_REQUEST['phprpc_callback'])) {
- $this->callback = base64_decode($this->getRequest('phprpc_callback'));
- }
- else {
- $this->callback = "";
- }
- }
- function initKeylen() {
- if (isset($_REQUEST['phprpc_keylen'])) {
- $this->keylen = (int)$this->getRequest('phprpc_keylen');
- }
- else if (isset($_SESSION[$this->cid])) {
- $session = unserialize(base64_decode($_SESSION[$this->cid]));
- if (isset($session['keylen'])) {
- $this->keylen = $session['keylen'];
- }
- else {
- $this->keylen = 128;
- }
- }
- else {
- $this->keylen = 128;
- }
- }
- function initClientID() {
- $this->cid = 0;
- if (isset($_REQUEST['phprpc_id'])) {
- $this->cid = $this->getRequest('phprpc_id');
- }
- $this->cid = "phprpc_" . $this->cid;
- }
- function initEncrypt() {
- $this->encrypt = false;
- if (isset($_REQUEST['phprpc_encrypt'])) {
- $this->encrypt = $this->getRequest('phprpc_encrypt');
- if ($this->encrypt === "true") $this->encrypt = true;
- if ($this->encrypt === "false") $this->encrypt = false;
- }
- }
- function initKey() {
- if ($this->encrypt == 0) {
- return;
- }
- else if (isset($_SESSION[$this->cid])) {
- $session = unserialize(base64_decode($_SESSION[$this->cid]));
- if (isset($session['key'])) {
- $this->key = $session['key'];
- require_once('xxtea.php');
- return;
- }
- }
- $this->errno = E_ERROR;
- $this->errstr = "Can't find the key for decryption.";
- $this->encrypt = 0;
- $this->sendError();
- }
- function getArguments() {
- if (isset($_REQUEST['phprpc_args'])) {
- $arguments = unserialize($this->decryptString(base64_decode($this->getRequest('phprpc_args')), 1));
- ksort($arguments);
- }
- else {
- $arguments = array();
- }
- return $arguments;
- }
- function callFunction() {
- $this->initKey();
- $function = strtolower($this->getRequest('phprpc_func'));
- if (array_key_exists($function, $this->functions)) {
- $function = $this->functions[$function];
- $arguments = $this->getArguments();
- $result = $this->encodeString($this->encryptString(serialize_fix($this->call($function, $arguments)), 2));
- $output = ob_get_clean();
- $this->buffer .= "phprpc_result=\"$result\";\r\n";
- if ($this->ref) {
- $arguments = $this->encodeString($this->encryptString(serialize_fix($arguments), 1));
- $this->buffer .= "phprpc_args=\"$arguments\";\r\n";
- }
- }
- else {
- $this->errno = E_ERROR;
- $this->errstr = "Can't find this function $function().";
- $output = ob_get_clean();
- }
- $this->sendError($output);
- }
- function keyExchange() {
- require_once('bigint.php');
- $this->initKeylen();
- if (isset($_SESSION[$this->cid])) {
- $session = unserialize(base64_decode($_SESSION[$this->cid]));
- }
- else {
- $session = array();
- }
- if ($this->encrypt === true) {
- require_once('dhparams.php');
- $DHParams = new DHParams($this->keylen);
- $this->keylen = $DHParams->getL();
- $encrypt = $DHParams->getDHParams();
- $x = bigint_random($this->keylen - 1, true);
- $session['x'] = bigint_num2dec($x);
- $session['p'] = $encrypt['p'];
- $session['keylen'] = $this->keylen;
- $encrypt['y'] = bigint_num2dec(bigint_powmod(bigint_dec2num($encrypt['g']), $x, bigint_dec2num($encrypt['p'])));
- $this->buffer .= "phprpc_encrypt=\"" . $this->encodeString(serialize_fix($encrypt)) . "\";\r\n";
- if ($this->keylen != 128) {
- $this->buffer .= "phprpc_keylen=\"{$this->keylen}\";\r\n";
- }
- $this->sendURL();
- }
- else {
- $y = bigint_dec2num($this->encrypt);
- $x = bigint_dec2num($session['x']);
- $p = bigint_dec2num($session['p']);
- $key = bigint_powmod($y, $x, $p);
- if ($this->keylen == 128) {
- $key = bigint_num2str($key);
- }
- else {
- $key = pack('H*', md5(bigint_num2dec($key)));
- }
- $session['key'] = str_pad($key, 16, "\0", STR_PAD_LEFT);
- }
- $_SESSION[$this->cid] = base64_encode(serialize($session));
- $this->sendCallback();
- }
- function initSession() {
- @ob_start();
- ob_implicit_flush(0);
- session_start();
- }
- function initOutputBuffer() {
- @ob_start(array(&$this, "fatalErrorHandler"));
- ob_implicit_flush(0);
- $this->buffer = "";
- }
-
- function PHPRPC_Server() {
- require_once('compat.php');
- $this->functions = array();
- $this->charset = 'UTF-8';
- $this->debug = false;
- $this->enableGZIP = false;
- }
- function add($functions, $obj = NULL, $aliases = NULL) {
- if (is_null($functions) || (gettype($functions) != gettype($aliases) && !is_null($aliases))) {
- return false;
- }
- if (is_object($functions)) {
- $obj = $functions;
- $functions = get_class_methods(get_class($obj));
- $aliases = $functions;
- }
- if (is_null($aliases)) {
- $aliases = $functions;
- }
- if (is_string($functions)) {
- if (is_null($obj)) {
- $this->functions[strtolower($aliases)] = $functions;
- }
- else if (is_object($obj)) {
- $this->functions[strtolower($aliases)] = array(&$obj, $functions);
- }
- else if (is_string($obj)) {
- $this->functions[strtolower($aliases)] = array($obj, $functions);
- }
- }
- else {
- if (count($functions) != count($aliases)) {
- return false;
- }
- foreach ($functions as $key => $function) {
- $this->add($function, $obj, $aliases[$key]);
- }
- }
- return true;
- }
- function setCharset($charset) {
- $this->charset = $charset;
- }
- function setDebugMode($debug) {
- $this->debug = $debug;
- }
- function setEnableGZIP($enableGZIP) {
- $this->enableGZIP = $enableGZIP;
- }
- function start() {
- while(ob_get_length() !== false) @ob_end_clean();
- $this->initOutputBuffer();
- $this->sendHeader();
- $this->initErrorHandler();
- $this->initEncode();
- $this->initCallback();
- $this->initRef();
- $this->initClientID();
- $this->initEncrypt();
- if (isset($_REQUEST['phprpc_func'])) {
- $this->callFunction();
- }
- else if ($this->encrypt != false) {
- $this->keyExchange();
- }
- else {
- $this->sendFunctions();
- }
- }
- }
- PHPRPC_Server::initSession();
- ?>
|