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