From 905c85813a24f02050421df8a7b1bf7ffbf4d987 Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sat, 01 Nov 2014 23:52:41 +0000 Subject: [PATCH] [core] Zablokowanie przetwarzania XML External Entities --- class/BotAPIGG.php | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 150 insertions(+), 30 deletions(-) diff --git a/class/BotAPIGG.php b/class/BotAPIGG.php index 0801ac6..90981dd 100644 --- a/class/BotAPIGG.php +++ b/class/BotAPIGG.php @@ -6,7 +6,7 @@ function __construct($msg, $httpcode, $content) { $this->httpcode = $httpcode; $this->content = $content; - parent::__construct($msg); + parent::__construct($msg.' Błąd '.$httpcode); } function __get($name) { @@ -44,7 +44,7 @@ } class BotAPIGG extends config { - private $token; + private static $token; const STATUS_DOSTEPNY = 2; const STATUS_DOSTEPNY_DESC = 4; @@ -71,7 +71,7 @@ const STATUS_INVISIBLE = 20; const STATUS_INVISIBLE_DESC = 22; - private function httpQuery($address, $useToken = TRUE, $curlopts = array()) { + private function httpQuery($address, $curlopts = array(), $useToken = TRUE, $parseXML = TRUE) { if(!is_array($curlopts)) { $curlopts = array(); } @@ -97,21 +97,29 @@ $tok2 = $tok = curl_exec($dane); $info = curl_getinfo($dane); - try { - libxml_use_internal_errors(TRUE); - $tok = new SimpleXMLElement($tok); + if($parseXML) { + try { + libxml_use_internal_errors(TRUE); + $tok = new SimpleXMLElement($tok); + } + catch(Exception $e) { + throw new BotAPIGGXMLException('Otrzymano błędny XML od botmastera.', $tok2); + } + + if(!$tok) { + if($info['http_code'] != 200) { + throw new BotAPIGGHTTPException('Nie udało się wykonać zapytania HTTP.', $info['http_code'], $tok2); + } + else + { + throw new BotAPIGGXMLException('Otrzymano błędny XML od botmastera.', $tok2); + } + } } - catch(Exception $e) { - throw new BotAPIGGXMLException('Otrzymano błędny XML od botmastera.', $tok2); - } - - if(!$tok) { + else + { if($info['http_code'] != 200) { throw new BotAPIGGHTTPException('Nie udało się wykonać zapytania HTTP.', $info['http_code'], $tok2); - } - else - { - throw new BotAPIGGXMLException('Otrzymano błędny XML od botmastera.', $tok2); } } @@ -119,32 +127,34 @@ } function getToken($force = FALSE) { - if($force || !$this->token) { + if($force || self::$token === NULL) { $auth = $this->APIs['Gadu-Gadu']; - $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/getToken/'.$auth['numer'], FALSE, array( + $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/getToken/'.$auth['numer'], array( CURLOPT_USERPWD => $auth['login'].':'.$auth['haslo'], CURLOPT_HTTPAUTH => CURLAUTH_BASIC, - )); + ), FALSE); if($tok->errorMsg) { throw new BotAPIGGReplyException('Pobieranie tokena nie powiodło się.', $tok); } - $this->token = array('token' => (string)$tok->token, 'host' => (string)$tok->server, 'port' => (int)$tok->port); + self::$token = array('token' => (string)$tok->token, 'host' => (string)$tok->server, 'port' => (int)$tok->port); } - return $this->token; + return self::$token; } function setStatus($status, $desc = '') { $auth = $this->APIs['Gadu-Gadu']; $token = $this->getToken(); - $tok = $this->httpQuery('https://'.$token['host'].'/setStatus/'.$auth['numer'], FALSE, array( - CURLOPT_HTTPHEADER => array('Content-Type: application/x-www-form-urlencoded'), + $tok = $this->httpQuery('https://'.$token['host'].'/setStatus/'.$auth['numer'], array( CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => 'token='.urlencode($token['token']).'&status='.urlencode($status).'&desc='.urlencode($desc), + CURLOPT_POSTFIELDS => http_build_query(array( + 'status' => $status, + 'desc' => $desc, + ), '', '&'), )); if( (string)$tok->status != '0') { @@ -155,7 +165,7 @@ function setUrl($url) { $auth = $this->APIs['Gadu-Gadu']; - $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/setUrl/'.$auth['numer'], TRUE, array( + $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/setUrl/'.$auth['numer'], array( CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $url, )); @@ -167,6 +177,54 @@ return $tok; } + function getImage($hash) { + $auth = $this->APIs['Gadu-Gadu']; + $token = $this->getToken(); + + $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/getImage/'.$auth['numer'], array( + CURLOPT_POST => TRUE, + CURLOPT_POSTFIELDS => http_build_query(array('hash' => $hash), '', '&'), + ), TRUE, FALSE); + + return $tok; + } + + function existsImage($hash) { + $auth = $this->APIs['Gadu-Gadu']; + $token = $this->getToken(); + + $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/existsImage/'.$auth['numer'], array( + CURLOPT_POST => TRUE, + CURLOPT_POSTFIELDS => http_build_query(array('hash' => $hash), '', '&'), + )); + + if( (string)$tok->status != '0') { + return FALSE; + } + + return TRUE; + } + + function putImage($path) { + $auth = $this->APIs['Gadu-Gadu']; + $token = $this->getToken(); + + $tok = $this->httpQuery('https://botapi.gadu-gadu.pl/botmaster/putImage/'.$auth['numer'], array( + CURLOPT_HTTPHEADER => array( + 'Content-Type: image/x-any', + 'Expect: ', + ), + CURLOPT_POST => TRUE, + CURLOPT_POSTFIELDS => file_get_contents($path), + )); + + if( (string)$tok->status != '0') { + throw new BotAPIGGReplyException('Przesyłanie obrazka do botmastera nie powiodło się.', $tok); + } + + return (string)$tok->hash; + } + /** * Wysyła wiadomość do podanych użytkowników * @param array $toURL Lista adresatów wiadomości w postaci: array('Gadu-Gadu://NUMER@gadu-gadu.pl', ...) @@ -174,16 +232,27 @@ * @param array $params Parametry przekazywane funkcji. Aktualnie dostępne: * array( 'SendToOffline' => (bool)TRUE/FALSE ) */ - function sendMessage($toURL, BotMsg $msg, $params = array()) { + if(is_string($toURL)) { + $toURL = array($toURL); + } + + if(!is_array($toURL)) { + throw new Exception('Lista adresatów przekazywanych do funkcji BotAPIGG::sendMessage() winna być tablicą.'); + } + $to = array(); foreach($toURL as $url) { $url = parse_url($url); + if($url === FALSE) { + continue; + } + if($url['scheme'] != 'Gadu-Gadu') { continue; } - if($url['user']=='' || !ctype_digit($url['user'])) { + if($url['user'] == '' || !ctype_digit($url['user'])) { throw new Exception('Nieznany użytkownik sieci Gadu-Gadu, któremu należy dostarczyć wiadomość.'); } @@ -208,17 +277,24 @@ while(!empty($to)) { $to_part = implode(',', array_splice($to, -5000)); - $tok = $this->httpQuery('https://'.$token['host'].'/sendMessage/'.$auth['numer'], FALSE, array( + $tok = $this->httpQuery('https://'.$token['host'].'/sendMessage/'.$auth['numer'], array( CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => 'token='.urlencode($token['token']).'&to='.urlencode($to_part).'&msg='.urlencode($msg->getGG(FALSE)), + CURLOPT_POSTFIELDS => array( + 'to' => $to_part, + 'msg' => $msg->getGG(FALSE), + ), )); + // Brak obrazka w cache BotMastera... if((string)$tok->status == '18') { - $tok = $this->httpQuery('https://'.$token['host'].'/sendMessage/'.$auth['numer'], FALSE, array( + $tok = $this->httpQuery('https://'.$token['host'].'/sendMessage/'.$auth['numer'], array( CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => 'token='.urlencode($token['token']).'&to='.urlencode($to_part).'&msg='.urlencode($msg->getGG(FALSE)), + CURLOPT_POSTFIELDS => array( + 'to' => $to_part, + 'msg' => $msg->getGG(TRUE), + ), )); } @@ -229,5 +305,49 @@ return TRUE; } + + /** + * Pobiera dane użytkownika z katalogu publicznego. + * @param string|BotUser Numer użytkownika + * @return array|false Tablica z danymi. + */ + function getPublicData($number) { + if($number instanceof BotUser) { + if($number->network != 'gadu-gadu.pl') { + return FALSE; + } + + $number = $number->uid; + } + + if(!ctype_digit($number)) { + throw new Exception('Numer użytkownika przekazany do funkcji BotAPIGG::getPublicData() jest niepoprawny.'); + } + + try { + $data = file_get_contents('http://api.gadu-gadu.pl/users/'.$number.'.xml'); + if(!$data) { + throw new Exception('Nie udało się pobrać danych użytkownika z katalogu publicznego.'); + } + } + catch(Exception $e) { + throw new Exception('Nie udało się pobrać danych użytkownika z katalogu publicznego.'); + } + + libxml_use_internal_errors(); + $data = simplexml_load_string($data); + libxml_clear_errors(); + + if(!$data) { + throw new Exception('Dane użytkownika otrzymane z API Gadu-Gadu mają niepoprawny format.'); + } + + if(!$data) { + throw new Exception('Dane użytkownika otrzymane z API Gadu-Gadu mają niepoprawny format.'); + } + + + return (array)$data->users->user; + } } ?> \ No newline at end of file -- Gitblit v1.9.1