This source file includes following definitions.
- _send
- _check_telopt
- _get_rfc1143
- _set_rfc1143
- _send_negotiate
- _negotiate
- _environ_telnet
- _ttype_telnet
- _subnegotiate
- telnet_init
- telnet_free
- _buffer_byte
- _process
- telnet_recv
- telnet_iac
- telnet_negotiate
- telnet_send
- telnet_send_text
- telnet_begin_sb
- telnet_vprintf
- telnet_printf
- telnet_raw_vprintf
- telnet_raw_printf
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 #include <stdlib.h>
56 #include <string.h>
57 #include <stdio.h>
58 #include <errno.h>
59 #include <string.h>
60 #include <stdarg.h>
61
62
63 #if defined(_WIN32)
64 # define __func__ __FUNCTION__
65 # if defined(_MSC_VER)
66 # if _MSC_VER <= 1700
67 # define va_copy(dest, src) (dest = src)
68 # endif
69 # endif
70 #endif
71
72 #include "libtelnet.h"
73
74 #if defined(FREE)
75 # undef FREE
76 #endif
77 #define FREE(p) do \
78 { \
79 free((p)); \
80 (p) = NULL; \
81 } while(0)
82
83
84 #define Q_US(q) ((q).state & 0x0F)
85 #define Q_HIM(q) (((q).state & 0xF0) >> 4)
86 #define Q_MAKE(us,him) ((us) | ((him) << 4))
87
88
89 #define NEGOTIATE_EVENT(telnet,cmd,opt) \
90 ev.type = (cmd); \
91 ev.neg.telopt = (opt); \
92 (telnet)->eh((telnet), &ev, (telnet)->ud);
93
94
95 enum telnet_state_t {
96 TELNET_STATE_DATA = 0,
97 TELNET_STATE_EOL,
98 TELNET_STATE_IAC,
99 TELNET_STATE_WILL,
100 TELNET_STATE_WONT,
101 TELNET_STATE_DO,
102 TELNET_STATE_DONT,
103 TELNET_STATE_SB,
104 TELNET_STATE_SB_DATA,
105 TELNET_STATE_SB_DATA_IAC
106 };
107 typedef enum telnet_state_t telnet_state_t;
108
109
110 struct telnet_t {
111
112 void *ud;
113
114 const telnet_telopt_t *telopts;
115
116 telnet_event_handler_t eh;
117
118 struct telnet_rfc1143_t *q;
119
120 char *buffer;
121
122 size_t buffer_size;
123
124 size_t buffer_pos;
125
126 enum telnet_state_t state;
127
128 unsigned char flags;
129
130 unsigned char sb_telopt;
131
132 unsigned int q_size;
133
134 unsigned int q_cnt;
135 };
136
137
138 typedef struct telnet_rfc1143_t {
139 unsigned char telopt;
140 unsigned char state;
141 } telnet_rfc1143_t;
142
143
144 #define Q_NO 0
145 #define Q_YES 1
146 #define Q_WANTNO 2
147 #define Q_WANTYES 3
148 #define Q_WANTNO_OP 4
149 #define Q_WANTYES_OP 5
150
151
152 static const char CRLF[] = { '\r', '\n' };
153 static const char CRNUL[] = { '\r', '\0' };
154
155
156 static const size_t _buffer_sizes[] = { 0, 512, 2048, 8192, 16384, };
157 static const size_t _buffer_sizes_count = sizeof(_buffer_sizes) /
158 sizeof(_buffer_sizes[0]);
159
160
161 static telnet_error_t _error(telnet_t *telnet, unsigned line,
162 const char* func, telnet_error_t err,
163 int fatal, const char *fmt, ...) {
164 telnet_event_t ev;
165 char buffer[512];
166 va_list va;
167
168
169 va_start(va, fmt);
170 (void)vsnprintf(buffer, sizeof(buffer), fmt, va);
171 va_end(va);
172
173
174 ev.type = fatal ? TELNET_EV_ERROR : TELNET_EV_WARNING;
175 ev.error.file = __FILE__;
176 ev.error.func = func;
177 ev.error.line = (int) line;
178 ev.error.msg = buffer;
179 telnet->eh(telnet, &ev, telnet->ud);
180
181 return err;
182 }
183
184
185 static void _send(telnet_t *telnet, const char *buffer,
186 size_t size) {
187 telnet_event_t ev;
188
189 ev.type = TELNET_EV_SEND;
190 ev.data.buffer = buffer;
191 ev.data.size = size;
192 telnet->eh(telnet, &ev, telnet->ud);
193 }
194
195
196 #define _sendu(t, d, s) _send((t), (const char*)(d), (s))
197
198
199
200
201
202
203
204 static __inline__ int _check_telopt(telnet_t *telnet, unsigned char telopt,
205 int us) {
206 int i;
207
208
209 if (telnet->telopts == 0)
210 return 0;
211
212
213 for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
214 if (telnet->telopts[i].telopt == telopt) {
215 if (us && telnet->telopts[i].us == TELNET_WILL)
216 return 1;
217 else if (!us && telnet->telopts[i].him == TELNET_DO)
218 return 1;
219 else
220 return 0;
221 }
222 }
223
224
225 return 0;
226 }
227
228
229 static __inline__ telnet_rfc1143_t _get_rfc1143(telnet_t *telnet,
230 unsigned char telopt) {
231 telnet_rfc1143_t empty;
232 unsigned int i;
233
234
235 for (i = 0; i != telnet->q_cnt; ++i) {
236 if (telnet->q[i].telopt == telopt) {
237 return telnet->q[i];
238 }
239 }
240
241
242 empty.telopt = telopt;
243 empty.state = 0;
244 return empty;
245 }
246
247
248 static __inline__ void _set_rfc1143(telnet_t *telnet, unsigned char telopt,
249 unsigned char us, unsigned char him) {
250 telnet_rfc1143_t *qtmp;
251 unsigned int i;
252
253
254 for (i = 0; i != telnet->q_cnt; ++i) {
255 if (telnet->q[i].telopt == telopt) {
256 telnet->q[i].state = (unsigned char) Q_MAKE(us,him);
257 if (telopt != TELNET_TELOPT_BINARY)
258 return;
259 telnet->flags &=
260 (unsigned char)~(TELNET_FLAG_TRANSMIT_BINARY |
261 TELNET_FLAG_RECEIVE_BINARY);
262 if (us == Q_YES)
263 telnet->flags |= TELNET_FLAG_TRANSMIT_BINARY;
264 if (him == Q_YES)
265 telnet->flags |= TELNET_FLAG_RECEIVE_BINARY;
266 return;
267 }
268 }
269
270
271
272
273
274
275
276
277
278 #define QUANTUM 4
279
280 if (i >= telnet->q_size) {
281
282 if ((qtmp = (telnet_rfc1143_t *)realloc(telnet->q,
283 sizeof(telnet_rfc1143_t) * (telnet->q_size + QUANTUM))) == 0) {
284 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
285 "realloc() failed: %s", xstrerror_l(errno));
286 return;
287 }
288 (void)memset(&qtmp[telnet->q_size], 0, sizeof(telnet_rfc1143_t) * QUANTUM);
289 telnet->q = qtmp;
290 telnet->q_size += QUANTUM;
291 }
292
293 telnet->q[telnet->q_cnt].telopt = telopt;
294 telnet->q[telnet->q_cnt].state = (unsigned char) Q_MAKE(us, him);
295 telnet->q_cnt ++;
296 }
297
298
299 static __inline__ void _send_negotiate(telnet_t *telnet, unsigned char cmd,
300 unsigned char telopt) {
301 unsigned char bytes[3];
302 bytes[0] = TELNET_IAC;
303 bytes[1] = cmd;
304 bytes[2] = telopt;
305 _sendu(telnet, bytes, 3);
306 }
307
308
309 static void _negotiate(telnet_t *telnet, unsigned char telopt) {
310 telnet_event_t ev;
311 telnet_rfc1143_t q;
312
313
314 if (telnet->flags & TELNET_FLAG_PROXY) {
315 switch ((int)telnet->state) {
316 case TELNET_STATE_WILL:
317 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
318 break;
319 case TELNET_STATE_WONT:
320 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
321 break;
322 case TELNET_STATE_DO:
323 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
324 break;
325 case TELNET_STATE_DONT:
326 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
327 break;
328 }
329 return;
330 }
331
332
333 q = _get_rfc1143(telnet, telopt);
334
335
336 switch ((int)telnet->state) {
337
338 case TELNET_STATE_WILL:
339 switch (Q_HIM(q)) {
340 case Q_NO:
341 if (_check_telopt(telnet, telopt, 0)) {
342 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
343 _send_negotiate(telnet, TELNET_DO, telopt);
344 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
345 } else
346 _send_negotiate(telnet, TELNET_DONT, telopt);
347 break;
348 case Q_WANTNO:
349 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
350 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
351 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
352 "DONT answered by WILL");
353 break;
354 case Q_WANTNO_OP:
355 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
356 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
357 "DONT answered by WILL");
358 break;
359 case Q_WANTYES:
360 _set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
361 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
362 break;
363 case Q_WANTYES_OP:
364 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
365 _send_negotiate(telnet, TELNET_DONT, telopt);
366 NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
367 break;
368 }
369 break;
370
371
372 case TELNET_STATE_WONT:
373 switch (Q_HIM(q)) {
374 case Q_YES:
375 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
376 _send_negotiate(telnet, TELNET_DONT, telopt);
377 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
378 break;
379 case Q_WANTNO:
380 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
381 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
382 break;
383 case Q_WANTNO_OP:
384 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
385 _send_negotiate(telnet, TELNET_DO, telopt);
386 NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
387 break;
388 case Q_WANTYES:
389 case Q_WANTYES_OP:
390 _set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
391 break;
392 }
393 break;
394
395
396 case TELNET_STATE_DO:
397 switch (Q_US(q)) {
398 case Q_NO:
399 if (_check_telopt(telnet, telopt, 1)) {
400 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
401 _send_negotiate(telnet, TELNET_WILL, telopt);
402 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
403 } else
404 _send_negotiate(telnet, TELNET_WONT, telopt);
405 break;
406 case Q_WANTNO:
407 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
408 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
409 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
410 "WONT answered by DO");
411 break;
412 case Q_WANTNO_OP:
413 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
414 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
415 "WONT answered by DO");
416 break;
417 case Q_WANTYES:
418 _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
419 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
420 break;
421 case Q_WANTYES_OP:
422 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
423 _send_negotiate(telnet, TELNET_WONT, telopt);
424 NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
425 break;
426 }
427 break;
428
429
430 case TELNET_STATE_DONT:
431 switch (Q_US(q)) {
432 case Q_YES:
433 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
434 _send_negotiate(telnet, TELNET_WONT, telopt);
435 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
436 break;
437 case Q_WANTNO:
438 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
439 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
440 break;
441 case Q_WANTNO_OP:
442 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
443 _send_negotiate(telnet, TELNET_WILL, telopt);
444 NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
445 break;
446 case Q_WANTYES:
447 case Q_WANTYES_OP:
448 _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
449 break;
450 }
451 break;
452 }
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469 static int _environ_telnet(telnet_t *telnet, unsigned char type,
470 char* buffer, size_t size) {
471 telnet_event_t ev;
472 struct telnet_environ_t *values = 0;
473 char *c, *last, *out;
474 size_t eindex, count;
475
476
477 if (size == 0) {
478 return 0;
479 }
480
481
482 if ((unsigned)buffer[0] != TELNET_ENVIRON_SEND &&
483 (unsigned)buffer[0] != TELNET_ENVIRON_IS &&
484 (unsigned)buffer[0] != TELNET_ENVIRON_INFO) {
485 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
486 "telopt %ld subneg has invalid command", (long) type);
487 return 0;
488 }
489
490
491 ev.environ.cmd = (unsigned char) buffer[0];
492
493
494 if (size == 1) {
495
496 ev.environ.values = 0;
497 ev.environ.size = 0;
498
499
500 ev.type = TELNET_EV_ENVIRON;
501 telnet->eh(telnet, &ev, telnet->ud);
502
503 return 0;
504 }
505
506
507 if ((unsigned)buffer[1] != TELNET_ENVIRON_VAR &&
508 (unsigned)buffer[1] != TELNET_ENVIRON_USERVAR) {
509 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
510 "telopt %d subneg missing variable type", type);
511 return 0;
512 }
513
514
515 if ((unsigned)buffer[size - 1] == TELNET_ENVIRON_ESC) {
516 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
517 "telopt %d subneg ends with ESC", type);
518 return 0;
519 }
520
521
522 count = 0;
523 for (c = buffer + 1; c < buffer + size; ++c) {
524 if (*c == TELNET_ENVIRON_VAR || *c == TELNET_ENVIRON_USERVAR) {
525 ++count;
526 } else if (*c == TELNET_ENVIRON_ESC) {
527
528 ++c;
529 }
530 }
531
532
533 if ((values = (struct telnet_environ_t *)calloc(count,
534 sizeof(struct telnet_environ_t))) == 0) {
535 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
536 "calloc() failed: %s", xstrerror_l(errno));
537 return 0;
538 }
539
540
541 out = buffer;
542 c = buffer + 1;
543 for (eindex = 0; eindex != count; ++eindex) {
544
545 values[eindex].type = (unsigned char) (*c++);
546
547
548
549 last = out;
550 while (c < buffer + size) {
551
552 if ((unsigned)*c == TELNET_ENVIRON_VAR ||
553 (unsigned)*c == TELNET_ENVIRON_VALUE ||
554 (unsigned)*c == TELNET_ENVIRON_USERVAR) {
555 break;
556 }
557
558
559 if (*c == TELNET_ENVIRON_ESC) {
560 ++c;
561 }
562
563 *out++ = *c++;
564 }
565 *out++ = '\0';
566
567
568 values[eindex].var = last;
569 values[eindex].value = "";
570
571
572
573 if (c < buffer + size && *c == TELNET_ENVIRON_VALUE) {
574 ++c;
575 last = out;
576 while (c < buffer + size) {
577
578 if ((unsigned)*c == TELNET_ENVIRON_VAR ||
579 (unsigned)*c == TELNET_ENVIRON_USERVAR) {
580 break;
581 }
582
583
584 if (*c == TELNET_ENVIRON_ESC) {
585 ++c;
586 }
587
588 *out++ = *c++;
589 }
590 *out++ = '\0';
591
592
593 values[eindex].value = last;
594 }
595 }
596
597
598 ev.environ.values = values;
599 ev.environ.size = count;
600
601
602 ev.type = TELNET_EV_ENVIRON;
603 telnet->eh(telnet, &ev, telnet->ud);
604
605
606 FREE(values);
607 return 0;
608 }
609
610
611 static int _ttype_telnet(telnet_t *telnet, const char* buffer, size_t size) {
612 telnet_event_t ev;
613
614
615 if (size == 0) {
616 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
617 "incomplete TERMINAL-TYPE request");
618 return 0;
619 }
620
621
622 if (buffer[0] != TELNET_TTYPE_IS &&
623 buffer[0] != TELNET_TTYPE_SEND) {
624 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
625 "TERMINAL-TYPE request has invalid type");
626 return 0;
627 }
628
629
630 if (buffer[0] == TELNET_TTYPE_IS) {
631 char *name;
632
633
634 if ((name = (char *)malloc(size)) == 0) {
635 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
636 "malloc() failed: %s", xstrerror_l(errno));
637 return 0;
638 }
639 memcpy(name, buffer + 1, size - 1);
640 name[size - 1] = '\0';
641
642 ev.type = TELNET_EV_TTYPE;
643 ev.ttype.cmd = TELNET_TTYPE_IS;
644 ev.ttype.name = name;
645 telnet->eh(telnet, &ev, telnet->ud);
646
647
648 FREE(name);
649 } else {
650 ev.type = TELNET_EV_TTYPE;
651 ev.ttype.cmd = TELNET_TTYPE_SEND;
652 ev.ttype.name = 0;
653 telnet->eh(telnet, &ev, telnet->ud);
654 }
655
656 return 0;
657 }
658
659
660
661
662
663
664 static int _subnegotiate(telnet_t *telnet) {
665 telnet_event_t ev;
666
667
668 ev.type = TELNET_EV_SUBNEGOTIATION;
669 ev.sub.telopt = telnet->sb_telopt;
670 ev.sub.buffer = telnet->buffer;
671 ev.sub.size = telnet->buffer_pos;
672 telnet->eh(telnet, &ev, telnet->ud);
673
674 switch (telnet->sb_telopt) {
675
676 case TELNET_TELOPT_TTYPE:
677 return _ttype_telnet(telnet, telnet->buffer, telnet->buffer_pos);
678 case TELNET_TELOPT_ENVIRON:
679 case TELNET_TELOPT_NEW_ENVIRON:
680 return _environ_telnet(telnet, telnet->sb_telopt, telnet->buffer,
681 telnet->buffer_pos);
682 default:
683 return 0;
684 }
685 }
686
687
688 telnet_t *telnet_init(const telnet_telopt_t *telopts,
689 telnet_event_handler_t eh, unsigned char flags, void *user_data) {
690
691 struct telnet_t *telnet = (telnet_t*)calloc(1, sizeof(telnet_t));
692 if (telnet == 0)
693 return 0;
694
695
696 telnet->ud = user_data;
697 telnet->telopts = telopts;
698 telnet->eh = eh;
699 telnet->flags = flags;
700
701 return telnet;
702 }
703
704
705 void telnet_free(telnet_t *telnet) {
706
707 if (telnet->buffer != 0) {
708 FREE(telnet->buffer);
709 telnet->buffer = 0;
710 telnet->buffer_size = 0;
711 telnet->buffer_pos = 0;
712 }
713
714
715 if (telnet->q) {
716 FREE(telnet->q);
717 telnet->q = NULL;
718 telnet->q_size = 0;
719 telnet->q_cnt = 0;
720 }
721
722
723 free(telnet);
724 }
725
726
727 static telnet_error_t _buffer_byte(telnet_t *telnet,
728 unsigned char byte) {
729 char *new_buffer;
730
731
732 if (telnet->buffer_pos == telnet->buffer_size) {
733 size_t i;
734
735 for (i = 0; i != _buffer_sizes_count; ++i) {
736 if (_buffer_sizes[i] == telnet->buffer_size) {
737 break;
738 }
739 }
740
741
742 if (i >= _buffer_sizes_count - 1) {
743 _error(telnet, __LINE__, __func__, TELNET_EOVERFLOW, 0,
744 "subnegotiation buffer size limit reached");
745 return TELNET_EOVERFLOW;
746 }
747
748
749 new_buffer = (char *)realloc(telnet->buffer, _buffer_sizes[i + 1]);
750 if (new_buffer == 0) {
751 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
752 "realloc() failed");
753 return TELNET_ENOMEM;
754 }
755
756 telnet->buffer = new_buffer;
757 telnet->buffer_size = _buffer_sizes[i + 1];
758 }
759
760
761 telnet->buffer[telnet->buffer_pos++] = (char) byte;
762 return TELNET_EOK;
763 }
764
765 static void _process(telnet_t *telnet, const char *buffer, size_t size) {
766 telnet_event_t ev;
767 unsigned char byte;
768 size_t i, start;
769 for (i = start = 0; i != size; ++i) {
770 byte = (unsigned char) buffer[i];
771 switch (telnet->state) {
772
773 case TELNET_STATE_DATA:
774
775
776 if (byte == TELNET_IAC) {
777 if (i != start) {
778 ev.type = TELNET_EV_DATA;
779 ev.data.buffer = buffer + start;
780 ev.data.size = i - start;
781 telnet->eh(telnet, &ev, telnet->ud);
782 }
783 telnet->state = TELNET_STATE_IAC;
784 } else if (byte == '\r' &&
785 (telnet->flags & TELNET_FLAG_NVT_EOL) &&
786 !(telnet->flags & TELNET_FLAG_RECEIVE_BINARY)) {
787 if (i != start) {
788 ev.type = TELNET_EV_DATA;
789 ev.data.buffer = buffer + start;
790 ev.data.size = i - start;
791 telnet->eh(telnet, &ev, telnet->ud);
792 }
793 telnet->state = TELNET_STATE_EOL;
794 }
795 break;
796
797
798 case TELNET_STATE_EOL:
799 if (byte != '\n') {
800 byte = '\r';
801 ev.type = TELNET_EV_DATA;
802 ev.data.buffer = (char*)&byte;
803 ev.data.size = 1;
804 telnet->eh(telnet, &ev, telnet->ud);
805 byte = (unsigned char) buffer[i];
806 }
807
808
809 start = i;
810 if (byte == '\0')
811 ++start;
812
813 telnet->state = TELNET_STATE_DATA;
814 break;
815
816
817 case TELNET_STATE_IAC:
818 switch (byte) {
819
820 case TELNET_SB:
821 telnet->state = TELNET_STATE_SB;
822 break;
823
824 case TELNET_WILL:
825 telnet->state = TELNET_STATE_WILL;
826 break;
827 case TELNET_WONT:
828 telnet->state = TELNET_STATE_WONT;
829 break;
830 case TELNET_DO:
831 telnet->state = TELNET_STATE_DO;
832 break;
833 case TELNET_DONT:
834 telnet->state = TELNET_STATE_DONT;
835 break;
836
837 case TELNET_IAC:
838
839 ev.type = TELNET_EV_DATA;
840 ev.data.buffer = (char*)&byte;
841 ev.data.size = 1;
842 telnet->eh(telnet, &ev, telnet->ud);
843
844
845 start = i + 1;
846 telnet->state = TELNET_STATE_DATA;
847 break;
848
849 default:
850
851 ev.type = TELNET_EV_IAC;
852 ev.iac.cmd = byte;
853 telnet->eh(telnet, &ev, telnet->ud);
854
855
856 start = i + 1;
857 telnet->state = TELNET_STATE_DATA;
858 }
859 break;
860
861
862 case TELNET_STATE_WILL:
863 case TELNET_STATE_WONT:
864 case TELNET_STATE_DO:
865 case TELNET_STATE_DONT:
866 _negotiate(telnet, byte);
867 start = i + 1;
868 telnet->state = TELNET_STATE_DATA;
869 break;
870
871
872 case TELNET_STATE_SB:
873 telnet->sb_telopt = byte;
874 telnet->buffer_pos = 0;
875 telnet->state = TELNET_STATE_SB_DATA;
876 break;
877
878
879 case TELNET_STATE_SB_DATA:
880
881 if (byte == TELNET_IAC) {
882 telnet->state = TELNET_STATE_SB_DATA_IAC;
883 } else if (_buffer_byte(telnet, byte) != TELNET_EOK) {
884 start = i + 1;
885 telnet->state = TELNET_STATE_DATA;
886 }
887 break;
888
889
890 case TELNET_STATE_SB_DATA_IAC:
891 switch (byte) {
892
893 case TELNET_SE:
894
895 start = i + 1;
896 telnet->state = TELNET_STATE_DATA;
897
898
899 if (_subnegotiate(telnet) != 0) {
900 telnet_recv(telnet, &buffer[start], size - start);
901 return;
902 }
903 break;
904
905 case TELNET_IAC:
906
907 if (_buffer_byte(telnet, TELNET_IAC) !=
908 TELNET_EOK) {
909 start = i + 1;
910 telnet->state = TELNET_STATE_DATA;
911 } else {
912 telnet->state = TELNET_STATE_SB_DATA;
913 }
914 break;
915
916
917
918
919
920
921 default:
922 _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0,
923 "unexpected byte after IAC inside SB: %d",
924 byte);
925
926
927 start = i + 1;
928 telnet->state = TELNET_STATE_IAC;
929
930
931
932
933
934
935 if (_subnegotiate(telnet) != 0) {
936 telnet_recv(telnet, &buffer[start], size - start);
937 return;
938 } else {
939
940
941
942
943
944
945 _process(telnet, (char *)&byte, 1);
946 }
947 break;
948 }
949 break;
950 }
951 }
952
953
954 if (telnet->state == TELNET_STATE_DATA && i != start) {
955 ev.type = TELNET_EV_DATA;
956 ev.data.buffer = buffer + start;
957 ev.data.size = i - start;
958 telnet->eh(telnet, &ev, telnet->ud);
959 }
960 }
961
962
963 void telnet_recv(telnet_t *telnet, const char *buffer,
964 size_t size) {
965 _process(telnet, buffer, size);
966 }
967
968
969 void telnet_iac(telnet_t *telnet, unsigned char cmd) {
970 unsigned char bytes[2];
971 bytes[0] = TELNET_IAC;
972 bytes[1] = cmd;
973 _sendu(telnet, bytes, 2);
974 }
975
976
977 void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
978 unsigned char telopt) {
979 telnet_rfc1143_t q;
980
981
982 if (telnet->flags & TELNET_FLAG_PROXY) {
983 unsigned char bytes[3];
984 bytes[0] = TELNET_IAC;
985 bytes[1] = cmd;
986 bytes[2] = telopt;
987 _sendu(telnet, bytes, 3);
988 return;
989 }
990
991
992 q = _get_rfc1143(telnet, telopt);
993
994 switch (cmd) {
995
996 case TELNET_WILL:
997 switch (Q_US(q)) {
998 case Q_NO:
999 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
1000 _send_negotiate(telnet, TELNET_WILL, telopt);
1001 break;
1002 case Q_WANTNO:
1003 _set_rfc1143(telnet, telopt, Q_WANTNO_OP, Q_HIM(q));
1004 break;
1005 case Q_WANTYES_OP:
1006 _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
1007 break;
1008 }
1009 break;
1010
1011
1012 case TELNET_WONT:
1013 switch (Q_US(q)) {
1014 case Q_YES:
1015 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
1016 _send_negotiate(telnet, TELNET_WONT, telopt);
1017 break;
1018 case Q_WANTYES:
1019 _set_rfc1143(telnet, telopt, Q_WANTYES_OP, Q_HIM(q));
1020 break;
1021 case Q_WANTNO_OP:
1022 _set_rfc1143(telnet, telopt, Q_WANTNO, Q_HIM(q));
1023 break;
1024 }
1025 break;
1026
1027
1028 case TELNET_DO:
1029 switch (Q_HIM(q)) {
1030 case Q_NO:
1031 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
1032 _send_negotiate(telnet, TELNET_DO, telopt);
1033 break;
1034 case Q_WANTNO:
1035 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO_OP);
1036 break;
1037 case Q_WANTYES_OP:
1038 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
1039 break;
1040 }
1041 break;
1042
1043
1044 case TELNET_DONT:
1045 switch (Q_HIM(q)) {
1046 case Q_YES:
1047 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
1048 _send_negotiate(telnet, TELNET_DONT, telopt);
1049 break;
1050 case Q_WANTYES:
1051 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES_OP);
1052 break;
1053 case Q_WANTNO_OP:
1054 _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTNO);
1055 break;
1056 }
1057 break;
1058 }
1059 }
1060
1061
1062 void telnet_send(telnet_t *telnet, const char *buffer,
1063 size_t size) {
1064 size_t i, l;
1065
1066 for (l = i = 0; i != size; ++i) {
1067
1068 if (buffer[i] == (char)TELNET_IAC) {
1069
1070 if (i != l) {
1071 _send(telnet, buffer + l, i - l);
1072 }
1073 l = i + 1;
1074
1075
1076 telnet_iac(telnet, TELNET_IAC);
1077 }
1078 }
1079
1080
1081 if (i != l) {
1082 _send(telnet, buffer + l, i - l);
1083 }
1084 }
1085
1086
1087 void telnet_send_text(telnet_t *telnet, const char *buffer,
1088 size_t size) {
1089 size_t i, l;
1090
1091 for (l = i = 0; i != size; ++i) {
1092
1093 if (buffer[i] == (char)TELNET_IAC) {
1094
1095 if (i != l) {
1096 _send(telnet, buffer + l, i - l);
1097 }
1098 l = i + 1;
1099
1100
1101 telnet_iac(telnet, TELNET_IAC);
1102 }
1103
1104 else if (!(telnet->flags & TELNET_FLAG_TRANSMIT_BINARY) &&
1105 (buffer[i] == '\r' || buffer[i] == '\n')) {
1106
1107 if (i != l) {
1108 _send(telnet, buffer + l, i - l);
1109 }
1110 l = i + 1;
1111
1112
1113 if (buffer[i] == '\r') {
1114 _send(telnet, CRNUL, 2);
1115 }
1116
1117 else {
1118 _send(telnet, CRLF, 2);
1119 }
1120 }
1121 }
1122
1123
1124 if (i != l) {
1125 _send(telnet, buffer + l, i - l);
1126 }
1127 }
1128
1129
1130 void telnet_begin_sb(telnet_t *telnet, unsigned char telopt) {
1131 unsigned char sb[3];
1132 sb[0] = TELNET_IAC;
1133 sb[1] = TELNET_SB;
1134 sb[2] = telopt;
1135 _sendu(telnet, sb, 3);
1136 }
1137
1138
1139 int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
1140 char buffer[1024];
1141 char *output = buffer;
1142 int rs, i, l;
1143
1144
1145 va_list va2;
1146 va_copy(va2, va);
1147 rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
1148 if ((unsigned long) rs >= sizeof(buffer)) {
1149 output = (char*)malloc((unsigned long) ((unsigned long)rs + 1L));
1150 if (output == 0) {
1151 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
1152 "malloc() failed: %s", xstrerror_l(errno));
1153 va_end(va2);
1154 return -1;
1155 }
1156 rs = vsnprintf(output, rs + 1, fmt, va2);
1157 }
1158 va_end(va2);
1159 va_end(va);
1160
1161
1162 for (l = i = 0; i != rs; ++i) {
1163
1164 if (output[i] == (char)TELNET_IAC || output[i] == '\r' ||
1165 output[i] == '\n') {
1166
1167 if (i != l)
1168 _send(telnet, output + l, (size_t) (i - l));
1169 l = i + 1;
1170
1171
1172 if (output[i] == (char)TELNET_IAC)
1173 telnet_iac(telnet, TELNET_IAC);
1174
1175 else if (output[i] == '\r')
1176 _send(telnet, CRNUL, 2);
1177
1178 else if (output[i] == '\n')
1179 _send(telnet, CRLF, 2);
1180 }
1181 }
1182
1183
1184 if (i != l) {
1185 _send(telnet, output + l, (size_t) (i - l));
1186 }
1187
1188
1189 if (output != buffer) {
1190 FREE(output);
1191 }
1192
1193 return rs;
1194 }
1195
1196
1197 int telnet_printf(telnet_t *telnet, const char *fmt, ...) {
1198 va_list va;
1199 int rs;
1200
1201 va_start(va, fmt);
1202 rs = telnet_vprintf(telnet, fmt, va);
1203 va_end(va);
1204
1205 return rs;
1206 }
1207
1208
1209 int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
1210 char buffer[1024];
1211 char *output = buffer;
1212 int rs;
1213
1214
1215 va_list va2;
1216 va_copy(va2, va);
1217 rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
1218 if ((unsigned long) rs >= sizeof(buffer)) {
1219 output = (char*)malloc((unsigned long) rs + 1);
1220 if (output == 0) {
1221 _error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0,
1222 "malloc() failed: %s", xstrerror_l(errno));
1223 va_end(va2);
1224 return -1;
1225 }
1226 rs = vsnprintf(output, (int)((unsigned int) rs + 1), fmt, va2);
1227 }
1228 va_end(va2);
1229 va_end(va);
1230
1231
1232 telnet_send(telnet, output, (size_t) rs);
1233
1234
1235 if (output != buffer) {
1236 FREE(output);
1237 }
1238
1239 return rs;
1240 }
1241
1242
1243 int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...) {
1244 va_list va;
1245 int rs;
1246
1247 va_start(va, fmt);
1248 rs = telnet_raw_vprintf(telnet, fmt, va);
1249 va_end(va);
1250
1251 return rs;
1252 }