Example #1
0
 function configure()
 {
     $this->pid = getmypid();
     $this->mode = isset($_REQUEST['jaxl']) ? "cgi" : "cli";
     if (!JAXLUtil::isWin() && JAXLUtil::pcntlEnabled() && $config['sigh'] != FALSE) {
         pcntl_signal(SIGTERM, array($this, "shutdown"));
         pcntl_signal(SIGINT, array($this, "shutdown"));
         JAXLog::log("Registering shutdown for SIGH Terms ...", 0, $this);
     }
     if (JAXLUtil::sslEnabled()) {
         JAXLog::log("Openssl enabled ...", 0, $this);
     }
     if ($this->mode == "cli") {
         if (!function_exists('fsockopen')) {
             die("Jaxl requires fsockopen method ...");
         }
         file_put_contents(JAXL_PID_PATH, $this->pid);
     }
     if ($this->mode == "cgi") {
         if (!function_exists('curl_init')) {
             die("Jaxl requires curl_init method ...");
         }
     }
     // include service discovery XEP, recommended for every IM client
     jaxl_require('JAXL0030', $this, array('category' => 'client', 'type' => 'bot', 'name' => JAXL_NAME, 'lang' => 'en'));
 }
Example #2
0
 public static function getPresence($payloads, $jaxl)
 {
     $html = '';
     foreach ($payloads as $payload) {
         if (in_array($payload['type'], array('', 'available', 'unavailable'))) {
             list($room, $domain, $nick) = JAXLUtil::splitJid($payload['from']);
             $html .= '<div class="presIn">';
             $html .= '<p class="from">' . $nick;
             if ($payload['type'] == 'unavailable') {
                 $html .= ' left the room</p>';
             } else {
                 $html .= ' joined the room</p>';
             }
             $html .= '</div>';
         }
     }
     if ($html != '') {
         $response = array('jaxl' => 'presence', 'presence' => urlencode($html));
         $jaxl->JAXL0206('out', $response);
     }
     return $payloads;
 }
$body = file_get_contents("php://input");
$body = new SimpleXMLElement($body);
$attrs = $body->attributes();
if (!@$attrs['to'] && !@$attrs['rid'] && !@$attrs['wait'] && !@$attrs['hold']) {
    echo "invalid input";
    exit;
}
//
// initialize JAXL object with initial config
//
require_once 'jaxl.php';
$to = $attrs['to'];
$rid = $attrs['rid'];
$wait = $attrs['wait'];
$hold = $attrs['hold'];
echo $to . " " . $rid . " " . $wait . " " . $hold;
exit;
list($host, $port) = JAXLUtil::get_dns_srv($to);
$client = new JAXL(array('domain' => $to, 'host' => $host, 'port' => $port, 'bosh_url' => 'http://localhost:5280/http-bind', 'bosh_rid' => $rid, 'bosh_wait' => $wait, 'bosh_hold' => $hold, 'auth_type' => 'ANONYMOUS'));
$client->add_cb('on_auth_success', function () {
    global $client;
    _info($client->full_jid->to_string());
    _info($client->xeps['0206']->sid);
    _info($client->xeps['0206']->rid);
    exit;
});
//
// finally start configured xmpp stream
//
$client->start();
echo "done\n";
Example #4
0
 public static function sendBody($xml, $jaxl)
 {
     $xml = JAXLPlugin::execute('jaxl_pre_curl', $xml, $jaxl);
     if ($xml != false) {
         JAXLog::log("[[XMPPSend]] body\n" . $xml, 4, $jaxl);
         $payload = JAXLUtil::curl($jaxl->bosh['url'], 'POST', $jaxl->bosh['headers'], $xml);
         $payload = $payload['content'];
         XMPPGet::handler($payload, $jaxl);
     }
     return $xml;
 }
Example #5
0
 public static function startAuth($type, $jaxl)
 {
     $jaxl->authType = $type;
     $xml = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="' . $type . '">';
     switch ($type) {
         case 'DIGEST-MD5':
             break;
         case 'PLAIN':
             $xml .= base64_encode("" . $jaxl->user . "" . $jaxl->pass);
             break;
         case 'ANONYMOUS':
             break;
         case 'X-FACEBOOK-PLATFORM':
             break;
         case 'CRAM-MD5':
             break;
         case 'SCRAM-SHA-1':
             $xml .= base64_encode("n,,n=" . $jaxl->user . ",r=" . base64_encode(JAXLUtil::generateNonce()));
             break;
         default:
             break;
     }
     $xml .= '</auth>';
     JAXLog::log("Performing Auth type: " . $type, 0, $jaxl);
     return self::xml($xml, $jaxl);
 }
Example #6
0
 public static function getResponse($authType, $challenge, $jaxl)
 {
     $response = array();
     $decoded = base64_decode($challenge);
     $xml = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">';
     if ($authType == 'X-FACEBOOK-PLATFORM') {
         $decoded = explode('&', $decoded);
         foreach ($decoded as $k => $v) {
             list($kk, $vv) = explode('=', $v);
             $decoded[$kk] = $vv;
             unset($decoded[$k]);
         }
         list($secret, $decoded['api_key'], $decoded['session_key']) = JAXLPlugin::execute('jaxl_get_facebook_key', false, $jaxl);
         $decoded['call_id'] = time();
         $decoded['v'] = '1.0';
         $base_string = '';
         foreach (array('api_key', 'call_id', 'method', 'nonce', 'session_key', 'v') as $key) {
             if (isset($decoded[$key])) {
                 $response[$key] = $decoded[$key];
                 $base_string .= $key . '=' . $decoded[$key];
             }
         }
         $base_string .= $secret;
         $response['sig'] = md5($base_string);
         $responseURI = '';
         foreach ($response as $k => $v) {
             if ($responseURI == '') {
                 $responseURI .= $k . '=' . urlencode($v);
             } else {
                 $responseURI .= '&' . $k . '=' . urlencode($v);
             }
         }
         $xml .= base64_encode($responseURI);
     } else {
         if ($authType == 'DIGEST-MD5') {
             $decoded = JAXLUtil::explodeData($decoded);
             if (!isset($decoded['digest-uri'])) {
                 $decoded['digest-uri'] = 'xmpp/' . $jaxl->domain;
             }
             $decoded['cnonce'] = base64_encode(JAXLUtil::generateNonce());
             if (isset($decoded['qop']) && $decoded['qop'] != 'auth' && strpos($decoded['qop'], 'auth') !== false) {
                 $decoded['qop'] = 'auth';
             }
             $response = array('username' => $jaxl->user, 'response' => JAXLUtil::encryptPassword(array_merge($decoded, array('nc' => '00000001')), $jaxl->user, $jaxl->pass), 'charset' => 'utf-8', 'nc' => '00000001', 'qop' => 'auth');
             foreach (array('nonce', 'digest-uri', 'realm', 'cnonce') as $key) {
                 if (isset($decoded[$key])) {
                     $response[$key] = $decoded[$key];
                 }
             }
             $xml .= base64_encode(JAXLUtil::implodeData($response));
         } else {
             if ($authType == 'SCRAM-SHA-1') {
                 $decoded = JAXLUtil::explodeData($decoded);
                 // SaltedPassword  := Hi(Normalize(password), salt, i)
                 $saltedPasswd = JAXLUtil::pbkdf2($jaxl->pass, $decoded['s'], $decoded['i']);
                 // ClientKey       := HMAC(SaltedPassword, "Client Key")
                 $clientKey = JAXLUtil::hashMD5($saltedPassword, "Client Key");
                 // StoredKey       := H(ClientKey)
                 $storedKey = sha1("Client Key");
                 // assemble client-final-message-without-proof
                 $clientFinalMessage = "c=bwis,r=" . $decoded['r'];
                 // AuthMessage     := client-first-message-bare + "," + server-first-message + "," + client-final-message-without-proof
                 // ClientSignature := HMAC(StoredKey, AuthMessage)
                 // ClientProof     := ClientKey XOR ClientSignature
                 // ServerKey       := HMAC(SaltedPassword, "Server Key")
                 // ServerSignature := HMAC(ServerKey, AuthMessage)
                 foreach (array('c', 'r', 'p') as $key) {
                     if (isset($decoded[$key])) {
                         $response[$key] = $decoded[$key];
                     }
                 }
                 $xml .= base64_encode(JAXLUtil::implodeData($response));
             } else {
                 if ($authType == 'CRAM-MD5') {
                     $xml .= base64_encode($jaxl->user . ' ' . hash_hmac('md5', $jaxl->pass, $arr['challenge']));
                 }
             }
         }
     }
     $xml .= '</response>';
     $jaxl->secondChallenge = true;
     return $xml;
 }
 public function get_challenge_response($decoded)
 {
     $response = array();
     $nc = '00000001';
     if (!isset($decoded['digest-uri'])) {
         $decoded['digest-uri'] = 'xmpp/' . $this->jid->domain;
     }
     $decoded['cnonce'] = base64_encode(JAXLUtil::get_nonce());
     if (isset($decoded['qop']) && $decoded['qop'] != 'auth' && strpos($decoded['qop'], 'auth') !== false) {
         $decoded['qop'] = 'auth';
     }
     $data = array_merge($decoded, array('nc' => $nc));
     $response = array('username' => $this->jid->node, 'response' => $this->encrypt_password($data, $this->jid->node, $this->pass), 'charset' => 'utf-8', 'nc' => $nc, 'qop' => 'auth');
     foreach (array('nonce', 'digest-uri', 'realm', 'cnonce') as $key) {
         if (isset($decoded[$key])) {
             $response[$key] = $decoded[$key];
         }
     }
     return base64_encode($this->implode_data($response));
 }
Example #8
0
 /**
  * Tracks all incoming presence stanza's
  */
 function _handlePresence($payloads, $jaxl)
 {
     foreach ($payloads as $payload) {
         if ($this->trackPresence) {
             // update local $roster cache
             $jid = JAXLUtil::getBareJid($payload['from']);
             $this->_addRosterNode($jid, false);
             if (!isset($this->roster[$jid]['presence'][$payload['from']])) {
                 $this->roster[$jid]['presence'][$payload['from']] = array();
             }
             $this->roster[$jid]['presence'][$payload['from']]['type'] = $payload['type'] == '' ? 'available' : $payload['type'];
             $this->roster[$jid]['presence'][$payload['from']]['status'] = $payload['status'];
             $this->roster[$jid]['presence'][$payload['from']]['show'] = $payload['show'];
             $this->roster[$jid]['presence'][$payload['from']]['priority'] = $payload['priority'];
         }
         if ($payload['type'] == 'subscribe' && $this->autoSubscribe) {
             $this->subscribed($payload['from']);
             $this->subscribe($payload['from']);
             $this->executePlugin('jaxl_post_subscription_request', $payload);
         } else {
             if ($payload['type'] == 'subscribed') {
                 $this->executePlugin('jaxl_post_subscription_accept', $payload);
             }
         }
     }
     return $payloads;
 }
Example #9
0
 public function get_scram_sha1_response($pass, $challenge)
 {
     // it contains users iteration count i and the user salt
     // also server will append it's own nonce to the one we specified
     $decoded = $this->explode_data(base64_decode($challenge));
     // r=,s=,i=
     $nonce = $decoded['r'];
     $salt = base64_decode($decoded['s']);
     $iteration = intval($decoded['i']);
     // SaltedPassword  := Hi(Normalize(password), salt, i)
     $salted = JAXLUtil::pbkdf2($this->pass, $salt, $iteration);
     // ClientKey       := HMAC(SaltedPassword, "Client Key")
     $client_key = hash_hmac('sha1', $salted, "Client Key", true);
     // StoredKey       := H(ClientKey)
     $stored_key = hash('sha1', $client_key, true);
     // AuthMessage     := client-first-message-bare + "," + server-first-message + "," + client-final-message-without-proof
     $auth_message = '';
     // ClientSignature := HMAC(StoredKey, AuthMessage)
     $signature = hash_hmac('sha1', $stored_key, $auth_message, true);
     // ClientProof     := ClientKey XOR ClientSignature
     $client_proof = $client_key ^ $signature;
     $proof = 'c=biws,r=' . $nonce . ',p=' . base64_encode($client_proof);
     return base64_encode($proof);
 }
Example #10
0
 /**
  * Routes incoming XMPP data to appropriate handlers
  */
 function handler($payload)
 {
     if ($payload == '' && $this->mode == 'cli') {
         return '';
     }
     if ($payload != '' && $this->mode == 'cgi') {
         $this->log("[[XMPPGet]] \n" . $payload, 4);
     }
     $payload = $this->executePlugin('jaxl_pre_handler', $payload);
     $xmls = JAXLUtil::splitXML($payload);
     $pktCnt = count($xmls);
     $this->totalRcvdPkt += $pktCnt;
     $buffer = array();
     foreach ($xmls as $pktNo => $xml) {
         if ($pktNo == $pktCnt - 1) {
             if (substr($xml, -1, 1) != '>') {
                 $this->buffer .= $xml;
                 break;
             }
         }
         if (substr($xml, 0, 7) == '<stream') {
             $arr = $this->xml->xmlize($xml);
         } else {
             $arr = JAXLXml::parse($xml, $this->getSXE);
         }
         if ($arr === false) {
             $this->buffer .= $xml;
             continue;
         }
         switch (true) {
             case isset($arr['stream:stream']):
                 XMPPGet::streamStream($arr['stream:stream'], $this);
                 break;
             case isset($arr['stream:features']):
                 XMPPGet::streamFeatures($arr['stream:features'], $this);
                 break;
             case isset($arr['stream:error']):
                 XMPPGet::streamError($arr['stream:error'], $this);
                 break;
             case isset($arr['failure']):
                 XMPPGet::failure($arr['failure'], $this);
                 break;
             case isset($arr['proceed']):
                 XMPPGet::proceed($arr['proceed'], $this);
                 break;
             case isset($arr['challenge']):
                 XMPPGet::challenge($arr['challenge'], $this);
                 break;
             case isset($arr['success']):
                 XMPPGet::success($arr['success'], $this);
                 break;
             case isset($arr['presence']):
                 $buffer['presence'][] = $arr['presence'];
                 break;
             case isset($arr['message']):
                 $buffer['message'][] = $arr['message'];
                 break;
             case isset($arr['iq']):
                 $this->payloadRaw = $arr['xml'];
                 XMPPGet::iq($arr['iq'], $this);
                 break;
             default:
                 $jaxl->log("[[XMPPGet]] \nUnrecognized payload received from jabber server...");
                 throw new JAXLException("[[XMPPGet]] Unrecognized payload received from jabber server...");
                 break;
         }
     }
     if (isset($buffer['presence'])) {
         XMPPGet::presence($buffer['presence'], $this);
     }
     if (isset($buffer['message'])) {
         XMPPGet::message($buffer['message'], $this);
     }
     unset($buffer);
     $this->executePlugin('jaxl_post_handler', $payload);
     return $payload;
 }
Example #11
0
 private static function preparePresence($jaxl, $to, $from, $child, $type, $id, $ns)
 {
     $xml = '<presence';
     if ($type) {
         $xml .= ' type="' . $type . '"';
     }
     if ($from) {
         $xml .= ' from="' . $from . '"';
     }
     if ($to) {
         $xml .= ' to="' . htmlspecialchars($to) . '"';
     }
     if ($id) {
         $xml .= ' id="' . $id . '"';
     }
     $xml .= '>';
     if ($child) {
         if (isset($child['show'])) {
             $xml .= '<show>' . $child['show'] . '</show>';
         }
         if (isset($child['status'])) {
             $xml .= '<status>' . JAXLUtil::xmlentities($child['status']) . '</status>';
         }
         if (isset($child['priority'])) {
             $xml .= '<priority>' . $child['priority'] . '</priority>';
         }
         if (isset($child['payload'])) {
             $xml .= $child['payload'];
         }
     }
     $xml .= '</presence>';
     return $xml;
 }
Example #12
0
 public static function handler($payload, &$jaxl)
 {
     JAXLog::log("[[XMPPGet]] \n" . $payload, 4, $jaxl);
     $buffer = array();
     $payload = JAXLPlugin::execute('jaxl_pre_handler', $payload, $jaxl);
     $xmls = JAXLUtil::splitXML($payload);
     $pktCnt = count($xmls);
     foreach ($xmls as $pktNo => $xml) {
         if ($pktNo == $pktCnt - 1) {
             if (substr($xml, -1, 1) != '>') {
                 $jaxl->buffer = $xml;
                 break;
             }
         }
         if (substr($xml, 0, 7) == '<stream') {
             $arr = $jaxl->xml->xmlize($xml);
         } else {
             $arr = JAXLXml::parse($xml);
         }
         switch (true) {
             case isset($arr['stream:stream']):
                 self::streamStream($arr['stream:stream'], $jaxl);
                 break;
             case isset($arr['stream:features']):
                 self::streamFeatures($arr['stream:features'], $jaxl);
                 break;
             case isset($arr['stream:error']):
                 self::streamError($arr['stream:error'], $jaxl);
                 break;
             case isset($arr['failure']):
                 self::failure($arr['failure'], $jaxl);
                 break;
             case isset($arr['proceed']):
                 self::proceed($arr['proceed'], $jaxl);
                 break;
             case isset($arr['challenge']):
                 self::challenge($arr['challenge'], $jaxl);
                 break;
             case isset($arr['success']):
                 self::success($arr['success'], $jaxl);
                 break;
             case isset($arr['presence']):
                 $buffer['presence'][] = $arr['presence'];
                 break;
             case isset($arr['message']):
                 $buffer['message'][] = $arr['message'];
                 break;
             case isset($arr['iq']):
                 self::iq($arr['iq'], $jaxl);
                 break;
             default:
                 print "Unrecognized payload received from jabber server...";
                 break;
         }
     }
     if (isset($buffer['presence'])) {
         self::presence($buffer['presence'], $jaxl);
     }
     if (isset($buffer['message'])) {
         self::message($buffer['message'], $jaxl);
     }
     unset($buffer);
     JAXLPlugin::execute('jaxl_post_handler', $payload, $jaxl);
 }
Example #13
0
 /**
  * Configures Jaxl instance to run across various platforms (*nix/windows)
  *
  * Configure method tunes connecting Jaxl instance for
  * OS compatibility, SSL support and dependencies over PHP methods
  */
 protected function configure()
 {
     // register shutdown function
     if (!JAXLUtil::isWin() && JAXLUtil::pcntlEnabled() && $this->sigh) {
         pcntl_signal(SIGTERM, array($this, "shutdown"));
         pcntl_signal(SIGINT, array($this, "shutdown"));
         $this->log("Registering callbacks for CTRL+C and kill.");
     } else {
         $this->log("No callbacks registered for CTRL+C and kill.");
     }
     // check Jaxl dependency on PHP extension in cli mode
     if ($this->mode == "cli") {
         if ($this->openSSL = JAXLUtil::sslEnabled()) {
             $this->log("OpenSSL extension is loaded.");
         } else {
             $this->log("OpenSSL extension not loaded.");
         }
         if (!function_exists('fsockopen')) {
             die("Jaxl requires fsockopen method");
         }
         if (@is_writable($this->pidPath)) {
             file_put_contents($this->pidPath, $this->pid);
         }
     }
     // check Jaxl dependency on PHP extension in cgi mode
     if ($this->mode == "cgi") {
         if (!function_exists('curl_init')) {
             die("Jaxl requires CURL PHP extension");
         }
         if (!function_exists('json_encode')) {
             die("Jaxl requires JSON PHP extension.");
         }
     }
 }
Example #14
0
 public static function sendBody($xml, $jaxl)
 {
     $xml = self::saveSession($xml, $jaxl);
     if ($xml != false) {
         $jaxl->log("[[XMPPSend]] body\n" . $xml, 4);
         $payload = JAXLUtil::curl($jaxl->bosh['url'], 'POST', $jaxl->bosh['headers'], $xml);
         $payload = $payload['content'];
         $jaxl->handler($payload);
     }
     return $xml;
 }
Example #15
0
 public static function sendBody($xml, $jaxl)
 {
     $xml = self::saveSession($xml, $jaxl);
     if ($xml != false) {
         $jaxl->log("[[XMPPSend]] body\n" . $xml, 4);
         $payload = JAXLUtil::curl($jaxl->bosh['url'], 'POST', $jaxl->bosh['headers'], $xml);
         // curl error handling
         if ($payload['errno'] != 0) {
             $log = "[[JAXL0124]] Curl errno " . $payload['errno'] . " encountered";
             switch ($payload['errno']) {
                 case 7:
                     $log .= ". Failed to connect with " . $jaxl->bosh['url'];
                     break;
                 case 52:
                     $log .= ". Empty response rcvd from bosh endpoint";
                     break;
                 default:
                     break;
             }
             $jaxl->executePlugin('jaxl_get_bosh_curl_error', $payload);
             $jaxl->log($log);
         }
         $payload = $payload['content'];
         $jaxl->handler($payload);
     }
     return $xml;
 }
Example #16
0
 public static function postBind($arr, $jaxl)
 {
     if ($arr["type"] == "result") {
         $jaxl->jid = $arr["bindJid"];
         list($user, $domain, $resource) = JAXLUtil::splitJid($jaxl->jid);
         $jaxl->resource = $resource;
         $jaxl->executePlugin('jaxl_post_bind', false);
         if ($jaxl->sessionRequired) {
             $jaxl->startSession();
         } else {
             $jaxl->auth = true;
             $jaxl->log("[[XMPPGet]] Auth completed...");
             $jaxl->executePlugin('jaxl_post_auth', false);
         }
     }
 }