From 43b4bc94ab4dcd5d85a1be230b7b4d73c5f511c5 Mon Sep 17 00:00:00 2001 From: Ivan Borzenkov Date: Sun, 7 Mar 2010 22:38:11 +0300 Subject: [PATCH 1/8] reverting "use XMPPHP/ folder instead of dirname(__FILE__) which is inefficient" method whis relative path not work for lib - random current dir dirname faster and not need change include_path more info on http://stackoverflow.com/questions/2220443/whats-better-of-requiredirname-file-myparent-php-than-just-require --- XMPPHP/BOSH.php | 2 +- XMPPHP/XMLStream.php | 6 +++--- XMPPHP/XMPP.php | 4 ++-- XMPPHP/XMPP_Old.php | 2 +- examples/cli_longrun_example.php | 2 +- examples/cli_longrun_example_bosh.php | 2 +- examples/sendmessage_example.php | 2 +- examples/webclient_example.php | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/XMPPHP/BOSH.php b/XMPPHP/BOSH.php index dacb3b4..49e977d 100644 --- a/XMPPHP/BOSH.php +++ b/XMPPHP/BOSH.php @@ -27,7 +27,7 @@ */ /** XMPPHP_XMLStream */ -require_once 'XMPPHP/XMPP.php'; +require_once dirname(__FILE__) . '/XMPP.php'; /** * XMPPHP Main Class diff --git a/XMPPHP/XMLStream.php b/XMPPHP/XMLStream.php index a39e12e..cd03c96 100644 --- a/XMPPHP/XMLStream.php +++ b/XMPPHP/XMLStream.php @@ -27,13 +27,13 @@ */ /** XMPPHP_Exception */ -require_once 'XMPPHP/Exception.php'; +require_once dirname(__FILE__) . '/Exception.php'; /** XMPPHP_XMLObj */ -require_once 'XMPPHP/XMLObj.php'; +require_once dirname(__FILE__) . '/XMLObj.php'; /** XMPPHP_Log */ -require_once 'XMPPHP/Log.php'; +require_once dirname(__FILE__) . '/Log.php'; /** * XMPPHP XML Stream diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php index ffd9340..76a26ba 100644 --- a/XMPPHP/XMPP.php +++ b/XMPPHP/XMPP.php @@ -27,8 +27,8 @@ */ /** XMPPHP_XMLStream */ -require_once 'XMPPHP/XMLStream.php'; -require_once 'XMPPHP/Roster.php'; +require_once dirname(__FILE__) . '/XMLStream.php'; +require_once dirname(__FILE__) . '/Roster.php'; /** * XMPPHP Main Class diff --git a/XMPPHP/XMPP_Old.php b/XMPPHP/XMPP_Old.php index 43f56b1..6083dad 100644 --- a/XMPPHP/XMPP_Old.php +++ b/XMPPHP/XMPP_Old.php @@ -33,7 +33,7 @@ * The old Jabber protocol wasn't standardized, so use at your own risk. * */ -require_once "XMPP.php"; +require_once dirname(__FILE__) . '/XMPP.php'; class XMPPHP_XMPPOld extends XMPPHP_XMPP { /** diff --git a/examples/cli_longrun_example.php b/examples/cli_longrun_example.php index 59bb29d..e15b924 100644 --- a/examples/cli_longrun_example.php +++ b/examples/cli_longrun_example.php @@ -3,7 +3,7 @@ // activate full error reporting //error_reporting(E_ALL & E_STRICT); -include 'XMPPHP/XMPP.php'; +include dirname(dirname(__FILE__)).'/XMPPHP/XMPP.php'; #Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports #If this doesn't work, are you running 64-bit PHP with < 5.2.6? diff --git a/examples/cli_longrun_example_bosh.php b/examples/cli_longrun_example_bosh.php index 21b63f1..80da540 100644 --- a/examples/cli_longrun_example_bosh.php +++ b/examples/cli_longrun_example_bosh.php @@ -3,7 +3,7 @@ // activate full error reporting //error_reporting(E_ALL & E_STRICT); -include 'XMPPHP/BOSH.php'; +include dirname(dirname(__FILE__)).'/XMPPHP/BOSH.php'; #Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports #If this doesn't work, are you running 64-bit PHP with < 5.2.6? diff --git a/examples/sendmessage_example.php b/examples/sendmessage_example.php index e506130..60d5e6f 100644 --- a/examples/sendmessage_example.php +++ b/examples/sendmessage_example.php @@ -3,7 +3,7 @@ // activate full error reporting //error_reporting(E_ALL & E_STRICT); -include 'XMPPHP/XMPP.php'; +include dirname(dirname(__FILE__)).'/XMPPHP/XMPP.php'; #Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports #If this doesn't work, are you running 64-bit PHP with < 5.2.6? diff --git a/examples/webclient_example.php b/examples/webclient_example.php index eb40e82..fa04f7a 100644 --- a/examples/webclient_example.php +++ b/examples/webclient_example.php @@ -4,7 +4,7 @@ header('content-type', 'plain/text'); // activate full error reporting //error_reporting(E_ALL & E_STRICT); -include 'XMPPHP/BOSH.php'; +include dirname(dirname(__FILE__)).'/XMPPHP/BOSH.php'; print "
";
 
 #Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports

From 6e1b55fddf3be619cdaf8c0b084897ef8615e13a Mon Sep 17 00:00:00 2001
From: Ivan Borzenkov 
Date: Sun, 7 Mar 2010 23:31:18 +0300
Subject: [PATCH 2/8] Add to roster

---
 XMPPHP/XMPP.php | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php
index 76a26ba..88c414a 100644
--- a/XMPPHP/XMPP.php
+++ b/XMPPHP/XMPP.php
@@ -218,6 +218,41 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		#$this->send("");
 	}
 
+	/**
+	 * Add user to Roster
+	 *
+	 * @param string $jid
+	 * @param string $name
+	 */
+	public function RosterAddUser($jid, $name=null, $group=null) {
+		$payload = "\n".
+		($group?''.htmlspecialchars($group, ENT_QUOTES, 'UTF-8').'':'');
+		$this->SendIq(NULL, 'set', "jabber:iq:roster", $payload);
+	}
+
+	/**
+	 * Send ID action
+	 *
+	 * @param string $to
+	 * @param string $type
+	 * @param string $xmlns
+	 * @param string $payload
+	 * @param string $from
+	 */
+	private function sendIq($to = NULL, $type = 'get', $xmlns = NULL, $payload = NULL, $from = NULL)
+	{
+		$id = $this->getID();
+		$xml = "
+			
+				$payload
+			
+			";
+		return $this->send($xml);
+	}
+
 	/**
 	 * Message handler
 	 *

From b26491cdc944303be6a96dc532dc6487405745d8 Mon Sep 17 00:00:00 2001
From: Ivan Borzenkov 
Date: Sun, 7 Mar 2010 23:58:05 +0300
Subject: [PATCH 3/8] add patch from
 http://code.google.com/p/xmpphp/issues/detail?id=67 - Digest MD5

---
 XMPPHP/XMPP.php | 96 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php
index 88c414a..9588c13 100644
--- a/XMPPHP/XMPP.php
+++ b/XMPPHP/XMPP.php
@@ -98,6 +98,21 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 	 */
 	public $roster;
 
+	/**
+	 * @var array supported auth mechanisms
+	 */
+	protected $auth_mechanism_supported = array('PLAIN', 'DIGEST-MD5');
+
+	/**
+	 * @var string default auth mechanism
+	 */
+	protected $auth_mechanism_default = 'PLAIN';
+
+	/**
+	 * @var string prefered auth mechanism
+	 */
+	protected $auth_mechanism_preferred = 'DIGEST-MD5';
+
 	/**
 	 * Constructor
 	 *
@@ -117,6 +132,7 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		$this->password = $password;
 		$this->resource = $resource;
 		if(!$server) $server = $host;
+		$this->server = $server;
 		$this->basejid = $this->user . '@' . $this->host;
 
 		$this->roster = new Roster();
@@ -133,6 +149,8 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		$this->addXPathHandler('{jabber:client}message', 'message_handler');
 		$this->addXPathHandler('{jabber:client}presence', 'presence_handler');
 		$this->addXPathHandler('iq/{jabber:iq:roster}query', 'roster_iq_handler');
+		// For DIGEST-MD5 auth :
+		$this->addXPathHandler('{urn:ietf:params:xml:ns:xmpp-sasl}challenge', 'sasl_challenge_handler');
 	}
 
 	/**
@@ -316,7 +334,33 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		} else {
 			$this->log->log("Attempting Auth...");
 			if ($this->password) {
-			$this->send("" . base64_encode("\x00" . $this->user . "\x00" . $this->password) . "");
+				$mechanism = 'PLAIN'; // default;
+				if ($xml->hasSub('mechanisms') && $xml->sub('mechanisms')->hasSub('mechanism')) {
+					// Get the list of all available auth mechanism that we can use
+					$available = array();
+					foreach ($xml->sub('mechanisms')->subs as $sub) {
+						if ($sub->name == 'mechanism') {
+							if (in_array($sub->data, $this->auth_mechanism_supported)) {
+								$available[$sub->data] = $sub->data;
+							}
+						}
+					}
+					if (isset($available[$this->auth_mechanism_preferred])) {
+						$mechanism = $this->auth_mechanism_preferred;
+					} else {
+						// use the first available
+						$mechanism = reset($available);
+					}
+					$this->log->log("Trying $mechanism (available : " . implode(',', $available) . ')');
+				}
+				switch ($mechanism) {
+					case 'PLAIN':
+						$this->send("" . base64_encode("\x00" . $this->user . "\x00" . $this->password) . "");
+						break;
+					case 'DIGEST-MD5':
+						$this->send("");
+						break;
+				}
 			} else {
                         $this->send("");
 			}	
@@ -346,6 +390,56 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		throw new XMPPHP_Exception('Auth failed!');
 	}
 
+	/**
+	 * Handle challenges for DIGEST-MD5 auth
+	 *
+	 * @param string $xml
+	 */
+	protected function sasl_challenge_handler($xml) {
+		// Decode and parse the challenge string
+		// (may be something like foo="bar",foo2="bar2,bar3,bar4",foo3=bar5 )
+		$challenge = base64_decode($xml->data);
+		$vars = array();
+		$matches = array();
+		preg_match_all('/(\w+)=(?:"([^"]*)|([^,]*))/', $challenge, $matches);
+		$res = array();
+		foreach ($matches[1] as $k => $v) {
+			$vars[$v] = (empty($matches[2][$k])?$matches[3][$k]:$matches[2][$k]);
+		}
+
+		if (isset($vars['nonce'])) {
+			// First step
+			$vars['cnonce'] = uniqid(mt_rand(), false);
+			$vars['nc']     = '00000001';
+			$vars['qop']    = 'auth'; // Force qop to auth
+			if (!isset($vars['digest-uri'])) $vars['digest-uri'] = 'xmpp/' . $this->server;
+			if (!isset($vars['realm'])) $vars['realm'] = '';
+
+			// now, the magic...
+			$a1 = sprintf('%s:%s:%s', $this->user, $vars['realm'], $this->password);
+			if ($vars['algorithm'] == 'md5-sess') {
+				$a1 = pack('H32',md5($a1)) . ':' . $vars['nonce'] . ':' . $vars['cnonce'];
+			}
+			$a2 = "AUTHENTICATE:" . $vars['digest-uri'];
+			$password = md5($a1) . ':' . $vars['nonce'] . ':' . $vars['nc'] . ':' . $vars['cnonce'] . ':' . $vars['qop'] . ':' .md5($a2);
+			$password = md5($password);
+			$response = sprintf('username="%s",realm="%s",nonce="%s",cnonce="%s",nc=%s,qop=%s,digest-uri="%s",response=%s,charset=utf-8',
+				$this->user, $vars['realm'], $vars['nonce'], $vars['cnonce'], $vars['nc'], $vars['qop'], $vars['digest-uri'], $password);
+
+			// Send the response
+			$response = base64_encode($response);
+			$this->send("$response");
+		} else {
+			if (isset($vars['rspauth'])) {
+				// Second step
+				$this->send("");
+			} else {
+				$this->log->log("ERROR receiving challenge : " . $challenge, XMPPHP_Log::LEVEL_ERROR);
+			}
+
+		}
+	}
+
 	/**
 	 * Resource bind handler
 	 *

From 7d2ef0ee95c59cdceaa7c4dc0bd0c0d41e9938c1 Mon Sep 17 00:00:00 2001
From: Ivan Borzenkov 
Date: Mon, 8 Mar 2010 00:49:54 +0300
Subject: [PATCH 4/8] remove stream non-blocking - any micro timeout break
 connection

---
 XMPPHP/XMLStream.php | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/XMPPHP/XMLStream.php b/XMPPHP/XMLStream.php
index cd03c96..0ffec4d 100644
--- a/XMPPHP/XMLStream.php
+++ b/XMPPHP/XMLStream.php
@@ -457,15 +457,7 @@ class XMPPHP_XMLStream {
 			} else if ($updated > 0) {
 				$buff = '';
 				do {
-					if ($buff != '') {
-						//disable blocking for now because fread() will
-						// block until the 4k are full if we already
-						// read a part of the packet
-						stream_set_blocking($this->socket, 0);
-					}
 					$part = fread($this->socket, 4096);
-					stream_set_blocking($this->socket, 1);
-
 					if (!$part) {
 						if($this->reconnect) {
 							$this->doReconnect();

From 6abf075531c048fd8a2bc6148f77b4fd2755964c Mon Sep 17 00:00:00 2001
From: Ivan Borzenkov 
Date: Tue, 9 Mar 2010 19:41:38 +0300
Subject: [PATCH 5/8] add PHPDOC to adduser

---
 XMPPHP/XMPP.php | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php
index 9588c13..37c8684 100644
--- a/XMPPHP/XMPP.php
+++ b/XMPPHP/XMPP.php
@@ -239,8 +239,9 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 	/**
 	 * Add user to Roster
 	 *
-	 * @param string $jid
-	 * @param string $name
+	 * @param string $jid user jid
+	 * @param string $name user nickname
+	 * @param string $group group to add
 	 */
 	public function RosterAddUser($jid, $name=null, $group=null) {
 		$payload = "\n".
@@ -251,11 +252,11 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 	/**
 	 * Send ID action
 	 *
-	 * @param string $to
-	 * @param string $type
-	 * @param string $xmlns
-	 * @param string $payload
-	 * @param string $from
+	 * @param string $to to jid
+	 * @param string $type type of ID
+	 * @param string $xmlns xmlns name
+	 * @param string $payload payload string
+	 * @param string $from from jid
 	 */
 	private function sendIq($to = NULL, $type = 'get', $xmlns = NULL, $payload = NULL, $from = NULL)
 	{

From eb08b045c3b00ea77e4f5098468af3ed57a8f723 Mon Sep 17 00:00:00 2001
From: Ivan Borzenkov 
Date: Wed, 10 Mar 2010 00:01:19 +0300
Subject: [PATCH 6/8] Return stream_blocking and add false check

---
 XMPPHP/XMLStream.php | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/XMPPHP/XMLStream.php b/XMPPHP/XMLStream.php
index 0ffec4d..d818881 100644
--- a/XMPPHP/XMLStream.php
+++ b/XMPPHP/XMLStream.php
@@ -457,8 +457,15 @@ class XMPPHP_XMLStream {
 			} else if ($updated > 0) {
 				$buff = '';
 				do {
+					if ($buff != '') {
+						//disable blocking for now because fread() will
+						// block until the 4k are full if we already
+						// read a part of the packet
+						stream_set_blocking($this->socket, 0);
+					}
 					$part = fread($this->socket, 4096);
-					if (!$part) {
+					stream_set_blocking($this->socket, 1);
+					if ($part === false) {
 						if($this->reconnect) {
 							$this->doReconnect();
 						} else {

From 8cf43499f4f98e7a32123cb95371d906dafaa965 Mon Sep 17 00:00:00 2001
From: Superwayne 
Date: Wed, 14 Apr 2010 19:35:05 +0200
Subject: [PATCH 7/8] fix: $priority is not set if $show is "available" or
 $status is omitted

---
 XMPPHP/XMPP.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php
index ffd9340..0a442bd 100644
--- a/XMPPHP/XMPP.php
+++ b/XMPPHP/XMPP.php
@@ -196,7 +196,7 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		$out = "
Date: Wed, 14 Apr 2010 21:05:11 +0200
Subject: [PATCH 8/8] fix: cannot set priority to 0 if status message is
 omitted or $show is set to "available"

---
 XMPPHP/XMPP.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/XMPPHP/XMPP.php b/XMPPHP/XMPP.php
index 0a442bd..9b5e398 100644
--- a/XMPPHP/XMPP.php
+++ b/XMPPHP/XMPP.php
@@ -196,7 +196,7 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
 		$out = "