PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/temp/server/php/jabberclass.php

https://bitbucket.org/davaeron/zeus
PHP | 296 lines | 253 code | 43 blank | 0 comment | 60 complexity | d46ea7e0d9a60101c4d713c81bd6bf01 MD5 | raw file
  1. <?php
  2. class Jabber
  3. {
  4. var $server;
  5. var $port;
  6. var $username;
  7. var $password;
  8. var $resource;
  9. var $jid;
  10. var $streamId;
  11. var $packetQueue;
  12. var $connector;
  13. var $activeSocket;
  14. function Jabber()
  15. {
  16. $this->server = '127.0.0.1';
  17. $this->port = 5222;
  18. $this->username = '';
  19. $this->password = '';
  20. $this->resource = NULL;
  21. $this->packetQueue = array();
  22. }
  23. function openSocket($server, $port)
  24. {
  25. if($this->activeSocket = fsockopen($server, $port))
  26. {
  27. socket_set_blocking($this->activeSocket, 0);
  28. socket_set_timeout($this->activeSocket, 31536000);
  29. return true;
  30. }
  31. return false;
  32. }
  33. function closeSocket()
  34. {
  35. return fclose($this->activeSocket);
  36. }
  37. function writeToSocket($data)
  38. {
  39. return fwrite($this->activeSocket, $data);
  40. }
  41. function readFromSocket($chunksize)
  42. {
  43. return fread($this->activeSocket, $chunksize);
  44. }
  45. function connect()
  46. {
  47. if($this->openSocket($this->server, $this->port))
  48. {
  49. $this->sendPacket("<?xml version='1.0' encoding='UTF-8' ?".">\n");
  50. $this->sendPacket("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>\n");
  51. sleep(2);
  52. if($this->checkConnected())return true;
  53. }
  54. return false;
  55. }
  56. function disconnect()
  57. {
  58. sleep(1);
  59. $this->sendPacket("</stream:stream>");
  60. $this->closeSocket();
  61. }
  62. function sendAuth()
  63. {
  64. $this->authId = "auth_".md5(time());
  65. $this->resource = ($this->resource != NULL) ? $this->resource : ("Class.Jabber.PHP ".md5($this->authId));
  66. $this->jid = "{$this->username}@{$this->server}/{$this->resource}";
  67. $payload = "<username>{$this->username}</username>";
  68. $packet = $this->sendIq(NULL, 'get', $this->authId, "jabber:iq:auth", $payload);
  69. if($this->getInfoFromIqType($packet) == 'result' && $this->getInfoFromIqId($packet) == $this->authId)
  70. {
  71. if(function_exists('mhash') && isset($packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]) && isset($packet['iq']['#']['query'][0]['#']['token'][0]["#"]))
  72. {
  73. return $this->sendAuth0k($packet['iq']['#']['query'][0]['#']['token'][0]["#"], $packet['iq']['#']['query'][0]['#']['sequence'][0]["#"]);
  74. }
  75. else if(function_exists('mhash') && isset($packet['iq']['#']['query'][0]['#']['digest']))
  76. {
  77. $payload = "<username>{$this->username}</username><resource>{$this->resource}</resource><digest>".bin2hex(mhash(MHASH_SHA1, $this->streamId.$this->password))."</digest>";
  78. $packet = $this->sendIq(NULL, 'set', $this->authId, "jabber:iq:auth", $payload);
  79. if($this->getInfoFromIqType($packet) == 'result' && $this->getInfoFromIqId($packet) == $this->authId)return true;
  80. }
  81. else if($packet['iq']['#']['query'][0]['#']['password'])
  82. {
  83. $payload = "<username>{$this->username}</username><password>{$this->password}</password><resource>{$this->resource}</resource>";
  84. $packet = $this->sendIq(NULL, 'set', $this->authId, "jabber:iq:auth", $payload);
  85. if($this->getInfoFromIqType($packet) == 'result' && $this->getInfoFromIqId($packet) == $this->authId)return true;
  86. }
  87. }
  88. return false;
  89. }
  90. function sendPacket($xml)
  91. {
  92. return $this->writeToSocket(trim($xml));
  93. }
  94. function listen()
  95. {
  96. $incoming = '';
  97. while($line = $this->readFromSocket(4096))$incoming .= $line;
  98. $incoming = trim($incoming);
  99. if($incoming != '')
  100. {
  101. $temp = $this->splitIncoming($incoming);
  102. for($a = 0; $a < count($temp); $a++)$this->packetQueue[] = $this->xmlize($temp[$a]);
  103. }
  104. return true;
  105. }
  106. function sendMessage($to, $type = "normal", $id = NULL, $content = NULL, $payload = NULL)
  107. {
  108. if($to && is_array($content))
  109. {
  110. if(!$id)$id = $type.'_'.time();
  111. $content = $this->arrayHtmlSpecialChars($content);
  112. $xml = "<message to='$to' type='$type' id='$id'>\n";
  113. if(!empty($content['subject']))$xml .= "<subject>".$content['subject']."</subject>\n";
  114. if(!empty($content['thread']))$xml .= "<thread>".$content['thread']."</thread>\n";
  115. $xml .= "<body>{$content['body']}</body>\n{$payload}</message>\n";
  116. if($this->sendPacket($xml))return true;
  117. }
  118. return false;
  119. }
  120. function sendPresence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL)
  121. {
  122. $xml = "<presence";
  123. $xml .= ($to) ? " to='$to'" : '';
  124. $xml .= ($type) ? " type='$type'" : '';
  125. $xml .= ($status || $show || $priority) ? ">\n" : " />\n";
  126. $xml .= ($status) ? " <status>$status</status>\n" : '';
  127. $xml .= ($show) ? " <show>$show</show>\n" : '';
  128. $xml .= ($priority) ? " <priority>$priority</priority>\n" : '';
  129. $xml .= ($status || $show || $priority) ? "</presence>\n" : '';
  130. return $this->sendPacket($xml);
  131. }
  132. function getFromQueueById($packetType, $id)
  133. {
  134. $foundMessage = false;
  135. foreach ($this->packetQueue as $key => $value)if($value[$packetType]['@']['id'] == $id)
  136. {
  137. $foundMessage = $value;
  138. unset($this->packetQueue[$key]);
  139. break;
  140. }
  141. return is_array($foundMessage) ? $foundMessage : false;
  142. }
  143. function sendIq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL)
  144. {
  145. if(!preg_match("/^(get|set|result|error)$/", $type))unset($type);
  146. else if($id && $xmlns)
  147. {
  148. $xml = "<iq type='{$type}' id='{$id}'";
  149. if($to)$xml .= " to='{$to}'";
  150. if($from)$xml .= " from='{$from}'";
  151. $xml .= "><query xmlns='$xmlns'>$payload</query></iq>";
  152. $this->sendPacket($xml);
  153. sleep(1);
  154. $this->listen();
  155. return (preg_match("/^(get|set)$/", $type)) ? $this->getFromQueueById("iq", $id) : true;
  156. }
  157. return false;
  158. }
  159. function sendAuth0k($zerokToken, $zerokSequence)
  160. {
  161. $zerokHash = bin2hex(mhash(MHASH_SHA1, $this->password));
  162. $zerokHash = bin2hex(mhash(MHASH_SHA1, $zerokHash.$zerokToken));
  163. for($a = 0; $a < $zerokSequence; $a++)$zerokHash = bin2hex(mhash(MHASH_SHA1, $zerokHash));
  164. $payload = "<username>{$this->username}</username><hash>$zerokHash</hash><resource>{$this->resource}</resource>";
  165. $packet = $this->sendIq(NULL, 'set', $this->authId, "jabber:iq:auth", $payload);
  166. if($this->getInfoFromIqType($packet) == 'result' && $this->getInfoFromIqId($packet) == $this->authId)return true;
  167. return false;
  168. }
  169. function listenIncoming()
  170. {
  171. $incoming = '';
  172. while($line = $this->readFromSocket(4096))$incoming .= $line;
  173. $incoming = trim($incoming);
  174. return $this->xmlize($incoming);
  175. }
  176. function checkConnected()
  177. {
  178. $incomingArray = $this->listenIncoming();
  179. if(is_array($incomingArray))if($incomingArray["stream:stream"]['@']['from'] == $this->server && $incomingArray["stream:stream"]['@']['xmlns'] == "jabber:client" && $incomingArray["stream:stream"]['@']["xmlns:stream"] == "http://etherx.jabber.org/streams")
  180. {
  181. $this->streamId = $incomingArray["stream:stream"]['@']['id'];
  182. return true;
  183. }
  184. return false;
  185. }
  186. function splitIncoming($incoming)
  187. {
  188. $temp = preg_split("/<(message|iq|presence|stream)/", $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
  189. $array = array();
  190. $c = count($temp);
  191. for($a = 1; $a < $c; $a = $a + 2)$array[] = "<".$temp[$a].$temp[($a + 1)];
  192. return $array;
  193. }
  194. function arrayHtmlSpecialChars($array)
  195. {
  196. if(is_array($array))foreach($array as $k => $v)$v = is_array($v) ? $this->arrayHtmlSpecialChars($v) : htmlspecialchars($v);
  197. return $array;
  198. }
  199. function getInfoFromIqType($packet)
  200. {
  201. return is_array($packet) ? $packet['iq']['@']['type'] : false;
  202. }
  203. function getInfoFromIqId($packet)
  204. {
  205. return is_array($packet) ? $packet['iq']['@']['id'] : false;
  206. }
  207. function xmlize($data)
  208. {
  209. $vals = $index = $array = array();
  210. $parser = xml_parser_create();
  211. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  212. xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  213. xml_parse_into_struct($parser, $data, $vals, $index);
  214. xml_parser_free($parser);
  215. $i = 0;
  216. $tagName = $vals[$i]['tag'];
  217. $array[$tagName]['@'] = $vals[$i]['attributes'];
  218. $array[$tagName]['#'] = $this->xmlDepth($vals, $i);
  219. return $array;
  220. }
  221. function xmlDepth($vals, &$i)
  222. {
  223. $children = array();
  224. if(!empty($vals[$i]['value']))array_push($children, trim($vals[$i]['value']));
  225. while(++$i < count($vals))switch($vals[$i]['type'])
  226. {
  227. case 'cdata':
  228. array_push($children, trim($vals[$i]['value']));
  229. break;
  230. case 'complete':
  231. $tagName = $vals[$i]['tag'];
  232. $size = empty($children[$tagName]) ? 0 : sizeof($children[$tagName]);
  233. $children[$tagName][$size]['#'] = empty($vals[$i]['value']) ? '' : trim($vals[$i]['value']);
  234. if(!empty($vals[$i]['attributes']))$children[$tagName][$size]['@'] = $vals[$i]['attributes'];
  235. break;
  236. case 'open':
  237. $tagName = $vals[$i]['tag'];
  238. $size = empty($children[$tagName]) ? 0 : sizeof($children[$tagName]);
  239. if(!empty($vals[$i]['attributes']))
  240. {
  241. $children[$tagName][$size]['@'] = $vals[$i]['attributes'];
  242. $children[$tagName][$size]['#'] = $this->xmlDepth($vals, $i);
  243. }
  244. else $children[$tagName][$size]['#'] = $this->xmlDepth($vals, $i);
  245. break;
  246. case 'close':
  247. return $children;
  248. break;
  249. }
  250. return $children;
  251. }
  252. }
  253. ?>