Ident.php
10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4 |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2005 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Ondrej Jombik <nepto@platon.sk> |
// | Original author: Gavin Brown <gavin.brown@uk.com> |
// +----------------------------------------------------------------------+
//
// $Id$
//
// Identification Protocol implementation
//
require_once 'PEAR.php';
/**
* Net_Ident default values
* @const NET_IDENT_DEFAULT_TIMEOUT Default ident query network timeout
* @const NET_IDENT_DEFAULT_PORT Default ident protocol port
*/
define('NET_IDENT_DEFAULT_TIMEOUT', 30);
define('NET_IDENT_DEFAULT_PORT', 113);
/**
* Net_Ident object states
* @const NET_IDENT_STATUS_UNDEF Undefined Net_Ident object state
* @const NET_IDENT_STATUS_OK Net_Ident object did successful query
* @const NET_IDENT_STATUS_ERROR Net_Ident object query failed
*/
define('NET_IDENT_STATUS_UNDEF', 0);
define('NET_IDENT_STATUS_OK', 1);
define('NET_IDENT_STATUS_ERROR', 2);
/**
* Net_Ident - Identification Protocol implementation according to RFC 1413
*
* The Identification Protocol (a.k.a., "ident", a.k.a., "the Ident Protocol")
* provides a means to determine the identity of a user of a particular TCP
* connection. Given a TCP port number pair, it returns a character string
* which identifies the owner of that connection on the server's system.
*
* You can find out more about the Ident protocol at
*
* http://www.ietf.org/rfc/rfc1413.txt
*
* Usage:
* <?php
* require_once 'Net/Ident.php';
* $ident = new Net_Ident;
* $user = $ident->getUser();
* $os_type = $ident->getOsType();
* echo "user: $user, operating system: $os_type\n";
* ?>
*
* @author Ondrej Jombik <nepto@platon.sk>
* @package Net_Ident
* @version 1.1.0
* @access public
*/
class Net_Ident
{
/**
* Current object state (undef, ok, error)
*
* @var enum
* @access private
*/
var $_status;
/**
* Error message string;
* if $_status is "error", $_error contains system error message;
* if $_status is "ok", $_error contains ident error message
* or it is empty
*
* @var string
* @access private
*/
var $_error;
/**
* Properties array (contains remote host, remote port, ident port, etc.)
*
* @var array
* @access private
*/
var $_props;
/**
* Data array (contains ident username, ident operating system type, and
* raw line returned from ident server)
*
* @var array
* @access private
*/
var $_data;
/**
* Net_Ident object constructor
*
* Initializes class properties. Use empty string '' for any string
* parameter and value of 0 for any int parameter to set default value.
*
* @param string $remote_addr Remote host address (IP or hostname)
* @param int $remote_port Remote port (default $REMOTE_PORT)
* @param int $local_port Local port (default $SERVER_PORT)
* @param int $ident_port Ident port (default 113)
* @param int $timeout Socket timeout (default 30 seconds)
* @return none
* @access public
*/
function Net_Ident(
$remote_addr = '',
$remote_port = 0,
$local_port = 0,
$ident_port = 0,
$timeout = 0)
{
$this->_status = NET_IDENT_STATUS_UNDEF;
$this->setRemoteAddr($remote_addr);
$this->setRemotePort($remote_port);
$this->setLocalPort($local_port);
$this->setIdentPort($ident_port);
$this->setTimeout($timeout);
}
/**
* Sets remote host address (IP or hostname)
*
* @param string $remote_addr Remote host address (IP or hostname)
* @return none
* @access public
*/
function setRemoteAddr($remote_addr)
{
strlen($remote_addr) <= 0 && $remote_addr = $_SERVER['REMOTE_ADDR'];
$this->_props['remote_addr'] = $remote_addr;
}
/**
* Sets remote port
*
* @param int $remote_port Remote port (default $REMOTE_PORT)
* @return none
* @access public
*/
function setRemotePort($remote_port)
{
$remote_port = intval($remote_port);
$remote_port <= 0 && $remote_port = $_SERVER['REMOTE_PORT'];
$this->_props['remote_port'] = $remote_port;
}
/**
* Sets local port
*
* @param int $local_port Local port (default $SERVER_PORT)
* @return none
* @access public
*/
function setLocalPort($local_port)
{
$local_port = intval($local_port);
$local_port <= 0 && $local_port = $_SERVER['SERVER_PORT'];
$this->_props['local_port'] = $local_port;
}
/**
* Sets ident port
*
* @param int $ident_port Ident port (default 113)
* @return none
* @access public
*/
function setIdentPort($ident_port)
{
$ident_port = intval($ident_port);
$ident_port <= 0 && $ident_port = NET_IDENT_DEFAULT_PORT;
$this->_props['ident_port'] = $ident_port;
}
/**
* Sets socket timeout
*
* @param int $timeout Socket timeout (default 30 seconds)
* @return none
* @access public
*/
function setTimeout($timeout)
{
$timeout = intval($timeout);
$timeout <= 0 && $timeout = NET_IDENT_DEFAULT_TIMEOUT;
$this->_props['timeout'] = $timeout;
}
/**
* Performs network socket ident query
*
* @return mixed PEAR_Error on connection error
* rawdata read from socket on success
* @access public
*/
function query()
{
// query forced, clean current result
if ($this->_status == NET_IDENT_STATUS_OK) {
unset($this->_data['username']);
unset($this->_data['os_type']);
$this->_status = NET_IDENT_STATUS_UNDEF;
}
while (1) {
if ($this->_status == NET_IDENT_STATUS_ERROR) {
return new PEAR_Error($this->_error);
}
if ($socket = @fsockopen(
$this->_props['remote_addr'],
$this->_props['ident_port'],
$errno, $errstr,
$this->_props['timeout'])) {
break;
}
$this->_status = NET_IDENT_STATUS_ERROR;
$this->_error = 'Error connecting to ident server ('
.$this->_props['remote_addr'].':'
.$this->_props['ident_port']."): $errstr ($errno)"; // )
}
$line = $this->_props['remote_port'].','
.$this->_props['local_port']."\r\n";
@fwrite($socket, $line);
$line = @fgets($socket, 1000); // 1000 octets according to RFC 1413
fclose($socket);
$this->_status = NET_IDENT_STATUS_OK;
$this->_data['rawdata'] = $line;
$this->_parseIdentResponse($line);
return $line;
}
/**
* Returns ident username
*
* @return mixed PEAR_Error on connection error
* false boolean on ident protocol error
* username string on success
* @access public
*/
function getUser()
{
$this->_status == NET_IDENT_STATUS_UNDEF && $this->query();
if ($this->_status == NET_IDENT_STATUS_ERROR) {
return new PEAR_Error($this->_error);
}
return $this->_data['username'];
}
/**
* Returns ident operating system type
*
* @return mixed PEAR_Error on connection error
* false boolean on ident protocol error
* operating system type string on success
* @access public
*/
function getOsType()
{
$this->_status == NET_IDENT_STATUS_UNDEF && $this->query();
if ($this->_status == NET_IDENT_STATUS_ERROR) {
return new PEAR_Error($this->_error);
}
return $this->_data['os_type'];
}
/**
* Returns ident protocol error
*
* @return mixed error string if ident protocol error had occured
* false otherwise
* @access public
*/
function identError()
{
if ($this->_status == NET_IDENT_STATUS_OK
&& isset($this->_error)) {
return $this->_error;
}
return false;
}
/**
* Parses response from indent server and sets internal data structures
* with ident username and ident operating system type
*
* @param string $string ident server response
* @return boolean true if no ident protocol error had occured
* false otherwise
* @access private
*/
function _parseIdentResponse($string)
{
$this->_data['username'] = false;
$this->_data['os_type'] = false;
$array = explode(':', $string, 4);
if (count($array) > 1 && ! strcasecmp(trim($array[1]), 'USERID')) {
isset($array[2]) && $this->_data['os_type'] = trim($array[2]);
isset($array[3]) && $this->_data['username'] = trim($array[3]);
return true;
} elseif (count($array) > 1 && ! strcasecmp(trim($array[1]), 'ERROR')) {
isset($array[2]) && $this->_error = trim($array[2]);
} else {
$this->_error = 'Invalid ident server response';
}
return false;
}
}
?>