summaryrefslogtreecommitdiff
path: root/src/protocoltelnet.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2006-05-01 17:11:04 +0000
committerMike Buland <eichlan@xagasoft.com>2006-05-01 17:11:04 +0000
commitf7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54 (patch)
tree53cec4864776e07950e3c72f2a990a1017d08045 /src/protocoltelnet.cpp
downloadlibbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.gz
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.bz2
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.tar.xz
libbu++-f7a9549bd6ad83f2e0bceec9cddacfa5e3f84a54.zip
libbu++ is finally laid out the way it should be, trunk, branches, and tags.
Diffstat (limited to 'src/protocoltelnet.cpp')
-rw-r--r--src/protocoltelnet.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/src/protocoltelnet.cpp b/src/protocoltelnet.cpp
new file mode 100644
index 0000000..7beea5b
--- /dev/null
+++ b/src/protocoltelnet.cpp
@@ -0,0 +1,315 @@
1#include "protocoltelnet.h"
2#include <string.h>
3
4ProtocolTelnet::ProtocolTelnet()
5{
6 nTermType = termUnInited;
7 bEchoOn = true;
8}
9
10ProtocolTelnet::~ProtocolTelnet()
11{
12}
13
14bool ProtocolTelnet::onNewConnection()
15{
16 Connection *pCon = getConnection();
17
18 pCon->appendOutput( (char)IAC );
19 pCon->appendOutput( (char)WILL );
20 pCon->appendOutput( (char)SUPPRESSGA );
21
22 pCon->appendOutput( (char)IAC );
23 pCon->appendOutput( (char)DO );
24 pCon->appendOutput( (char)SUPPRESSGA );
25
26 pCon->appendOutput( (char)IAC );
27 pCon->appendOutput( (char)DONT );
28 pCon->appendOutput( (char)TERMTYPE );
29
30// pCon->appendOutput( IAC );
31// pCon->appendOutput( SB );
32// pCon->appendOutput( TERMTYPE );
33// pCon->appendOutput( 1 );
34// pCon->appendOutput( IAC );
35// pCon->appendOutput( SE );
36
37 pCon->appendOutput( (char)IAC );
38 pCon->appendOutput( (char)DONT );
39 pCon->appendOutput( (char)ECHO );
40
41 pCon->appendOutput( (char)IAC );
42 pCon->appendOutput( (char)WILL );
43 pCon->appendOutput( (char)ECHO );
44
45// 255(IAC),251(WILL),3
46}
47
48bool ProtocolTelnet::onNewData()
49{
50 Connection *pCon = getConnection();
51 if( !pCon->hasInput() )
52 {
53 return true;
54 }
55
56 int nInSize = pCon->getInputAmnt();
57 char *lpInStr = (char *)pCon->getInput();
58
59 // Here we interpret the basic commands and un-encapsulate them, so to
60 // speak. We'll allow this, even if the terminal is in raw mode, we
61 // just won't send anything in response...
62 for( int j = 0; j < nInSize; j++ )
63 {
64 switch( (unsigned char)lpInStr[j] )
65 {
66 case '\r':
67 fbEdited.appendData('\n');
68 if( bEchoOn ) pCon->appendOutput("\n\r");
69 break;
70
71 case '\n':
72 break;
73
74 case '\177': // backspace
75 if( fbEdited.getLength() > 0 )
76 {
77 fbEdited.usedData( -1 ); // Delete one char from the end
78 if( bEchoOn ) pCon->appendOutput(ESC "[D"); // Move the cursor back one
79 if( bEchoOn ) pCon->appendOutput(ESC "[P"); // Delete one character
80 }
81 break;
82
83 case '\x1B': // escape sequence
84 if( (unsigned char)lpInStr[j+1] == '[' )
85 {
86 switch( (unsigned char)lpInStr[j+2] )
87 {
88 case 'A': // Up
89 break;
90
91 case 'B': // Down
92 break;
93
94 case 'C': // Right
95 break;
96
97 case 'D': // Left
98 break;
99 }
100 j+=2;
101 }
102 break;
103
104 case 0: // NOP: No operation
105 break;
106
107 case IAC: // IAC: Interpret as command
108 switch( lpInStr[j+1] )
109 {
110 case SE: // SE: End of subnegotiation parameters.
111 break;
112
113 case NOP: // NOP: No operation
114 break;
115
116 case DM: // DM: Data mark. Indicates the position of a Synch event within the data stream. This should always be accompanied by a TCP urgent notification.
117 break;
118
119 case BRK: // BRK: Break. Indicates that the "break" or "attention" key was hit.
120 break;
121
122 case IP: // IP: Suspend, interrupt or abort the process to which the NVT is connected.
123 break;
124
125 case AO: // AO: Abort output. Allows the current process to run to completion but do not send its output to the user.
126 break;
127
128 case AYT: // AYT: Are you there. Send back to the NVT some visible evidence that the AYT was received.
129 break;
130
131 case EC: // EC: Erase character. The receiver should delete the last preceding undeleted character from the data stream.
132 break;
133
134 case EL: // EL: Erase line. Delete characters from the data stream back to but not including the previous CRLF.
135 break;
136
137 case GA: // GA: Go ahead. Used, under certain circumstances, to tell the other end that it can transmit.
138 break;
139
140 case SB: // SB: Subnegotiation of the indicated option follows.
141 switch( lpInStr[j+2] )
142 {
143 case TERMTYPE:
144 if( lpInStr[j+3] == 0 )
145 {
146 for( int k = 0; j+4+k < nInSize; k++ )
147 {
148 if( (unsigned char)lpInStr[j+4+k] == IAC &&
149 (unsigned char)lpInStr[j+5+k] == SE )
150 {
151 lpInStr[j+4+k] = 0;
152 //@TODO: Do something with the term type...
153 printf("Term type: %s\n", &lpInStr[j+4] );
154 j += 5+k;
155 }
156 }
157 }
158 else
159 {
160 }
161 break;
162
163 default:
164 //printf("unknown subnegotiation parameters! (%d)\n", lpInStr[j+2] );
165 break;
166 }
167 break;
168
169 case WILL: // WILL: Indicates the desire to begin performing
170 switch( lpInStr[j+2] )
171 {
172 case SUPPRESSGA:
173 j += 2;
174// pCon->usedInput( 3 );
175 break;
176
177 case TERMTYPE:
178 j += 2;
179// pCon->usedInput( 3 );
180 break;
181
182 case ECHO:
183 j += 2;
184// pCon->usedInput( 3 );
185 break;
186
187 case NAWS:
188 default:
189 pCon->appendOutput( (char)ESC[0] );
190 pCon->appendOutput( (char)DONT );
191 pCon->appendOutput( lpInStr[j+2] );
192 //printf("unknown will command used! (%d)\n", lpInStr[j+2] );
193 j += 2;
194 break;
195 }
196 break;
197
198 case WONT: // WONT: Indicates the refusal to perform
199 switch( lpInStr[j+2] )
200 {
201 case ECHO:
202 j += 2;
203// pCon->usedInput( 3 );
204 break;
205
206 default:
207 //printf("unknown wont command used! (%d)\n", lpInStr[j+2] );
208 j += 2;
209 break;
210 }
211 break;
212
213 case DO: // DO: Indicates the request that the other party perform
214 switch( lpInStr[j+2] )
215 {
216 case ECHO:
217 j += 2;
218 break;
219
220 case SUPPRESSGA:
221 j += 2;
222 break;
223
224 default:
225 pCon->appendOutput( (char)ESC[0] );
226 pCon->appendOutput( (char)DONT );
227 pCon->appendOutput( lpInStr[j+2] );
228 //printf("unknown do command used! (%d)\n", lpInStr[j+2] );
229 j += 2;
230 break;
231 }
232// pCon->usedInput( 3 );
233 break;
234
235 case DONT: // DONT: Indicates the demand that the other party stop performing
236 switch( lpInStr[j+2] )
237 {
238 case ECHO:
239 j += 2;
240// pCon->usedInput( 3 );
241 break;
242
243 default:
244 printf("unknown dont command used! (%d)\n", lpInStr[j+2] );
245 j += 2;
246 break;
247 }
248 break;
249 }
250 break;
251
252 default:
253 fbEdited.appendData( lpInStr[j] );
254 if( bEchoOn ) pCon->appendOutput( lpInStr[j] );
255 break;
256 }
257 }
258
259 pCon->usedInput( pCon->getInputAmnt() );
260
261 return true;
262}
263
264char *ProtocolTelnet::getLine( bool bFullOnly )
265{
266 int i = fbEdited.findChar('\n');
267
268 if( i < 0 )
269 {
270 if( bFullOnly == false )
271 {
272 i = fbEdited.getLength();
273 }
274 else
275 {
276 return NULL;
277 }
278 }
279
280 char *lpStr = new char[i+1];
281 strncpy( lpStr, fbEdited.getData(), i );
282 lpStr[i] = '\0';
283
284 fbEdited.usedData( i+1 );
285
286 return lpStr;
287}
288
289char *ProtocolTelnet::peekLine( bool bFullOnly )
290{
291 int i = fbEdited.findChar('\n');
292
293 if( i < 0 )
294 {
295 if( bFullOnly == false )
296 {
297 i = fbEdited.getLength();
298 }
299 else
300 {
301 return NULL;
302 }
303 }
304
305 char *lpStr = new char[i+1];
306 strncpy( lpStr, fbEdited.getData(), i );
307 lpStr[i] = '\0';
308
309 return lpStr;
310}
311
312void ProtocolTelnet::setEcho( bool bEchoOn )
313{
314 this->bEchoOn = bEchoOn;
315}