X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FMsn%2Fextlib%2Fphpmsnclass%2Fmsn.class.php;h=996c5571c20bd2c0a29458b7b1a00ef654f2e97b;hb=5bf0c9f610d2fe7852ffafbcd51436c9e057b0a7;hp=6dc1c49826c088a909968b526b7002a4ab02d59d;hpb=b313bc3cdefe72f038f5f4e6b163e1294c95ea1e;p=quix0rs-gnu-social.git
diff --git a/plugins/Msn/extlib/phpmsnclass/msn.class.php b/plugins/Msn/extlib/phpmsnclass/msn.class.php
index 6dc1c49826..996c5571c2 100644
--- a/plugins/Msn/extlib/phpmsnclass/msn.class.php
+++ b/plugins/Msn/extlib/phpmsnclass/msn.class.php
@@ -12,7 +12,7 @@ Documentation on the MSN protocol can be found at: http://msnpiki.msnfanatic.com
This class uses MSNP15.
In addition to PHP5, the additional php modules required are:
-curl pcre mhash mcrypt bcmath
+curl pcre mcrypt bcmath
*/
@@ -23,10 +23,10 @@ class MSN {
const PROD_KEY = 'PK}_A_0N_K%O?A9S';
const PROD_ID = 'PROD0114ES4Z%Q5W';
const LOGIN_METHOD = 'SSO';
-
+
const OIM_SEND_URL = 'https://ows.messenger.msn.com/OimWS/oim.asmx';
const OIM_SEND_SOAP = 'http://messenger.live.com/ws/2006/09/oim/Store2';
-
+
const OIM_MAILDATA_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';
const OIM_MAILDATA_SOAP = 'http://www.hotmail.msn.com/ws/2004/09/oim/rsi/GetMetadata';
const OIM_READ_URL = 'https://rsi.hotmail.com/rsi/rsi.asmx';
@@ -42,16 +42,16 @@ class MSN {
const DELMEMBER_URL = 'https://contacts.msn.com/abservice/SharingService.asmx';
const DELMEMBER_SOAP = 'http://www.msn.com/webservices/AddressBook/DeleteMember';
-
+
// the message length (include header) is limited (maybe since WLM 8.5 released)
// for WLM: 1664 bytes
// for YIM: 518 bytes
const MAX_MSN_MESSAGE_LEN = 1664;
const MAX_YAHOO_MESSAGE_LEN = 518;
-
+
private $debug;
private $timeout;
-
+
private $id;
private $ticket;
private $user = '';
@@ -76,7 +76,7 @@ class MSN {
private $port = 1863;
private $clientid = '';
-
+
private $error = '';
private $authed = false;
@@ -156,7 +156,6 @@ class MSN {
// Check support
if (!function_exists('curl_init')) throw new Exception("curl module not found!\n");
if (!function_exists('preg_match')) throw new Exception("pcre module not found!\n");
- if (!function_exists('mhash')) throw new Exception("mhash module not found!\n");
if (!function_exists('mcrypt_cbc')) throw new Exception("mcrypt module not found!\n");
if (!function_exists('bcmod')) throw new Exception("bcmath module not found!\n");
@@ -181,7 +180,7 @@ class MSN {
/**
* Signon methods
*/
-
+
/**
* Connect to the NS server
*
@@ -262,7 +261,7 @@ class MSN {
$this->user = $user;
$this->password = $password;
// NS: <<< USR {id} SSO S {policy} {nonce}
- @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce,) = @explode(' ', $data);
+ @list(/* USR */, /* id */, /* SSO */, /* S */, $policy, $nonce) = @explode(' ', $data);
$this->passport_policy = $policy;
$aTickets = $this->get_passport_ticket();
@@ -271,7 +270,7 @@ class MSN {
// NS: >>> OUT
$this->ns_writeln("OUT");
@fclose($this->NSfp);
- $this->error = 'Passport authenticated fail!';
+ $this->error = 'Passport authentication failed!';
return false;
}
@@ -291,7 +290,7 @@ class MSN {
// NS: <<< XFR {id} NS {server} 0 {server}
// MSNP15
// NS: <<< XFR {id} NS {server} U D
- @list(/* XFR */, /* id */, $Type, $server, /* ... */) = @explode(' ', $data);
+ @list(/* XFR */, /* id */, $Type, $server) = @explode(' ', $data);
if ($Type!='NS') break;
@list($ip, $port) = @explode(':', $server);
// this connection will close after XFR
@@ -313,7 +312,7 @@ class MSN {
case 'GCF':
// return some policy data after 'USR {id} SSO I {user}' command
// NS: <<< GCF 0 {size}
- @list(/* GCF */, /* 0 */, $size,) = @explode(' ', $data);
+ @list(/* GCF */, /* 0 */, $size) = @explode(' ', $data);
// we don't need the data, just read it and drop
if (is_numeric($size) && $size > 0)
$this->ns_readdata($size);
@@ -345,7 +344,7 @@ class MSN {
/* FIXME Don't implement the signon as a loop or we could hang
* the queue handler! */
$this->debug_message('*** Trying to connect to MSN network');
-
+
// Remove any remaining switchboard sessions
$this->switchBoardSessions = array();
$this->switchBoardSessionLookup = array();
@@ -358,7 +357,10 @@ class MSN {
}
// Update contacts
- if ($this->UpdateContacts() === false) continue;
+ if ($this->UpdateContacts() === false) {
+ $this->signonFailure('');
+ continue;
+ }
// Get membership lists
if (($this->aContactList = $this->getMembershipList()) === false) {
@@ -480,8 +482,10 @@ class MSN {
* @return void
*/
private function signonFailure($message) {
- $this->debug_message($message);
- $this->callHandler('ConnectFailed');
+ if(!empty($message)) {
+ $this->debug_message($message);
+ }
+ $this->callHandler('ConnectFailed', $message);
$this->NSRetryWait($this->retry_wait);
}
@@ -504,7 +508,7 @@ class MSN {
/**
* NS and SB command handling methods
*/
-
+
/**
* Read and handle incoming command from NS
*
@@ -527,7 +531,7 @@ class MSN {
$this->signon();
return;
}
-
+
switch (substr($data, 0, 3)) {
case 'SBS':
// after 'USR {id} OK {user} {verify} 0' response, the server will send SBS and profile to us
@@ -550,7 +554,7 @@ class MSN {
case 'LST':
// NS: <<< LST {email} {alias} 11 0
- @list(/* LST */, $email, /* alias */,) = @explode(' ', $data);
+ @list(/* LST */, $email) = @explode(' ', $data);
@list($u_name, $u_domain) = @explode('@', $email);
if (!isset($this->aContactList[$u_domain][$u_name][1])) {
$this->aContactList[$u_domain][$u_name][1]['Allow'] = 'Allow';
@@ -561,7 +565,7 @@ class MSN {
case 'ADL':
// randomly, we get ADL command, someone add us to their contact list for MSNP15
// NS: <<< ADL 0 {size}
- @list(/* ADL */, /* 0 */, $size,) = @explode(' ', $data);
+ @list(/* ADL */, /* 0 */, $size) = @explode(' ', $data);
if (is_numeric($size) && $size > 0) {
$data = $this->ns_readdata($size);
preg_match('##', $data, $matches);
@@ -613,7 +617,7 @@ class MSN {
case 'RML':
// randomly, we get RML command, someome remove us to their contact list for MSNP15
// NS: <<< RML 0 {size}
- @list(/* RML */, /* 0 */, $size,) = @explode(' ', $data);
+ @list(/* RML */, /* 0 */, $size) = @explode(' ', $data);
if (is_numeric($size) && $size > 0) {
$data = $this->ns_readdata($size);
preg_match('##', $data, $matches);
@@ -643,7 +647,7 @@ class MSN {
case 'MSG':
// randomly, we get MSG notification from server
// NS: <<< MSG Hotmail Hotmail {size}
- @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size,) = @explode(' ', $data);
+ @list(/* MSG */, /* Hotmail */, /* Hotmail */, $size) = @explode(' ', $data);
if (is_numeric($size) && $size > 0) {
$data = $this->ns_readdata($size);
$aLines = @explode("\n", $data);
@@ -788,7 +792,7 @@ class MSN {
case 'UBM':
// randomly, we get UBM, this is the message from other network, like Yahoo!
// NS: <<< UBM {email} $network $type {size}
- @list(/* UBM */, $from_email, $network, $type, $size,) = @explode(' ', $data);
+ @list(/* UBM */, $from_email, $network, $type, $size) = @explode(' ', $data);
if (is_numeric($size) && $size > 0) {
$data = $this->ns_readdata($size);
$aLines = @explode("\n", $data);
@@ -827,7 +831,7 @@ class MSN {
case 'UBX':
// randomly, we get UBX notification from server
// NS: <<< UBX email {network} {size}
- @list(/* UBX */, /* email */, /* network */, $size,) = @explode(' ', $data);
+ @list(/* UBX */, /* email */, /* network */, $size) = @explode(' ', $data);
// we don't need the notification data, so just ignore it
if (is_numeric($size) && $size > 0)
$this->ns_readdata($size);
@@ -836,7 +840,7 @@ class MSN {
case 'CHL':
// randomly, we'll get challenge from server
// NS: <<< CHL 0 {code}
- @list(/* CHL */, /* 0 */, $chl_code,) = @explode(' ', $data);
+ @list(/* CHL */, /* 0 */, $chl_code) = @explode(' ', $data);
$fingerprint = $this->getChallenge($chl_code);
// NS: >>> QRY {id} {product_id} 32
// NS: >>> fingerprint
@@ -860,7 +864,7 @@ class MSN {
// NS: <<< XFR {id} NS {server} U D
// for normal switchboard XFR
// NS: <<< XFR {id} SB {server} CKI {cki} U messenger.msn.com 0
- @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code, /* ... */) = @explode(' ', $data);
+ @list(/* XFR */, /* {id} */, $server_type, $server, /* CKI */, $cki_code) = @explode(' ', $data);
@list($ip, $port) = @explode(':', $server);
if ($server_type != 'SB') {
// maybe exit?
@@ -870,15 +874,8 @@ class MSN {
}
$this->debug_message("NS: <<< XFR SB");
- $user = array_shift($this->waitingForXFR);
- $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $User, $Message);
- /*
- $bSBresult = $this->switchboard_control($ip, $port, $cki_code, $aMSNUsers[$nCurrentUser], $sMessage);
- if ($bSBresult === false) {
- // error for switchboard
- $this->debug_message("!!! error for sending message to ".$aMSNUsers[$nCurrentUser]);
- $aOfflineUsers[] = $aMSNUsers[$nCurrentUser];
- }*/
+ $session = array_shift($this->waitingForXFR);
+ $this->connectToSBSession('Active', $ip, $port, $session['to'], array('cki' => $cki_code));
break;
case 'QNG':
// NS: <<< QNG {time}
@@ -894,12 +891,19 @@ class MSN {
// someone is trying to talk to us
// NS: <<< RNG {session_id} {server} {auth_type} {ticket} {email} {alias} U {client} 0
$this->debug_message("NS: <<< RNG $data");
- @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name, ) = @explode(' ', $data);
+ @list(/* RNG */, $sid, $server, /* auth_type */, $ticket, $email, $name) = @explode(' ', $data);
@list($sb_ip, $sb_port) = @explode(':', $server);
$this->debug_message("*** RING from $email, $sb_ip:$sb_port");
$this->addContact($email, 1, $email, true);
$this->connectToSBSession('Passive', $sb_ip, $sb_port, $email, array('sid' => $sid, 'ticket' => $ticket));
break;
+
+ case 'NLN':
+ // NS: <<< NLN {status} {email} {networkid} {nickname} {clientid} {dpobj}
+ @list(/* NLN */, $status, $email, $network, $nickname) = @explode(' ', $data);
+ $this->callHandler('StatusChange', array('screenname' => $email, 'status' => $status, 'network' => $network, 'nickname' => $nickname));
+ break;
+
case 'OUT':
// force logout from NS
// NS: <<< OUT xxx
@@ -944,18 +948,21 @@ class MSN {
// SB: <<< IRO {id} {rooster} {roostercount} {email} {alias} {clientid}
@list(/* IRO */, /* id */, $cur_num, $total, $email, $alias, $clientid) = @explode(' ', $data);
$this->debug_message("*** $email joined session");
- $session['joined'] = true;
+ if ($email == $session['to']) {
+ $session['joined'] = true;
+ $this->callHandler('SessionReady', array('to' => $email));
+ }
break;
case 'BYE':
$this->debug_message("*** Quit for BYE");
- $this->endSBSession();
+ $this->endSBSession($socket);
break;
case 'USR':
// SB: <<< USR {id} OK {user} {alias}
// we don't need the data, just ignore it
// request user to join this switchboard
// SB: >>> CAL {id} {user}
- $this->sb_writeln($socket, $id, "CAL $this->id $user");
+ $this->sb_writeln($socket, $id, "CAL $id ".$session['to']);
break;
case 'CAL':
// SB: <<< CAL {id} RINGING {?}
@@ -965,13 +972,15 @@ class MSN {
case 'JOI':
// SB: <<< JOI {user} {alias} {clientid?}
// someone join us
- // we don't need the data, just ignore it
- // no more user here
- $session['joined'] = true;
+ @list(/* JOI */, $email) = @explode(' ', $data);
+ if ($email == $session['to']) {
+ $session['joined'] = true;
+ $this->callHandler('SessionReady', array('to' => $email));
+ }
break;
case 'MSG':
// SB: <<< MSG {email} {alias} {len}
- @list(/* MSG */, $from_email, /* alias */, $len, ) = @explode(' ', $data);
+ @list(/* MSG */, $from_email, /* alias */, $len) = @explode(' ', $data);
$len = trim($len);
$data = $this->sb_readdata($socket, $len);
$aLines = @explode("\n", $data);
@@ -1108,7 +1117,7 @@ class MSN {
$footer = pack("L", 0);
$message = "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $from_email\r\n\r\n$hdr$footer";
$len = strlen($message);
- $this->sb_writeln($socket, $id, "MSG $this->id D $len");
+ $this->sb_writeln($socket, $id, "MSG $id D $len");
$this->sb_writedata($socket, $message);
$this->debug_message("*** p2p: send display picture acknowledgement for $hdr_SessionID");
$this->debug_message("*** p2p: Invite ACK message:\n".$this->dump_binary($message));
@@ -1146,7 +1155,7 @@ class MSN {
"MIME-Version: 1.0\r\n".
"Content-Type: application/x-msnmsgrp2p\r\n".
"P2P-Dest: $from_email\r\n\r\n$hdr$MessagePayload$footer";
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));
$this->sb_writedata($socket, $message);
$this->debug_message("*** p2p: dump 200 ok message:\n".$this->dump_binary($message));
$this->sb_readln($socket); // Read ACK;
@@ -1173,7 +1182,7 @@ class MSN {
"MIME-Version: 1.0\r\n".
"Content-Type: application/x-msnmsgrp2p\r\n".
"P2P-Dest: $from_email\r\n\r\n$hdr".pack('L', 0)."$footer";
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));
$this->sb_writedata($socket, $message);
$this->debug_message("*** p2p: dump send Data preparation message:\n".$this->dump_binary($message));
$this->debug_message("*** p2p: Data Prepare Hdr:\n".$this->dump_binary($hdr));
@@ -1205,7 +1214,7 @@ class MSN {
"MIME-Version: 1.0\r\n".
"Content-Type: application/x-msnmsgrp2p\r\n".
"P2P-Dest: $from_email\r\n\r\n$hdr$FileContent$footer";
- $this->sb_writeln($socket, $id, "MSG $this->id D ".strlen($message));
+ $this->sb_writeln($socket, $id, "MSG $id D ".strlen($message));
$this->sb_writedata($socket, $message);
$this->debug_message("*** p2p: dump send Data Content message $Offset / $FileSize :\n".$this->dump_binary($message));
$this->debug_message("*** p2p: Data Content Hdr:\n".$this->dump_binary($hdr));
@@ -1308,17 +1317,16 @@ class MSN {
break;
}
$this->debug_message("*** MSG from $from_email: $sMsg");
- $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => $network, 'offline' => false));
+ $this->callHandler('IMin', array('sender' => $from_email, 'message' => $sMsg, 'network' => 1, 'offline' => false));
break;
case '217':
- $this->debug_message("*** User $user is offline. Trying OIM.");
+ $this->debug_message('*** User '.$session['to'].' is offline. Trying OIM.');
$session['offline'] = true;
break;
default:
if (is_numeric($code)) {
$this->error = "Error code: $code, please check the detail information from: http://msnpiki.msnfanatic.com/index.php/Reference:Error_List";
$this->debug_message("*** SB: $this->error");
- $sessionEnd=true;
}
break;
}
@@ -1352,7 +1360,7 @@ class MSN {
/**
* Switchboard related methods
*/
-
+
/**
* Send a request for a switchboard session
*
@@ -1371,7 +1379,7 @@ class MSN {
'offline' => false,
'XFRReqTime' => time()
);
- $this->waitingForXFR[] = &$this->switchBoardSessions[$to];
+ $this->waitingForXFR[$to] = &$this->switchBoardSessions[$to];
}
/**
@@ -1427,7 +1435,7 @@ class MSN {
$this->sb_writeln($socket, $id, "ANS $id $this->user $ticket $sid");
}
}
-
+
/**
* Called when we want to end a switchboard session
* or a switchboard session ends
@@ -1462,16 +1470,10 @@ class MSN {
if (self::socketcheck($socket)) {
return false;
}
-
- $intsocket = (int) $socket;
- if (!$this->switchBoardSessions[$intsocket]['joined']) {
- // If our participant has not joined the session yet we can't message them!
- return false;
- }
- $id = &$this->switchBoardSessions[$intsocket]['id'];
+ $id = &$this->switchBoardSessions[(int) $socket]['id'];
- $aMessage = $this->getMessage($Message);
+ $aMessage = $this->getMessage($message);
// CheckEmotion...
$MsnObjDefine = $this->GetMsnObjDefine($aMessage);
if ($MsnObjDefine !== '') {
@@ -1480,6 +1482,7 @@ class MSN {
if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||
$this->sb_writedata($socket, $SendString) === false) {
+ $this->endSBSession($socket);
return false;
}
}
@@ -1487,6 +1490,7 @@ class MSN {
if ($this->sb_writeln($socket, $id, "MSG $id N $len") === false ||
$this->sb_writedata($socket, $aMessage) === false) {
+ $this->endSBSession($socket);
return false;
}
@@ -1520,36 +1524,58 @@ class MSN {
* where network is 1 for MSN, 32 for Yahoo
* and 'Offline' for offline messages
* @param string $message Message
+ * @param boolean &$waitForSession Boolean passed by reference,
+ * if set to true on return, message
+ * did not fail to send but is
+ * waiting for a valid session
+ *
+ * @return boolean true on success
*/
- public function sendMessage($to, $message) {
+ public function sendMessage($to, $message, &$waitForSession) {
if ($message != '') {
- list($name, $host, $network) = explode('@', $to);
- $network = $network == '' ? 1 : $network;
- $recipient = $name.$host;
+ $toParts = explode('@', $to);
+ if(count($toParts) < 3) {
+ list($name, $host) = $toParts;
+ $network = 1;
+ } else {
+ list($name, $host, $network) = $toParts;
+ }
+
+ $recipient = $name.'@'.$host;
if ($network === 1) {
- if (!isset($this->switchBoardSessionLookup[$recipient]) && (!isset($this->switchBoardSessions[$recipient])
- || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout)) {
- $this->debug_message("*** No existing SB session or request has timed out");
- $this->reqSBSession($recipient);
+ if (!isset($this->switchBoardSessionLookup[$recipient])) {
+ if (!isset($this->switchBoardSessions[$recipient]) || time() - $this->switchBoardSessions[$recipient]['XFRReqTime'] > $this->XFRReqTimeout) {
+ $this->debug_message("*** No existing SB session or request has timed out");
+ $this->reqSBSession($recipient);
+ }
+
+ $waitForSession = true;
return false;
} else {
- $socket = $this->switchBoardSessionLookup[$to];
- if ($this->switchBoardSessions[(int) $socket]['offline']) {
+ $socket = $this->switchBoardSessionLookup[$recipient];
+ $intsocket = (int) $socket;
+ if ($this->switchBoardSessions[$intsocket]['offline']) {
$this->debug_message("*** Contact ($recipient) offline, sending OIM");
$this->endSBSession($socket);
+ $waitForSession = false;
return $this->sendMessage($recipient.'@Offline', $message);
} else {
+ if ($this->switchBoardSessions[$intsocket]['joined'] !== true) {
+ $this->debug_message("*** Recipient has not joined session, returning false");
+ $waitForSession = true;
+ return false;
+ }
+
$this->debug_message("*** Attempting to send message to $recipient using existing SB session");
if ($this->sendMessageViaSB($recipient, $message)) {
$this->debug_message('*** Message sent successfully');
return true;
- } else {
- $this->debug_message('*** Message sending failed, requesting new SB session');
- $this->reqSBSession($to);
- return false;
}
+
+ $waitForSession = false;
+ return false;
}
}
} elseif ($network == 'Offline') {
@@ -1593,7 +1619,7 @@ class MSN {
/**
* OIM methods
*/
-
+
/**
* Get OIM mail data
*
@@ -1796,7 +1822,7 @@ class MSN {
$this->debug_message("*** OIM ($msgid) deleted");
return $sMsg;
}
-
+
/**
* Send offline message
*
@@ -1908,11 +1934,11 @@ X-OIM-Sequence-Num: 1
}
return array('challenge' => $challenge, 'auth_policy' => $auth_policy);
}
-
+
/**
* Contact / Membership list methods
*/
-
+
/**
* Fetch contact list
*
@@ -2337,7 +2363,7 @@ X-OIM-Sequence-Num: 1
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$this->debug_message("*** Get Result:\n$data");
-
+
if ($http_code != 200) return false;
$p = $data;
$aMemberships = array();
@@ -2417,11 +2443,11 @@ X-OIM-Sequence-Num: 1
}
return $aContactList;
}
-
+
/**
* MsnObj related methods
*/
-
+
/**
*
* @param $FilePath åæªè·¯å¾
@@ -2461,14 +2487,14 @@ X-OIM-Sequence-Num: 1
}
return $DefineString;
}
-
+
/**
* Socket methods
*/
-
+
/**
* Read data of specified size from NS socket
- *
+ *
* @param integer $size Size to read
* @return string Data read
*/
@@ -2487,7 +2513,7 @@ X-OIM-Sequence-Num: 1
/**
* Read line from the NS socket
- *
+ *
* @return string Data read
*/
private function ns_readln() {
@@ -2501,9 +2527,9 @@ X-OIM-Sequence-Num: 1
/**
* Write line to NS socket
- *
+ *
* Also increments id
- *
+ *
* @param string $data Line to write to socket
* @return mixed Bytes written or false on failure
*/
@@ -2518,7 +2544,7 @@ X-OIM-Sequence-Num: 1
/**
* Write data to NS socket
- *
+ *
* @param string $data Data to write to socket
* @return mixed Bytes written or false on failure
*/
@@ -2532,7 +2558,7 @@ X-OIM-Sequence-Num: 1
/**
* Read data of specified size from given SB socket
- *
+ *
* @param resource $socket SB socket
* @param integer $size Size to read
* @return string Data read
@@ -2552,7 +2578,7 @@ X-OIM-Sequence-Num: 1
/**
* Read line from given SB socket
- *
+ *
* @param resource $socket SB Socket
* @return string Line read
*/
@@ -2567,9 +2593,9 @@ X-OIM-Sequence-Num: 1
/**
* Write line to given SB socket
- *
+ *
* Also increments id
- *
+ *
* @param resource $socket SB socket
* @param integer $id Reference to SB id
* @param string $data Line to write
@@ -2586,7 +2612,7 @@ X-OIM-Sequence-Num: 1
/**
* Write data to given SB socket
- *
+ *
* @param resource $socket SB socket
* @param $data Data to write to socket
* @return mixed Bytes written or false on error
@@ -2618,16 +2644,16 @@ X-OIM-Sequence-Num: 1
$info = stream_get_meta_data($socket);
return $info['eof'];
}
-
+
/**
* Key generation methods
*/
-
+
private function derive_key($key, $magic) {
- $hash1 = mhash(MHASH_SHA1, $magic, $key);
- $hash2 = mhash(MHASH_SHA1, $hash1.$magic, $key);
- $hash3 = mhash(MHASH_SHA1, $hash1, $key);
- $hash4 = mhash(MHASH_SHA1, $hash3.$magic, $key);
+ $hash1 = $this->mhash_sha1($magic, $key);
+ $hash2 = $this->mhash_sha1($hash1.$magic, $key);
+ $hash3 = $this->mhash_sha1($hash1, $key);
+ $hash4 = $this->mhash_sha1($hash3.$magic, $key);
return $hash2.substr($hash4, 0, 4);
}
@@ -2637,7 +2663,7 @@ X-OIM-Sequence-Num: 1
$key3 = $this->derive_key($key1, 'WS-SecureConversationSESSION KEY ENCRYPTION');
// get hash of challenge using key2
- $hash = mhash(MHASH_SHA1, $challenge, $key2);
+ $hash = $this->mhash_sha1($challenge, $key2);
// get 8 bytes random data
$iv = substr(base64_encode(rand(1000,9999).rand(1000,9999)), 2, 8);
@@ -2651,7 +2677,7 @@ X-OIM-Sequence-Num: 1
return base64_encode($blob);
}
-
+
/**
* Generate challenge response
*
@@ -2731,11 +2757,11 @@ X-OIM-Sequence-Num: 1
return $hash;
}
-
+
/**
* Utility methods
*/
-
+
private function Array2SoapVar($Array, $ReturnSoapVarObj = true, $TypeName = null, $TypeNameSpace = null) {
$ArrayString = '';
foreach($Array as $Key => $Val) {
@@ -2743,7 +2769,7 @@ X-OIM-Sequence-Num: 1
$Attrib = '';
if (is_array($Val[':'])) {
foreach ($Val[':'] as $AttribName => $AttribVal)
- $Attrib .= " $AttribName = '$AttribVal'";
+ $Attrib .= " $AttribName = '$AttribVal'";
}
if ($Key{0} == '!') {
//List Type Define
@@ -2763,7 +2789,7 @@ X-OIM-Sequence-Num: 1
if ($ReturnSoapVarObj) return new SoapVar($ArrayString, XSD_ANYXML, $TypeName, $TypeNameSpace);
return $ArrayString;
}
-
+
private function linetoArray($lines) {
$lines = str_replace("\r", '', $lines);
$lines = explode("\n", $lines);
@@ -2774,7 +2800,7 @@ X-OIM-Sequence-Num: 1
}
return $Data;
}
-
+
/**
* Get Passport ticket
*
@@ -3021,7 +3047,7 @@ X-OIM-Sequence-Num: 1
$this->ABAuthHeader = new SoapHeader('http://www.msn.com/webservices/AddressBook', 'ABAuthHeader', $this->Array2SoapVar($ABAuthHeaderArray));
return $aTickets;
}
-
+
/**
* Generate the data to send a message
*
@@ -3040,7 +3066,7 @@ X-OIM-Sequence-Num: 1
$msg = substr($sMessage, 0, $maxlen);
return $msg_header.$msg;
}
-
+
/**
* Sleep for the given number of seconds
*
@@ -3050,7 +3076,7 @@ X-OIM-Sequence-Num: 1
$this->debug_message("*** Sleeping for $wait seconds before retrying");
sleep($wait);
}
-
+
/**
* Sends a ping command
*
@@ -3062,7 +3088,7 @@ X-OIM-Sequence-Num: 1
// NS: >>> PNG
$this->ns_writeln("PNG");
}
-
+
/**
* Methods to add / call callbacks
*/
@@ -3091,8 +3117,8 @@ X-OIM-Sequence-Num: 1
* Registers a user handler
*
* Handler List
- * IMIn, Pong, ConnectFailed, Reconnect,
- * AddedToList, RemovedFromList
+ * IMIn, SessionReady, Pong, ConnectFailed, Reconnect,
+ * AddedToList, RemovedFromList, StatusChange
*
* @param string $event Event name
* @param string $handler User function to call
@@ -3107,24 +3133,24 @@ X-OIM-Sequence-Num: 1
return false;
}
}
-
+
/**
* Debugging methods
*/
-
+
/**
* Print message if debugging is enabled
- *
+ *
* @param string $str Message to print
*/
private function debug_message($str) {
if (!$this->debug) return;
echo $str."\n";
}
-
+
/**
* Dump binary data
- *
+ *
* @param string $str Data string
* @return Binary data
*/
@@ -3153,4 +3179,32 @@ X-OIM-Sequence-Num: 1
$buf .= "$h_str $a_str\n";
return $buf;
}
+
+ function mhash_sha1($data, $key)
+ {
+ if (extension_loaded("mhash"))
+ return mhash(MHASH_SHA1, $data, $key);
+
+ if (function_exists("hash_hmac"))
+ return hash_hmac('sha1', $data, $key, true);
+
+ // RFC 2104 HMAC implementation for php. Hacked by Lance Rushing
+ $b = 64;
+ if (strlen($key) > $b)
+ $key = pack("H*", sha1($key));
+ $key = str_pad($key, $b, chr(0x00));
+ $ipad = str_pad("", $b, chr(0x36));
+ $opad = str_pad("", $b, chr(0x5c));
+ $k_ipad = $key ^ $ipad ;
+ $k_opad = $key ^ $opad;
+
+ $sha1_value = sha1($k_opad . pack("H*", sha1($k_ipad . $data)));
+
+ $hash_data = '';
+ $str = join('',explode('\x', $sha1_value));
+ $len = strlen($str);
+ for ($i = 0; $i < $len; $i += 2)
+ $hash_data .= chr(hexdec(substr($str, $i, 2)));
+ return $hash_data;
+ }
}