Skip to content

Commit 61dbe67

Browse files
committed
Merge pull request NARKOZ#44 from dialtoneuk/master
Ported fucking_coffee to PHP. I'm not porting anymore.
2 parents 61f7950 + 4688d52 commit 61dbe67

File tree

2 files changed

+434
-0
lines changed

2 files changed

+434
-0
lines changed

php/Lib/Telnet.php

+264
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
<?php
2+
namespace HackerScripts\Lib;
3+
4+
/**
5+
* Telnet class
6+
*
7+
* Used to execute remote commands via telnet connection
8+
* Usess sockets functions and fgetc() to process result
9+
*
10+
* All methods throw Exceptions on error
11+
*
12+
* Written by Dalibor Andzakovic <[email protected]>
13+
* Based on the code originally written by Marc Ennaji and extended by
14+
* Matthias Blaser <[email protected]>
15+
*
16+
* Extended by Christian Hammers <[email protected]>
17+
* Modified by Frederik Sauer <[email protected]>
18+
*
19+
*/
20+
21+
class Telnet {
22+
23+
private $host;
24+
private $port;
25+
private $timeout;
26+
private $stream_timeout_sec;
27+
private $stream_timeout_usec;
28+
29+
private $socket = NULL;
30+
private $buffer = NULL;
31+
private $prompt;
32+
private $errno;
33+
private $errstr;
34+
private $strip_prompt = TRUE;
35+
36+
private $NULL;
37+
private $DC1;
38+
private $WILL;
39+
private $WONT;
40+
private $DO;
41+
private $DONT;
42+
private $IAC;
43+
44+
private $global_buffer = '';
45+
46+
const TELNET_ERROR = FALSE;
47+
const TELNET_OK = TRUE;
48+
49+
public function __construct($host = '127.0.0.1', $port = '23', $timeout = 10, $prompt = '$', $stream_timeout = 1) {
50+
$this->host = $host;
51+
$this->port = $port;
52+
$this->timeout = $timeout;
53+
$this->setPrompt($prompt);
54+
$this->setStreamTimeout($stream_timeout);
55+
56+
// set some telnet special characters
57+
$this->NULL = chr(0);
58+
$this->DC1 = chr(17);
59+
$this->WILL = chr(251);
60+
$this->WONT = chr(252);
61+
$this->DO = chr(253);
62+
$this->DONT = chr(254);
63+
$this->IAC = chr(255);
64+
65+
$this->connect();
66+
}
67+
68+
public function __destruct() {
69+
// clean up resources
70+
$this->disconnect();
71+
$this->buffer = NULL;
72+
$this->global_buffer = NULL;
73+
}
74+
75+
public function connect() {
76+
// check if we need to convert host to IP
77+
if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host)) {
78+
$ip = gethostbyname($this->host);
79+
80+
if ($this->host == $ip) {
81+
throw new Exception("Cannot resolve $this->host");
82+
} else {
83+
$this->host = $ip;
84+
}
85+
}
86+
87+
// attempt connection - suppress warnings
88+
$this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
89+
90+
if (!$this->socket) {
91+
throw new Exception("Cannot connect to $this->host on port $this->port");
92+
}
93+
94+
if (!empty($this->prompt)) {
95+
$this->waitPrompt();
96+
}
97+
98+
return self::TELNET_OK;
99+
}
100+
101+
public function disconnect() {
102+
if ($this->socket) {
103+
if (! fclose($this->socket)) {
104+
throw new Exception("Error while closing telnet socket");
105+
}
106+
$this->socket = NULL;
107+
}
108+
return self::TELNET_OK;
109+
}
110+
111+
public function exec($command, $add_newline = TRUE) {
112+
$this->write($command, $add_newline);
113+
$this->waitPrompt();
114+
return $this->getBuffer();
115+
}
116+
117+
public function login($username, $password) {
118+
try {
119+
$this->setPrompt('login:');
120+
$this->waitPrompt();
121+
$this->write($username);
122+
$this->setPrompt('Password:');
123+
$this->waitPrompt();
124+
$this->write($password);
125+
$this->setPrompt();
126+
$this->waitPrompt();
127+
} catch (Exception $e) {
128+
throw new Exception("Login failed.");
129+
}
130+
131+
return self::TELNET_OK;
132+
}
133+
134+
public function setPrompt($str = '$') {
135+
return $this->setRegexPrompt(preg_quote($str, '/'));
136+
}
137+
138+
public function setRegexPrompt($str = '\$') {
139+
$this->prompt = $str;
140+
return self::TELNET_OK;
141+
}
142+
143+
public function setStreamTimeout($timeout) {
144+
$this->stream_timeout_usec = (int)(fmod($timeout, 1) * 1000000);
145+
$this->stream_timeout_sec = (int)$timeout;
146+
}
147+
148+
public function stripPromptFromBuffer($strip) {
149+
$this->strip_prompt = $strip;
150+
} // function stripPromptFromBuffer
151+
152+
protected function getc() {
153+
stream_set_timeout($this->socket, $this->stream_timeout_sec, $this->stream_timeout_usec);
154+
$c = fgetc($this->socket);
155+
$this->global_buffer .= $c;
156+
return $c;
157+
}
158+
159+
public function clearBuffer() {
160+
$this->buffer = '';
161+
}
162+
163+
public function readTo($prompt) {
164+
if (!$this->socket) {
165+
throw new Exception("Telnet connection closed");
166+
}
167+
168+
// clear the buffer
169+
$this->clearBuffer();
170+
171+
$until_t = time() + $this->timeout;
172+
do {
173+
// time's up (loop can be exited at end or through continue!)
174+
if (time() > $until_t) {
175+
throw new Exception("Couldn't find the requested : '$prompt' within {$this->timeout} seconds");
176+
}
177+
178+
$c = $this->getc();
179+
180+
if ($c === FALSE) {
181+
if (empty($prompt)) {
182+
return self::TELNET_OK;
183+
}
184+
throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server: " . $this->buffer);
185+
}
186+
187+
// Interpreted As Command
188+
if ($c == $this->IAC) {
189+
if ($this->negotiateTelnetOptions()) {
190+
continue;
191+
}
192+
}
193+
194+
// append current char to global buffer
195+
$this->buffer .= $c;
196+
197+
// we've encountered the prompt. Break out of the loop
198+
if (!empty($prompt) && preg_match("/{$prompt}$/", $this->buffer)) {
199+
return self::TELNET_OK;
200+
}
201+
202+
} while ($c != $this->NULL || $c != $this->DC1);
203+
}
204+
205+
public function write($buffer, $add_newline = TRUE) {
206+
if (!$this->socket) {
207+
throw new Exception("Telnet connection closed");
208+
}
209+
210+
// clear buffer from last command
211+
$this->clearBuffer();
212+
213+
if ($add_newline == TRUE) {
214+
$buffer .= "\n";
215+
}
216+
217+
$this->global_buffer .= $buffer;
218+
if (!fwrite($this->socket, $buffer) < 0) {
219+
throw new Exception("Error writing to socket");
220+
}
221+
222+
return self::TELNET_OK;
223+
}
224+
225+
protected function getBuffer() {
226+
// Remove all carriage returns from line breaks
227+
$buf = preg_replace('/\r\n|\r/', "\n", $this->buffer);
228+
// Cut last line from buffer (almost always prompt)
229+
if ($this->strip_prompt) {
230+
$buf = explode("\n", $buf);
231+
unset($buf[count($buf) - 1]);
232+
$buf = implode("\n", $buf);
233+
}
234+
return trim($buf);
235+
}
236+
237+
public function getGlobalBuffer() {
238+
return $this->global_buffer;
239+
}
240+
241+
protected function negotiateTelnetOptions() {
242+
$c = $this->getc();
243+
244+
if ($c != $this->IAC) {
245+
if (($c == $this->DO) || ($c == $this->DONT)) {
246+
$opt = $this->getc();
247+
fwrite($this->socket, $this->IAC . $this->WONT . $opt);
248+
} else if (($c == $this->WILL) || ($c == $this->WONT)) {
249+
$opt = $this->getc();
250+
fwrite($this->socket, $this->IAC . $this->DONT . $opt);
251+
} else {
252+
throw new Exception('Error: unknown control character ' . ord($c));
253+
}
254+
} else {
255+
throw new Exception('Error: Something Wicked Happened');
256+
}
257+
258+
return self::TELNET_OK;
259+
}
260+
261+
protected function waitPrompt() {
262+
return $this->readTo($this->prompt);
263+
}
264+
}

0 commit comments

Comments
 (0)