mirror of
https://github.com/phpbb/phpbb.git
synced 2025-02-23 03:19:01 +01:00
- removed not utilized user_allow_email column from schema - removed inactive groups (they had no use at all, since inactive users are not able to login) The only benefit those brought are distinguish users - but this is no longer needed too due to the inactive code present. This also allows us to retain group memberships as well as default settings for users being set inactive due to profile changes. - rewrote user_active_flip to support multiple users and a mode, as well as coping with the aforementioned changes - implemented updated jabber class to support SRV server records and for better jabberd2 support. - jabber errors now logged to the error log with a full transaction - fixed user_delete calls to include usernames where possible and also update last post information correctly - implemented additioal checks to user management to cope with common mistakes - On installation, guess the required mysql schema as best as possible. Users now only need to decide if they want to use the mysqli extension or not (mysqli selected by default) and no longer need to know their mysql version. - founders do not need to re-activate their account on profile changes - remove older session if re-authentication was successful (re-authentication always assigns a new session id) - set the cookie directly instead of using php's function - added inactive_remind to see which users got deactivated because of reminders (or re-activation) sent out hopefully not introduced too many bugs - those testing with CVS releases, please concentrate on user registration, activation, profile changes (email/password)... git-svn-id: file:///svn/phpbb/trunk@6436 89ea8834-ac86-4346-8a33-228a782c2dd0
1493 lines
34 KiB
PHP
1493 lines
34 KiB
PHP
<?php
|
|
/**
|
|
*
|
|
* @package phpBB3
|
|
* @version $Id$
|
|
* @copyright (c) 2006 phpBB Group
|
|
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
*
|
|
*/
|
|
|
|
/**
|
|
*
|
|
* Class.Jabber.PHP v0.4.2
|
|
* (c) 2004 Nathan "Fritzy" Fritz
|
|
* http://cjphp.netflint.net *** fritzy@netflint.net
|
|
*
|
|
* This is a bugfix version, specifically for those who can't get
|
|
* 0.4 to work on Jabberd2 servers.
|
|
*
|
|
* last modified: 24.03.2004 13:01:53
|
|
*
|
|
* Modified by phpBB Development Team
|
|
* version: v0.4.3a
|
|
*
|
|
* @package phpBB3
|
|
*/
|
|
class jabber
|
|
{
|
|
var $server;
|
|
var $port;
|
|
var $username;
|
|
var $password;
|
|
var $resource;
|
|
var $jid;
|
|
|
|
var $connection;
|
|
var $delay_disconnect;
|
|
|
|
var $stream_id;
|
|
|
|
var $enable_logging;
|
|
var $log_array;
|
|
|
|
var $iq_sleep_timer;
|
|
var $last_ping_time;
|
|
|
|
var $packet_queue;
|
|
|
|
var $iq_version_name;
|
|
var $iq_version_os;
|
|
var $iq_version_version;
|
|
|
|
var $error_codes;
|
|
|
|
var $connected;
|
|
var $keep_alive_id;
|
|
var $returned_keep_alive;
|
|
var $txnid;
|
|
|
|
var $connector;
|
|
|
|
/**
|
|
* Constructor
|
|
*/
|
|
function jabber($server, $port, $username, $password, $resource)
|
|
{
|
|
$this->server = ($server) ? $server : 'localhost';
|
|
$this->port = ($port) ? $port : '5222';
|
|
$this->username = $username;
|
|
$this->password = $password;
|
|
$this->resource = ($resource) ? $resource : NULL;
|
|
|
|
$this->enable_logging = true;
|
|
$this->log_array = array();
|
|
|
|
$this->packet_queue = array();
|
|
$this->iq_sleep_timer = $this->delay_disconnect = 1;
|
|
|
|
$this->returned_keep_alive = true;
|
|
$this->txnid = 0;
|
|
|
|
$this->iq_version_name = "Class.Jabber.PHP -- http://cjphp.netflint.net -- by Nathan 'Fritzy' Fritz, fritz@netflint.net";
|
|
$this->iq_version_version = '0.4';
|
|
$this->iq_version_os = $_SERVER['SERVER_SOFTWARE'];
|
|
|
|
$this->error_codes = array(
|
|
400 => 'Bad Request',
|
|
401 => 'Unauthorized',
|
|
402 => 'Payment Required',
|
|
403 => 'Forbidden',
|
|
404 => 'Not Found',
|
|
405 => 'Not Allowed',
|
|
406 => 'Not Acceptable',
|
|
407 => 'Registration Required',
|
|
408 => 'Request Timeout',
|
|
409 => 'Conflict',
|
|
500 => 'Internal Server Error',
|
|
501 => 'Not Implemented',
|
|
502 => 'Remove Server Error',
|
|
503 => 'Service Unavailable',
|
|
504 => 'Remove Server Timeout',
|
|
510 => 'Disconnected'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Connect
|
|
*/
|
|
function connect()
|
|
{
|
|
$this->connector = new cjp_standard_connector;
|
|
|
|
if ($this->connector->open_socket($this->server, $this->port))
|
|
{
|
|
$this->send_packet("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
|
$this->send_packet("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
|
|
|
sleep(2);
|
|
|
|
if ($this->_check_connected())
|
|
{
|
|
$this->connected = true; // Nathan Fritz
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: connect() #1');
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: connect() #2');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disconnect
|
|
*/
|
|
function disconnect()
|
|
{
|
|
if (is_int($this->delay_disconnect))
|
|
{
|
|
sleep($this->delay_disconnect);
|
|
}
|
|
|
|
$this->send_packet('</stream:stream>');
|
|
$this->connector->close_socket();
|
|
}
|
|
|
|
/**
|
|
* Send authentication request
|
|
*/
|
|
function send_auth()
|
|
{
|
|
$this->auth_id = 'auth_' . md5(time() . $_SERVER['REMOTE_ADDR']);
|
|
$this->resource = ($this->resource != NULL) ? $this->resource : ('Class.Jabber.PHP ' . md5($this->auth_id));
|
|
$this->jid = "{$this->username}@{$this->server}/{$this->resource}";
|
|
|
|
// request available authentication methods
|
|
$payload = "<username>{$this->username}</username>";
|
|
$packet = $this->send_iq(NULL, 'get', $this->auth_id, 'jabber:iq:auth', $payload);
|
|
|
|
// was a result returned?
|
|
if ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id)
|
|
{
|
|
// yes, now check for auth method availability in descending order (best to worst)
|
|
if (isset($packet['iq']['#']['query'][0]['#']['sequence'][0]['#']) && isset($packet['iq']['#']['query'][0]['#']['token'][0]['#']))
|
|
{
|
|
// auth_0k
|
|
return $this->_sendauth_ok($packet['iq']['#']['query'][0]['#']['token'][0]['#'], $packet['iq']['#']['query'][0]['#']['sequence'][0]['#']);
|
|
}
|
|
else if (isset($packet['iq']['#']['query'][0]['#']['digest']))
|
|
{
|
|
// digest
|
|
return $this->_sendauth_digest();
|
|
}
|
|
else if ($packet['iq']['#']['query'][0]['#']['password'])
|
|
{
|
|
// plain text
|
|
return $this->_sendauth_plaintext();
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_auth() #2 - No auth method available!');
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// no result returned
|
|
$this->add_to_log('ERROR: send_auth() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register account
|
|
*/
|
|
function account_registration($reg_email = NULL, $reg_name = NULL)
|
|
{
|
|
$packet = $this->send_iq($this->server, 'get', 'reg_01', 'jabber:iq:register');
|
|
|
|
if ($packet)
|
|
{
|
|
// just in case a key was passed back from the server
|
|
$key = $this->get_info_from_iq_key($packet);
|
|
unset($packet);
|
|
|
|
$payload = "<username>{$this->username}</username>
|
|
<password>{$this->password}</password>
|
|
<email>$reg_email</email>
|
|
<name>$reg_name</name>\n";
|
|
|
|
$payload .= ($key) ? "<key>$key</key>\n" : '';
|
|
|
|
$packet = $this->send_iq($this->server, 'set', 'reg_01', 'jabber:iq:register', $payload);
|
|
|
|
if ($this->get_info_from_iq_type($packet) == 'result')
|
|
{
|
|
$return_code = (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#'])) ? 1 : 2;
|
|
$this->jid = ($this->resource) ? "{$this->username}@{$this->server}/{$this->resource}" : "{$this->username}@{$this->server}";
|
|
}
|
|
else if ($this->get_info_from_iq_type($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#']))
|
|
{
|
|
// "conflict" error, i.e. already registered
|
|
if ($packet['iq']['#']['error'][0]['@']['code'] == '409')
|
|
{
|
|
$return_code = 1;
|
|
}
|
|
else
|
|
{
|
|
$return_code = 'Error ' . $packet['iq']['#']['error'][0]['@']['code'] . ': ' . $packet['iq']['#']['error'][0]['#'];
|
|
}
|
|
}
|
|
|
|
return $return_code;
|
|
}
|
|
else
|
|
{
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Change password
|
|
*/
|
|
function change_password($new_password)
|
|
{
|
|
$packet = $this->send_iq($this->server, 'get', 'A0', 'jabber:iq:register');
|
|
|
|
if ($packet)
|
|
{
|
|
// just in case a key was passed back from the server
|
|
$key = $this->get_info_from_iq_key($packet);
|
|
unset($packet);
|
|
|
|
$payload = "<username>{$this->username}</username>
|
|
<password>{$new_password}</password>\n";
|
|
$payload .= ($key) ? "<key>$key</key>\n" : '';
|
|
|
|
$packet = $this->send_iq($this->server, 'set', 'A0', 'jabber:iq:register', $payload);
|
|
|
|
if ($this->get_info_from_iq_type($packet) == 'result')
|
|
{
|
|
$return_code = (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#'])) ? 1 : 2;
|
|
}
|
|
else if ($this->get_info_from_iq_type($packet) == 'error' && isset($packet['iq']['#']['error'][0]['#']))
|
|
{
|
|
// "conflict" error, i.e. already registered
|
|
if ($packet['iq']['#']['error'][0]['@']['code'] == '409')
|
|
{
|
|
$return_code = 1;
|
|
}
|
|
else
|
|
{
|
|
$return_code = 'Error ' . $packet['iq']['#']['error'][0]['@']['code'] . ': ' . $packet['iq']['#']['error'][0]['#'];
|
|
}
|
|
}
|
|
|
|
return $return_code;
|
|
}
|
|
else
|
|
{
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send packet
|
|
*/
|
|
function send_packet($xml)
|
|
{
|
|
$xml = trim($xml);
|
|
|
|
if ($this->connector->write_to_socket($xml))
|
|
{
|
|
$this->add_to_log('SEND: ' . $xml);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_packet() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listen to socket
|
|
*/
|
|
function listen()
|
|
{
|
|
$incoming = '';
|
|
|
|
while ($line = $this->connector->read_from_socket(4096))
|
|
{
|
|
$incoming .= $line;
|
|
}
|
|
|
|
$incoming = trim($incoming);
|
|
|
|
if ($incoming != '')
|
|
{
|
|
$this->add_to_log('RECV: ' . $incoming);
|
|
$temp = $this->_split_incoming($incoming);
|
|
|
|
for ($i = 0, $size = sizeof($temp); $i < $size; $i++)
|
|
{
|
|
$this->packet_queue[] = $this->xmlize($temp[$i]);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Strip jid
|
|
*/
|
|
function strip_jid($jid = NULL)
|
|
{
|
|
preg_match('#(.*)\/(.*)#Ui', $jid, $temp);
|
|
return ($temp[1] != '') ? $temp[1] : $jid;
|
|
}
|
|
|
|
/**
|
|
* Send a message
|
|
*/
|
|
function send_message($to, $type = 'normal', $id = NULL, $content = NULL, $payload = NULL)
|
|
{
|
|
if ($to && is_array($content))
|
|
{
|
|
if (!$id)
|
|
{
|
|
$id = $type . '_' . time();
|
|
}
|
|
|
|
$this->_array_xmlspecialchars($content);
|
|
|
|
$xml = "<message to='$to' type='$type' id='$id'>\n";
|
|
|
|
if (!empty($content['subject']))
|
|
{
|
|
$xml .= '<subject>' . $content['subject'] . "</subject>\n";
|
|
}
|
|
|
|
if (!empty($content['thread']))
|
|
{
|
|
$xml .= '<thread>' . $content['thread'] . "</thread>\n";
|
|
}
|
|
|
|
$xml .= '<body>' . $content['body'] . "</body>\n";
|
|
$xml .= $payload;
|
|
$xml .= "</message>\n";
|
|
|
|
if ($this->send_packet($xml))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_message() #1');
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_message() #2');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send presence
|
|
*/
|
|
function send_presence($type = NULL, $to = NULL, $status = NULL, $show = NULL, $priority = NULL)
|
|
{
|
|
$xml = '<presence';
|
|
$xml .= ($to) ? " to='$to'" : '';
|
|
$xml .= ($type) ? " type='$type'" : '';
|
|
$xml .= ($status || $show || $priority) ? ">\n" : " />\n";
|
|
|
|
$xml .= ($status) ? " <status>$status</status>\n" : '';
|
|
$xml .= ($show) ? " <show>$show</show>\n" : '';
|
|
$xml .= ($priority) ? " <priority>$priority</priority>\n" : '';
|
|
|
|
$xml .= ($status || $show || $priority) ? "</presence>\n" : '';
|
|
|
|
if ($this->send_packet($xml))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_presence() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send error
|
|
*/
|
|
function send_error($to, $id = NULL, $error_number, $error_message = NULL)
|
|
{
|
|
$xml = "<iq type='error' to='$to'";
|
|
$xml .= ($id) ? " id='$id'" : '';
|
|
$xml .= ">\n";
|
|
$xml .= " <error code='$error_number'>";
|
|
$xml .= ($error_message) ? $error_message : $this->error_codes[$error_number];
|
|
$xml .= "</error>\n";
|
|
$xml .= '</iq>';
|
|
|
|
$this->send_packet($xml);
|
|
}
|
|
|
|
/**
|
|
* Get first from queue
|
|
*/
|
|
function get_first_from_queue()
|
|
{
|
|
return array_shift($this->packet_queue);
|
|
}
|
|
|
|
/**
|
|
* Get from queue by id
|
|
*/
|
|
function get_from_queue_by_id($packet_type, $id)
|
|
{
|
|
$found_message = false;
|
|
|
|
foreach ($this->packet_queue as $key => $value)
|
|
{
|
|
if ($value[$packet_type]['@']['id'] == $id)
|
|
{
|
|
$found_message = $value;
|
|
unset($this->packet_queue[$key]);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (is_array($found_message)) ? $found_message : false;
|
|
}
|
|
|
|
/**
|
|
* Call handler
|
|
*/
|
|
function call_handler($packet = NULL)
|
|
{
|
|
$packet_type = $this->_get_packet_type($packet);
|
|
|
|
if ($packet_type == 'message')
|
|
{
|
|
$type = $packet['message']['@']['type'];
|
|
$type = ($type != '') ? $type : 'normal';
|
|
$funcmeth = "handler_message_$type";
|
|
}
|
|
else if ($packet_type == 'iq')
|
|
{
|
|
$namespace = $packet['iq']['#']['query'][0]['@']['xmlns'];
|
|
$namespace = str_replace(':', '_', $namespace);
|
|
$funcmeth = "handler_iq_$namespace";
|
|
}
|
|
else if ($packet_type == 'presence')
|
|
{
|
|
$type = $packet['presence']['@']['type'];
|
|
$type = ($type != '') ? $type : 'available';
|
|
$funcmeth = "handler_presence_$type";
|
|
}
|
|
|
|
if ($funcmeth != '')
|
|
{
|
|
if (function_exists($funcmeth))
|
|
{
|
|
call_user_func($funcmeth, $packet);
|
|
}
|
|
else if (method_exists($this, $funcmeth))
|
|
{
|
|
call_user_func(array(&$this, $funcmeth), $packet);
|
|
}
|
|
else
|
|
{
|
|
$this->handler_not_implemented($packet);
|
|
$this->add_to_log("ERROR: call_handler() #1 - neither method nor function $funcmeth() available");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cruise Control
|
|
*/
|
|
function cruise_control($seconds = -1)
|
|
{
|
|
$count = 0;
|
|
|
|
while ($count != $seconds)
|
|
{
|
|
$this->listen();
|
|
|
|
do
|
|
{
|
|
$packet = $this->get_first_from_queue();
|
|
|
|
if ($packet)
|
|
{
|
|
$this->call_handler($packet);
|
|
}
|
|
}
|
|
while (sizeof($this->packet_queue) > 1);
|
|
|
|
$count += 0.25;
|
|
usleep(250000);
|
|
|
|
if (($this->last_ping_time + 180) < time())
|
|
{
|
|
// Modified by Nathan Fritz
|
|
if ($this->returned_keep_alive == false)
|
|
{
|
|
$this->connected = false;
|
|
$this->add_to_log('EVENT: Disconnected');
|
|
}
|
|
|
|
if ($this->returned_keep_alive == true)
|
|
{
|
|
$this->connected = true;
|
|
}
|
|
|
|
$this->returned_keep_alive = false;
|
|
|
|
$this->keep_alive_id = 'keep_alive_' . time();
|
|
// $this->send_packet("<iq id='{$this->keep_alive_id}'/>", 'cruise_control');
|
|
$this->send_packet("<iq type='get' from='{$this->username}@{$this->server}/{$this->resource}' to='{$this->server}' id='{$this->keep_alive_id}'><query xmlns='jabber:iq:time' /></iq>");
|
|
$this->last_ping_time = time();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Send iq
|
|
*/
|
|
function send_iq($to = NULL, $type = 'get', $id = NULL, $xmlns = NULL, $payload = NULL, $from = NULL)
|
|
{
|
|
if (!preg_match('#^(get|set|result|error)$#', $type))
|
|
{
|
|
unset($type);
|
|
|
|
$this->add_to_log("ERROR: send_iq() #2 - type must be 'get', 'set', 'result' or 'error'");
|
|
return false;
|
|
}
|
|
else if ($id && $xmlns)
|
|
{
|
|
$xml = "<iq type='$type' id='$id'";
|
|
$xml .= ($to) ? " to='" . htmlspecialchars($to) . "'" : '';
|
|
$xml .= ($from) ? " from='$from'" : '';
|
|
$xml .= ">
|
|
<query xmlns='$xmlns'>
|
|
$payload
|
|
</query>
|
|
</iq>";
|
|
|
|
$this->send_packet($xml);
|
|
sleep($this->iq_sleep_timer);
|
|
$this->listen();
|
|
|
|
return (preg_match('#^(get|set)$#', $type)) ? $this->get_from_queue_by_id('iq', $id) : true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: send_iq() #1 - to, id and xmlns are mandatory');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* get the transport registration fields
|
|
* method written by Steve Blinch, http://www.blitzaffe.com
|
|
*/
|
|
function transport_registration_details($transport)
|
|
{
|
|
$this->txnid++;
|
|
$packet = $this->send_iq($transport, 'get', "reg_{$this->txnid}", 'jabber:iq:register', NULL, $this->jid);
|
|
|
|
if ($packet)
|
|
{
|
|
$res = array();
|
|
|
|
foreach ($packet['iq']['#']['query'][0]['#'] as $element => $data)
|
|
{
|
|
if ($element != 'instructions' && $element != 'key')
|
|
{
|
|
$res[] = $element;
|
|
}
|
|
}
|
|
|
|
return $res;
|
|
}
|
|
else
|
|
{
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* register with the transport
|
|
* method written by Steve Blinch, http://www.blitzaffe.com
|
|
*/
|
|
function transport_registration($transport, $details)
|
|
{
|
|
$this->txnid++;
|
|
$packet = $this->send_iq($transport, 'get', "reg_{$this->txnid}", 'jabber:iq:register', NULL, $this->jid);
|
|
|
|
if ($packet)
|
|
{
|
|
// just in case a key was passed back from the server
|
|
$key = $this->get_info_from_iq_key($packet);
|
|
unset($packet);
|
|
|
|
$payload = ($key) ? "<key>$key</key>\n" : '';
|
|
foreach ($details as $element => $value)
|
|
{
|
|
$payload .= "<$element>$value</$element>\n";
|
|
}
|
|
|
|
$packet = $this->send_iq($transport, 'set', "reg_{$this->txnid}", 'jabber:iq:register', $payload);
|
|
|
|
if ($this->get_info_from_iq_type($packet) == 'result')
|
|
{
|
|
$return_code = (isset($packet['iq']['#']['query'][0]['#']['registered'][0]['#'])) ? 1 : 2;
|
|
}
|
|
else if ($this->get_info_from_iq_type($packet) == 'error')
|
|
{
|
|
if (isset($packet['iq']['#']['error'][0]['#']))
|
|
{
|
|
$return_code = 'Error ' . $packet['iq']['#']['error'][0]['@']['code'] . ': ' . $packet['iq']['#']['error'][0]['#'];
|
|
$this->add_to_log('ERROR: transport_registration()');
|
|
}
|
|
}
|
|
|
|
return $return_code;
|
|
}
|
|
else
|
|
{
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return log
|
|
*/
|
|
function get_log()
|
|
{
|
|
if ($this->enable_logging && sizeof($this->log_array))
|
|
{
|
|
return implode("\n\n", $this->log_array);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Add information to log
|
|
*/
|
|
function add_to_log($string)
|
|
{
|
|
if ($this->enable_logging)
|
|
{
|
|
$this->log_array[] = htmlspecialchars($string);
|
|
}
|
|
}
|
|
|
|
|
|
// ======================================================================
|
|
// private methods
|
|
// ======================================================================
|
|
|
|
/**
|
|
* Send auth
|
|
* @access private
|
|
*/
|
|
function _sendauth_ok($zerok_token, $zerok_sequence)
|
|
{
|
|
// initial hash of password
|
|
$zerok_hash = sha1($this->password);
|
|
|
|
// sequence 0: hash of hashed-password and token
|
|
$zerok_hash = sha1($zerok_hash . $zerok_token);
|
|
|
|
// repeat as often as needed
|
|
for ($i = 0; $i < $zerok_sequence; $i++)
|
|
{
|
|
$zerok_hash = sha1($zerok_hash);
|
|
}
|
|
|
|
$payload = "<username>{$this->username}</username>
|
|
<hash>$zerok_hash</hash>
|
|
<resource>{$this->resource}</resource>";
|
|
|
|
$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
|
|
|
|
// was a result returned?
|
|
if ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: _sendauth_ok() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send auth digest
|
|
* @access private
|
|
*/
|
|
function _sendauth_digest()
|
|
{
|
|
$payload = "<username>{$this->username}</username>
|
|
<resource>{$this->resource}</resource>
|
|
<digest>" . sha1($this->stream_id . $this->password) . "</digest>";
|
|
|
|
$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
|
|
|
|
// was a result returned?
|
|
if ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: _sendauth_digest() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Send auth plain
|
|
* @access private
|
|
*/
|
|
function _sendauth_plaintext()
|
|
{
|
|
$payload = "<username>{$this->username}</username>
|
|
<password>{$this->password}</password>
|
|
<resource>{$this->resource}</resource>";
|
|
|
|
$packet = $this->send_iq(NULL, 'set', $this->auth_id, 'jabber:iq:auth', $payload);
|
|
|
|
// was a result returned?
|
|
if ($this->get_info_from_iq_type($packet) == 'result' && $this->get_info_from_iq_id($packet) == $this->auth_id)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: _sendauth_plaintext() #1');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Listen on socket
|
|
* @access private
|
|
*/
|
|
function _listen_incoming()
|
|
{
|
|
$incoming = '';
|
|
|
|
while ($line = $this->connector->read_from_socket(4096))
|
|
{
|
|
$incoming .= $line;
|
|
}
|
|
|
|
$incoming = trim($incoming);
|
|
|
|
if ($incoming != '')
|
|
{
|
|
$this->add_to_log('RECV: ' . $incoming);
|
|
}
|
|
|
|
return $this->xmlize($incoming);
|
|
}
|
|
|
|
/**
|
|
* Check if connected
|
|
* @access private
|
|
*/
|
|
function _check_connected()
|
|
{
|
|
$incoming_array = $this->_listen_incoming();
|
|
|
|
if (is_array($incoming_array))
|
|
{
|
|
if ($incoming_array['stream:stream']['@']['from'] == $this->server && $incoming_array['stream:stream']['@']['xmlns'] == 'jabber:client' && $incoming_array['stream:stream']['@']['xmlns:stream'] == 'http://etherx.jabber.org/streams')
|
|
{
|
|
$this->stream_id = $incoming_array['stream:stream']['@']['id'];
|
|
|
|
if ($incoming_array['stream:stream']['#']['stream:features'][0]['#']['starttls'][0]['@']['xmlns'] == 'urn:ietf:params:xml:ns:xmpp-tls')
|
|
{
|
|
return $this->_starttls();
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: _check_connected() #1');
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$this->add_to_log('ERROR: _check_connected() #2');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Start TLS/SSL session if supported (PHP5.1)
|
|
* @access private
|
|
*/
|
|
function _starttls()
|
|
{
|
|
if (!function_exists('stream_socket_enable_crypto') || !function_exists('stream_get_meta_data') || !function_exists('socket_set_blocking'))
|
|
{
|
|
$this->add_to_log('WARNING: TLS is not available');
|
|
return true;
|
|
}
|
|
|
|
$this->send_packet("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\n");
|
|
sleep(2);
|
|
$incoming_array = $this->_listen_incoming();
|
|
|
|
if (!is_array($incoming_array))
|
|
{
|
|
$this->add_to_log('ERROR: _starttls() #1');
|
|
return false;
|
|
}
|
|
|
|
if ($incoming_array['proceed']['@']['xmlns'] != 'urn:ietf:params:xml:ns:xmpp-tls')
|
|
{
|
|
$this->add_to_log('ERROR: _starttls() #2');
|
|
return false;
|
|
}
|
|
|
|
$meta = stream_get_meta_data($this->connector->active_socket);
|
|
socket_set_blocking($this->connector->active_socket, 1);
|
|
|
|
if (!stream_socket_enable_crypto($this->connector->active_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT))
|
|
{
|
|
socket_set_blocking($this->connector->active_socket, $meta['blocked']);
|
|
$this->add_to_log('ERROR: _starttls() #3');
|
|
return false;
|
|
}
|
|
socket_set_blocking($this->connector->active_socket, $meta['blocked']);
|
|
|
|
$this->send_packet("<?xml version='1.0' encoding='UTF-8' ?" . ">\n");
|
|
$this->send_packet("<stream:stream to='{$this->server}' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>\n");
|
|
sleep(2);
|
|
|
|
if (!$this->_check_connected())
|
|
{
|
|
$this->add_to_log('ERROR: _starttls() #4');
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get packet type
|
|
* @access private
|
|
*/
|
|
function _get_packet_type($packet = NULL)
|
|
{
|
|
if (is_array($packet))
|
|
{
|
|
reset($packet);
|
|
$packet_type = key($packet);
|
|
}
|
|
|
|
return ($packet_type) ? $packet_type : false;
|
|
}
|
|
|
|
/**
|
|
* Split incoming packet
|
|
* @access private
|
|
*/
|
|
function _split_incoming($incoming)
|
|
{
|
|
$temp = preg_split('#<(message|iq|presence|stream)#', $incoming, -1, PREG_SPLIT_DELIM_CAPTURE);
|
|
$array = array();
|
|
|
|
for ($i = 1, $size = sizeof($temp); $i < $size; $i += 2)
|
|
{
|
|
$array[] = '<' . $temp[$i] . $temp[($i + 1)];
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* Recursively prepares the strings in an array to be used in XML data.
|
|
* @access private
|
|
*/
|
|
function _array_xmlspecialchars(&$array)
|
|
{
|
|
if (is_array($array))
|
|
{
|
|
foreach ($array as $k => $v)
|
|
{
|
|
if (is_array($v))
|
|
{
|
|
$this->_array_xmlspecialchars($array[$k]);
|
|
}
|
|
else
|
|
{
|
|
$this->_xmlspecialchars($array[$k]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prepares a string for usage in XML data.
|
|
* @access private
|
|
*/
|
|
function _xmlspecialchars(&$string)
|
|
{
|
|
// we only have a few entities in xml
|
|
$string = str_replace(array('&', '>', '<', '"', '\''), array('&', '>', '<', '"', '''), $string);
|
|
}
|
|
|
|
// ======================================================================
|
|
// <message/> parsers
|
|
// ======================================================================
|
|
|
|
/**
|
|
* Get info from message (from)
|
|
*/
|
|
function get_info_from_message_from($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['@']['from'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (type)
|
|
*/
|
|
function get_info_from_message_type($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['@']['type'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (id)
|
|
*/
|
|
function get_info_from_message_id($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['@']['id'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (thread)
|
|
*/
|
|
function get_info_from_message_thread($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['#']['thread'][0]['#'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (subject)
|
|
*/
|
|
function get_info_from_message_subject($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['#']['subject'][0]['#'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (body)
|
|
*/
|
|
function get_info_from_message_body($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['#']['body'][0]['#'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (xmlns)
|
|
*/
|
|
function get_info_from_message_xmlns($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['message']['#']['x'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from message (error)
|
|
*/
|
|
function get_info_from_message_error($packet = NULL)
|
|
{
|
|
$error = preg_replace('#^\/$#', '', ($packet['message']['#']['error'][0]['@']['code'] . '/' . $packet['message']['#']['error'][0]['#']));
|
|
return (is_array($packet)) ? $error : false;
|
|
}
|
|
|
|
// ======================================================================
|
|
// <iq/> parsers
|
|
// ======================================================================
|
|
|
|
/**
|
|
* Get info from iq (from)
|
|
*/
|
|
function get_info_from_iq_from($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['iq']['@']['from'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from iq (type)
|
|
*/
|
|
function get_info_from_iq_type($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['iq']['@']['type'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from iq (id)
|
|
*/
|
|
function get_info_from_iq_id($packet = NULL)
|
|
{
|
|
return (is_array($packet)) ? $packet['iq']['@']['id'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from iq (key)
|
|
*/
|
|
function get_info_from_iq_key($packet = NULL)
|
|
{
|
|
return (is_array($packet) && isset($packet['iq']['#']['query'][0]['#']['key'][0]['#'])) ? $packet['iq']['#']['query'][0]['#']['key'][0]['#'] : false;
|
|
}
|
|
|
|
/**
|
|
* Get info from iq (error)
|
|
*/
|
|
function get_info_from_iq_error($packet = NULL)
|
|
{
|
|
$error = preg_replace('#^\/$#', '', ($packet['iq']['#']['error'][0]['@']['code'] . '/' . $packet['iq']['#']['error'][0]['#']));
|
|
return (is_array($packet)) ? $error : false;
|
|
}
|
|
|
|
// ======================================================================
|
|
// <message/> handlers
|
|
// ======================================================================
|
|
|
|
/**
|
|
* Message type normal
|
|
*/
|
|
function handler_message_normal($packet)
|
|
{
|
|
$from = $packet['message']['@']['from'];
|
|
$this->add_to_log("EVENT: Message (type normal) from $from");
|
|
}
|
|
|
|
/**
|
|
* Message type chat
|
|
*/
|
|
function handler_message_chat($packet)
|
|
{
|
|
$from = $packet['message']['@']['from'];
|
|
$this->add_to_log("EVENT: Message (type chat) from $from");
|
|
}
|
|
|
|
/**
|
|
* Message type groupchat
|
|
*/
|
|
function handler_message_groupchat($packet)
|
|
{
|
|
$from = $packet['message']['@']['from'];
|
|
$this->add_to_log("EVENT: Message (type groupchat) from $from");
|
|
}
|
|
|
|
/**
|
|
* Message type headline
|
|
*/
|
|
function handler_message_headline($packet)
|
|
{
|
|
$from = $packet['message']['@']['from'];
|
|
$this->add_to_log("EVENT: Message (type headline) from $from");
|
|
}
|
|
|
|
/**
|
|
* Message type error
|
|
*/
|
|
function handler_message_error($packet)
|
|
{
|
|
$from = $packet['message']['@']['from'];
|
|
$this->add_to_log("EVENT: Message (type error) from $from");
|
|
}
|
|
|
|
// ======================================================================
|
|
// <iq/> handlers
|
|
// ======================================================================
|
|
|
|
/**
|
|
* application version updates
|
|
*/
|
|
function handler_iq_jabber_iq_autoupdate($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:autoupdate from $from");
|
|
}
|
|
|
|
/**
|
|
* interactive server component properties
|
|
*/
|
|
function handler_iq_jabber_iq_agent($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:agent from $from");
|
|
}
|
|
|
|
/**
|
|
* method to query interactive server components
|
|
*/
|
|
function handler_iq_jabber_iq_agents($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:agents from $from");
|
|
}
|
|
|
|
/**
|
|
* simple client authentication
|
|
*/
|
|
function handler_iq_jabber_iq_auth($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:auth from $from");
|
|
}
|
|
|
|
/**
|
|
* out of band data
|
|
*/
|
|
function handler_iq_jabber_iq_oob($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:oob from $from");
|
|
}
|
|
|
|
/**
|
|
* method to store private data on the server
|
|
*/
|
|
function handler_iq_jabber_iq_private($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:private from $from");
|
|
}
|
|
|
|
/**
|
|
* method for interactive registration
|
|
*/
|
|
function handler_iq_jabber_iq_register($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:register from $from");
|
|
}
|
|
|
|
/**
|
|
* client roster management
|
|
*/
|
|
function handler_iq_jabber_iq_roster($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:roster from $from");
|
|
}
|
|
|
|
/**
|
|
* method for searching a user database
|
|
*/
|
|
function handler_iq_jabber_iq_search($packet)
|
|
{
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: jabber:iq:search from $from");
|
|
}
|
|
|
|
/**
|
|
* method for requesting the current time
|
|
*/
|
|
function handler_iq_jabber_iq_time($packet)
|
|
{
|
|
if ($this->keep_alive_id == $this->get_info_from_iq_id($packet))
|
|
{
|
|
$this->returned_keep_alive = true;
|
|
$this->connected = true;
|
|
|
|
$this->add_to_log('EVENT: Keep-Alive returned, connection alive.');
|
|
}
|
|
|
|
$type = $this->get_info_from_iq_type($packet);
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
$id = ($id != '') ? $id : 'time_' . time();
|
|
|
|
if ($type == 'get')
|
|
{
|
|
$payload = '<utc>' . gmdate("Ydm\TH:i:s") . '</utc><tz>' . date('T') . '</tz><display>' . date("Y/d/m h:i:s A") . '</display>';
|
|
$this->send_iq($from, 'result', $id, 'jabber:iq:time', $payload);
|
|
}
|
|
|
|
$this->add_to_log("EVENT: jabber:iq:time (type $type) from $from");
|
|
}
|
|
|
|
/**
|
|
*/
|
|
function handler_iq_error($packet)
|
|
{
|
|
// We'll do something with these later. This is a placeholder so that errors don't bounce back and forth.
|
|
}
|
|
|
|
/**
|
|
* method for requesting version
|
|
*/
|
|
function handler_iq_jabber_iq_version($packet)
|
|
{
|
|
$type = $this->get_info_from_iq_type($packet);
|
|
$from = $this->get_info_from_iq_from($packet);
|
|
$id = $this->get_info_from_iq_id($packet);
|
|
$id = ($id != '') ? $id : 'version_' . time();
|
|
|
|
if ($type == 'get')
|
|
{
|
|
$payload = "<name>{$this->iq_version_name}</name>
|
|
<os>{$this->iq_version_os}</os>
|
|
<version>{$this->iq_version_version}</version>";
|
|
|
|
//$this->SendIq($from, 'result', $id, "jabber:iq:version", $payload);
|
|
}
|
|
|
|
$this->add_to_log("EVENT: jabber:iq:version (type $type) from $from -- DISABLED");
|
|
}
|
|
|
|
// ======================================================================
|
|
// Generic handlers
|
|
// ======================================================================
|
|
|
|
/**
|
|
* Generic handler for unsupported requests
|
|
*/
|
|
function handler_not_implemented($packet)
|
|
{
|
|
$packet_type = $this->_get_packet_type($packet);
|
|
$from = call_user_func(array(&$this, 'get_info_from_' . strtolower($packet_type) . '_from'), $packet);
|
|
$id = call_user_func(array(&$this, 'get_info_from_' . strtolower($packet_type) . '_id'), $packet);
|
|
|
|
$this->send_error($from, $id, 501);
|
|
$this->add_to_log("EVENT: Unrecognized <$packet_type/> from $from");
|
|
}
|
|
|
|
// ======================================================================
|
|
// Third party code
|
|
// m@d pr0ps to the coders ;)
|
|
// ======================================================================
|
|
|
|
/**
|
|
* xmlize()
|
|
* @author Hans Anderson
|
|
* @copyright Hans Anderson / http://www.hansanderson.com/php/xml/
|
|
*/
|
|
function xmlize($data, $skip_white = 1, $encoding = 'UTF-8')
|
|
{
|
|
$data = trim($data);
|
|
|
|
$vals = $index = $array = array();
|
|
$parser = xml_parser_create($encoding);
|
|
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
|
|
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $skip_white);
|
|
xml_parse_into_struct($parser, $data, $vals, $index);
|
|
xml_parser_free($parser);
|
|
|
|
$i = 0;
|
|
$tagname = $vals[$i]['tag'];
|
|
|
|
$array[$tagname]['@'] = (isset($vals[$i]['attributes'])) ? $vals[$i]['attributes'] : array();
|
|
$array[$tagname]['#'] = $this->_xml_depth($vals, $i);
|
|
|
|
return $array;
|
|
}
|
|
|
|
/**
|
|
* _xml_depth()
|
|
* @author Hans Anderson
|
|
* @copyright Hans Anderson / http://www.hansanderson.com/php/xml/
|
|
*/
|
|
function _xml_depth($vals, &$i)
|
|
{
|
|
$children = array();
|
|
|
|
if (isset($vals[$i]['value']))
|
|
{
|
|
array_push($children, $vals[$i]['value']);
|
|
}
|
|
|
|
while (++$i < sizeof($vals))
|
|
{
|
|
switch ($vals[$i]['type'])
|
|
{
|
|
case 'open':
|
|
|
|
$tagname = (isset($vals[$i]['tag'])) ? $vals[$i]['tag'] : '';
|
|
$size = (isset($children[$tagname])) ? sizeof($children[$tagname]) : 0;
|
|
|
|
if (isset($vals[$i]['attributes']))
|
|
{
|
|
$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
|
|
}
|
|
|
|
$children[$tagname][$size]['#'] = $this->_xml_depth($vals, $i);
|
|
|
|
break;
|
|
|
|
case 'cdata':
|
|
array_push($children, $vals[$i]['value']);
|
|
break;
|
|
|
|
case 'complete':
|
|
|
|
$tagname = $vals[$i]['tag'];
|
|
$size = (isset($children[$tagname])) ? sizeof($children[$tagname]) : 0;
|
|
$children[$tagname][$size]['#'] = (isset($vals[$i]['value'])) ? $vals[$i]['value'] : array();
|
|
|
|
if (isset($vals[$i]['attributes']))
|
|
{
|
|
$children[$tagname][$size]['@'] = $vals[$i]['attributes'];
|
|
}
|
|
|
|
break;
|
|
|
|
case 'close':
|
|
return $children;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $children;
|
|
}
|
|
|
|
/**
|
|
* TraverseXMLize()
|
|
* @author acebone@f2s.com
|
|
* @copyright acebone@f2s.com, a HUGE help!
|
|
*/
|
|
function traverse_xmlize($array, $arr_name = 'array', $level = 0)
|
|
{
|
|
if ($level == 0)
|
|
{
|
|
echo '<pre>';
|
|
}
|
|
|
|
foreach ($array as $key => $val)
|
|
{
|
|
if (is_array($val))
|
|
{
|
|
$this->traverse_xmlize($val, $arr_name . '[' . $key . ']', $level + 1);
|
|
}
|
|
else
|
|
{
|
|
$GLOBALS['traverse_array'][] = '$' . $arr_name . '[' . $key . '] = "' . $val . "\"\n";
|
|
}
|
|
}
|
|
|
|
if ($level == 0)
|
|
{
|
|
echo '</pre>';
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Jabber Connector
|
|
* @package phpBB3
|
|
*/
|
|
class cjp_standard_connector
|
|
{
|
|
var $active_socket;
|
|
|
|
/**
|
|
* Open socket
|
|
*/
|
|
function open_socket($server, $port)
|
|
{
|
|
if (function_exists('dns_get_record'))
|
|
{
|
|
$record = dns_get_record("_xmpp-client._tcp.$server", DNS_SRV);
|
|
|
|
if (!empty($record))
|
|
{
|
|
$server = $record[0]['target'];
|
|
$port = $record[0]['port'];
|
|
}
|
|
}
|
|
|
|
$errno = 0;
|
|
$errstr = '';
|
|
|
|
if ($this->active_socket = @fsockopen($server, $port, $errno, $errstr, 5))
|
|
{
|
|
@socket_set_blocking($this->active_socket, 0);
|
|
@socket_set_timeout($this->active_socket, 31536000);
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close socket
|
|
*/
|
|
function close_socket()
|
|
{
|
|
return @fclose($this->active_socket);
|
|
}
|
|
|
|
/**
|
|
* Write to socket
|
|
*/
|
|
function write_to_socket($data)
|
|
{
|
|
return @fwrite($this->active_socket, $data);
|
|
}
|
|
|
|
/**
|
|
* Read from socket
|
|
*/
|
|
function read_from_socket($chunksize)
|
|
{
|
|
$buffer = @fread($this->active_socket, $chunksize);
|
|
$buffer = (STRIP) ? stripslashes($buffer) : $buffer;
|
|
|
|
return $buffer;
|
|
}
|
|
}
|
|
|
|
?>
|