moved here from the newlib branch
[platform/upstream/curl.git] / lib / telnet.c
1 /*****************************************************************************
2  *                                  _   _ ____  _     
3  *  Project                     ___| | | |  _ \| |    
4  *                             / __| | | | |_) | |    
5  *                            | (__| |_| |  _ <| |___ 
6  *                             \___|\___/|_| \_\_____|
7  *
8  *  The contents of this file are subject to the Mozilla Public License
9  *  Version 1.0 (the "License"); you may not use this file except in
10  *  compliance with the License. You may obtain a copy of the License at
11  *  http://www.mozilla.org/MPL/
12  *
13  *  Software distributed under the License is distributed on an "AS IS"
14  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
15  *  License for the specific language governing rights and limitations
16  *  under the License.
17  *
18  *  The Original Code is Curl.
19  *
20  *  The Initial Developer of the Original Code is Daniel Stenberg.
21  *
22  *  Portions created by the Initial Developer are Copyright (C) 1998.
23  *  All Rights Reserved.
24  *
25  * ------------------------------------------------------------
26  * Main author:
27  * - Daniel Stenberg <Daniel.Stenberg@haxx.nu>
28  *
29  *      http://curl.haxx.nu
30  *
31  * $Source$
32  * $Revision$
33  * $Date$
34  * $Author$
35  * $State$
36  * $Locker$
37  *
38  * ------------------------------------------------------------
39  *
40  * This implementation of the TELNET protocol is written by
41  * Linus Nielsen <Linus.Nielsen@haxx.nu>,
42  * with some code snippets stolen from the BSD Telnet client.
43  *
44  * The negotiation is performed according to RFC 1143 (D. Bernstein,
45  * "The Q Method of Implementing TELNET Option Negotiation")
46  *
47  ****************************************************************************/
48
49 /* -- WIN32 approved -- */
50 #include <stdio.h>
51 #include <string.h>
52 #include <stdarg.h>
53 #include <stdlib.h>
54 #include <ctype.h>
55 #include <sys/types.h>
56 #include <sys/stat.h>
57
58 #include <errno.h>
59
60 #include "setup.h"
61
62 #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
63 #include <winsock.h>
64 #include <time.h>
65 #include <io.h>
66 #else
67 #ifdef HAVE_SYS_SOCKET_H
68 #include <sys/socket.h>
69 #endif
70 #include <netinet/in.h>
71 #include <sys/time.h>
72 #include <sys/resource.h>
73 #ifdef HAVE_UNISTD_H
74 #include <unistd.h>
75 #endif
76 #include <netdb.h>
77 #ifdef HAVE_ARPA_INET_H
78 #include <arpa/inet.h>
79 #endif
80 #ifdef HAVE_NET_IF_H
81 #include <net/if.h>
82 #endif
83 #include <sys/ioctl.h>
84 #include <signal.h>
85
86 #ifdef HAVE_SYS_PARAM_H
87 #include <sys/param.h>
88 #endif
89
90 #ifdef HAVE_SYS_SELECT_H
91 #include <sys/select.h>
92 #endif
93
94
95 #endif
96
97 #include "urldata.h"
98 #include <curl/curl.h>
99 #include "download.h"
100 #include "sendf.h"
101 #include "formdata.h"
102 #include "progress.h"
103
104 #define _MPRINTF_REPLACE /* use our functions only */
105 #include <curl/mprintf.h>
106
107 #define  TELOPTS
108 #define  TELCMDS
109 #define  SLC_NAMES
110
111 #include "arpa_telnet.h"
112
113 #define SUBBUFSIZE 512
114
115 #define  SB_CLEAR()  subpointer = subbuffer;
116 #define  SB_TERM()   { subend = subpointer; SB_CLEAR(); }
117 #define  SB_ACCUM(c) if (subpointer < (subbuffer+sizeof subbuffer)) { \
118             *subpointer++ = (c); \
119          }
120
121 #define  SB_GET() ((*subpointer++)&0xff)
122 #define  SB_PEEK()   ((*subpointer)&0xff)
123 #define  SB_EOF() (subpointer >= subend)
124 #define  SB_LEN() (subend - subpointer)
125
126 void telwrite(struct UrlData *data,
127               unsigned char *buffer,    /* Data to write */
128               int count);               /* Number of bytes to write */
129
130 void telrcv(struct UrlData *data,
131             unsigned char *inbuf,       /* Data received from socket */
132             int count);                 /* Number of bytes received */
133
134 static void printoption(struct UrlData *data,
135                         const char *direction,
136                         int cmd, int option);
137
138 static void negotiate(struct UrlData *data);
139 static void send_negotiation(struct UrlData *data, int cmd, int option);
140 static void set_local_option(struct UrlData *data, int cmd, int option);
141 static void set_remote_option(struct UrlData *data, int cmd, int option);
142
143 static void printsub(struct UrlData *data,
144                      int direction, unsigned char *pointer, int length);
145 static void suboption(struct UrlData *data);
146
147 /* suboptions */
148 static char subbuffer[SUBBUFSIZE];
149 static char *subpointer, *subend;    /* buffer for sub-options */
150
151 /*
152  * Telnet receiver states for fsm
153  */
154 static enum
155 {
156    TS_DATA = 0,
157    TS_IAC,
158    TS_WILL,
159    TS_WONT,
160    TS_DO,
161    TS_DONT,
162    TS_CR,
163    TS_SB,   /* sub-option collection */
164    TS_SE   /* looking for sub-option end */
165 } telrcv_state;
166
167 /* For negotiation compliant to RFC 1143 */
168 #define NO      0
169 #define YES     1
170 #define WANTYES 2
171 #define WANTNO  3
172
173 #define EMPTY    0
174 #define OPPOSITE 1
175
176 static int us[256]; 
177 static int usq[256]; 
178 static int us_preferred[256]; 
179 static int him[256]; 
180 static int himq[256]; 
181 static int him_preferred[256]; 
182
183 void init_telnet(struct UrlData *data)
184 {
185    telrcv_state = TS_DATA;
186
187    /* Init suboptions */
188    SB_CLEAR();
189
190    /* Set all options to NO */
191    memset(us, NO, 256);
192    memset(usq, NO, 256);
193    memset(us_preferred, NO, 256);
194    memset(him, NO, 256);
195    memset(himq, NO, 256);
196    memset(him_preferred, NO, 256);
197
198    /* Set the options we want */
199    us_preferred[TELOPT_BINARY] = YES;
200    us_preferred[TELOPT_SGA] = YES;
201    him_preferred[TELOPT_BINARY] = YES;
202    him_preferred[TELOPT_SGA] = YES;
203
204    /* Start negotiating */
205    negotiate(data);
206 }
207
208 static void negotiate(struct UrlData *data)
209 {
210    int i;
211    
212    for(i = 0;i < NTELOPTS;i++)
213    {
214       if(us_preferred[i] == YES)
215          set_local_option(data, i, YES);
216       
217       if(him_preferred[i] == YES)
218          set_remote_option(data, i, YES);
219    }
220 }
221
222 static void printoption(struct UrlData *data,
223                         const char *direction, int cmd, int option)
224 {
225    char *fmt;
226    char *opt;
227    
228    if (data->bits.verbose)
229    {
230       if (cmd == IAC)
231       {
232          if (TELCMD_OK(option))
233             printf("%s IAC %s\n", direction, TELCMD(option));
234          else
235             printf("%s IAC %d\n", direction, option);
236       }
237       else
238       {
239          fmt = (cmd == WILL) ? "WILL" : (cmd == WONT) ? "WONT" :
240             (cmd == DO) ? "DO" : (cmd == DONT) ? "DONT" : 0;
241          if (fmt)
242          {
243             if (TELOPT_OK(option))
244                opt = TELOPT(option);
245             else if (option == TELOPT_EXOPL)
246                opt = "EXOPL";
247             else
248                opt = NULL;
249
250             if(opt)
251                printf("%s %s %s\n", direction, fmt, opt);
252             else
253                printf("%s %s %d\n", direction, fmt, option);
254          }
255          else
256             printf("%s %d %d\n", direction, cmd, option);
257       }
258    }
259 }
260
261 static void send_negotiation(struct UrlData *data, int cmd, int option)
262 {
263    unsigned char buf[3];
264
265    buf[0] = IAC;
266    buf[1] = cmd;
267    buf[2] = option;
268    
269    swrite(data->firstsocket, buf, 3);
270    
271    printoption(data, "SENT", cmd, option);
272 }
273
274 void set_remote_option(struct UrlData *data, int option, int newstate)
275 {
276    if(newstate == YES)
277    {
278       switch(him[option])
279       {
280       case NO:
281          him[option] = WANTYES;
282          send_negotiation(data, DO, option);
283          break;
284          
285       case YES:
286          /* Already enabled */
287          break;
288          
289       case WANTNO:
290          switch(himq[option])
291          {
292          case EMPTY:
293             /* Already negotiating for YES, queue the request */
294             himq[option] = OPPOSITE;
295             break;
296          case OPPOSITE:
297             /* Error: already queued an enable request */
298             break;
299          }
300          break;
301          
302       case WANTYES:
303          switch(himq[option])
304          {
305          case EMPTY:
306             /* Error: already negotiating for enable */
307             break;
308          case OPPOSITE:
309             himq[option] = EMPTY;
310             break;
311          }
312          break;
313       }
314    }
315    else /* NO */
316    {
317       switch(him[option])
318       {
319       case NO:
320          /* Already disabled */
321          break;
322          
323       case YES:
324          him[option] = WANTNO;
325          send_negotiation(data, DONT, option);
326          break;
327          
328       case WANTNO:
329          switch(himq[option])
330          {
331          case EMPTY:
332             /* Already negotiating for NO */
333             break;
334          case OPPOSITE:
335             himq[option] = EMPTY;
336             break;
337          }
338          break;
339          
340       case WANTYES:
341          switch(himq[option])
342          {
343          case EMPTY:
344             himq[option] = OPPOSITE;
345             break;
346          case OPPOSITE:
347             break;
348          }
349          break;
350       }
351    }
352 }
353
354 void rec_will(struct UrlData *data, int option)
355 {
356    switch(him[option])
357    {
358    case NO:
359       if(him_preferred[option] == YES)
360       {
361          him[option] = YES;
362          send_negotiation(data, DO, option);
363       }
364       else
365       {
366          send_negotiation(data, DONT, option);
367       }
368       break;
369          
370    case YES:
371       /* Already enabled */
372       break;
373          
374    case WANTNO:
375       switch(himq[option])
376       {
377       case EMPTY:
378          /* Error: DONT answered by WILL */
379          him[option] = NO;
380          break;
381       case OPPOSITE:
382          /* Error: DONT answered by WILL */
383          him[option] = YES;
384          himq[option] = EMPTY;
385          break;
386       }
387       break;
388          
389    case WANTYES:
390       switch(himq[option])
391       {
392       case EMPTY:
393          him[option] = YES;
394          break;
395       case OPPOSITE:
396          him[option] = WANTNO;
397          himq[option] = EMPTY;
398          send_negotiation(data, DONT, option);
399          break;
400       }
401       break;
402    }
403 }
404    
405 void rec_wont(struct UrlData *data, int option)
406 {
407    switch(him[option])
408    {
409    case NO:
410       /* Already disabled */
411       break;
412          
413    case YES:
414       him[option] = NO;
415       send_negotiation(data, DONT, option);
416       break;
417          
418    case WANTNO:
419       switch(himq[option])
420       {
421       case EMPTY:
422          him[option] = NO;
423          break;
424          
425       case OPPOSITE:
426          him[option] = WANTYES;
427          himq[option] = EMPTY;
428          send_negotiation(data, DO, option);
429          break;
430       }
431       break;
432          
433    case WANTYES:
434       switch(himq[option])
435       {
436       case EMPTY:
437          him[option] = NO;
438          break;
439       case OPPOSITE:
440          him[option] = NO;
441          himq[option] = EMPTY;
442          break;
443       }
444       break;
445    }
446 }
447    
448 void set_local_option(struct UrlData *data, int option, int newstate)
449 {
450    if(newstate == YES)
451    {
452       switch(us[option])
453       {
454       case NO:
455          us[option] = WANTYES;
456          send_negotiation(data, WILL, option);
457          break;
458          
459       case YES:
460          /* Already enabled */
461          break;
462          
463       case WANTNO:
464          switch(usq[option])
465          {
466          case EMPTY:
467             /* Already negotiating for YES, queue the request */
468             usq[option] = OPPOSITE;
469             break;
470          case OPPOSITE:
471             /* Error: already queued an enable request */
472             break;
473          }
474          break;
475          
476       case WANTYES:
477          switch(usq[option])
478          {
479          case EMPTY:
480             /* Error: already negotiating for enable */
481             break;
482          case OPPOSITE:
483             usq[option] = EMPTY;
484             break;
485          }
486          break;
487       }
488    }
489    else /* NO */
490    {
491       switch(us[option])
492       {
493       case NO:
494          /* Already disabled */
495          break;
496          
497       case YES:
498          us[option] = WANTNO;
499          send_negotiation(data, WONT, option);
500          break;
501          
502       case WANTNO:
503          switch(usq[option])
504          {
505          case EMPTY:
506             /* Already negotiating for NO */
507             break;
508          case OPPOSITE:
509             usq[option] = EMPTY;
510             break;
511          }
512          break;
513          
514       case WANTYES:
515          switch(usq[option])
516          {
517          case EMPTY:
518             usq[option] = OPPOSITE;
519             break;
520          case OPPOSITE:
521             break;
522          }
523          break;
524       }
525    }
526 }
527
528 void rec_do(struct UrlData *data, int option)
529 {
530    switch(us[option])
531    {
532    case NO:
533       if(us_preferred[option] == YES)
534       {
535          us[option] = YES;
536          send_negotiation(data, WILL, option);
537       }
538       else
539       {
540          send_negotiation(data, WONT, option);
541       }
542       break;
543          
544    case YES:
545       /* Already enabled */
546       break;
547          
548    case WANTNO:
549       switch(usq[option])
550       {
551       case EMPTY:
552          /* Error: DONT answered by WILL */
553          us[option] = NO;
554          break;
555       case OPPOSITE:
556          /* Error: DONT answered by WILL */
557          us[option] = YES;
558          usq[option] = EMPTY;
559          break;
560       }
561       break;
562          
563    case WANTYES:
564       switch(usq[option])
565       {
566       case EMPTY:
567          us[option] = YES;
568          break;
569       case OPPOSITE:
570          us[option] = WANTNO;
571          himq[option] = EMPTY;
572          send_negotiation(data, WONT, option);
573          break;
574       }
575       break;
576    }
577 }
578    
579 void rec_dont(struct UrlData *data, int option)
580 {
581    switch(us[option])
582    {
583    case NO:
584       /* Already disabled */
585       break;
586          
587    case YES:
588       us[option] = NO;
589       send_negotiation(data, WONT, option);
590       break;
591          
592    case WANTNO:
593       switch(usq[option])
594       {
595       case EMPTY:
596          us[option] = NO;
597          break;
598          
599       case OPPOSITE:
600          us[option] = WANTYES;
601          usq[option] = EMPTY;
602          send_negotiation(data, WILL, option);
603          break;
604       }
605       break;
606          
607    case WANTYES:
608       switch(usq[option])
609       {
610       case EMPTY:
611          us[option] = NO;
612          break;
613       case OPPOSITE:
614          us[option] = NO;
615          usq[option] = EMPTY;
616          break;
617       }
618       break;
619    }
620 }
621
622
623 static void printsub(struct UrlData *data,
624                      int direction,             /* '<' or '>' */
625                      unsigned char *pointer,    /* where suboption data is */
626                      int length)                /* length of suboption data */
627
628 {
629    int i = 0;
630
631    if (data->bits.verbose)
632    {
633       if (direction)
634       {
635          printf("%s IAC SB ", (direction == '<')? "RCVD":"SENT");
636          if (length >= 3)
637          {
638             int j;
639
640             i = pointer[length-2];
641             j = pointer[length-1];
642
643             if (i != IAC || j != SE)
644             {
645                printf("(terminated by ");
646                if (TELOPT_OK(i))
647                   printf("%s ", TELOPT(i));
648                else if (TELCMD_OK(i))
649                   printf("%s ", TELCMD(i));
650                else
651                   printf("%d ", i);
652                if (TELOPT_OK(j))
653                   printf("%s", TELOPT(j));
654                else if (TELCMD_OK(j))
655                   printf("%s", TELCMD(j));
656                else
657                   printf("%d", j);
658                printf(", not IAC SE!) ");
659             }
660          }
661          length -= 2;
662       }
663       if (length < 1)
664       {
665          printf("(Empty suboption?)");
666          return;
667       }
668
669       if (TELOPT_OK(pointer[0]))
670          printf("%s (unknown)", TELOPT(pointer[0]));
671       else
672          printf("%d (unknown)", pointer[i]);
673       for (i = 1; i < length; i++)
674          printf(" %d", pointer[i]);
675       
676       if (direction)
677       {
678          printf("\n");
679       }
680    }
681 }
682
683 /*
684  * suboption()
685  *
686  * Look at the sub-option buffer, and try to be helpful to the other
687  * side.
688  * No suboptions are supported yet.
689  */
690
691 static void suboption(struct UrlData *data)
692 {
693    printsub(data, '<', (unsigned char *)subbuffer, SB_LEN()+2);
694    return;
695 }
696
697 void telrcv(struct UrlData *data,
698             unsigned char *inbuf,       /* Data received from socket */
699             int count)                  /* Number of bytes received */
700 {
701    unsigned char c;
702    int index = 0;
703
704    while(count--)
705    {
706       c = inbuf[index++];
707
708       switch (telrcv_state)
709       {
710       case TS_CR:
711          telrcv_state = TS_DATA;
712          if (c == '\0')
713          {
714             break;   /* Ignore \0 after CR */
715          }
716          
717          data->fwrite((char *)&c, 1, 1, data->out);
718          continue;
719
720       case TS_DATA:
721          if (c == IAC)
722          {
723             telrcv_state = TS_IAC;
724             break;
725          }
726          else if(c == '\r')
727          {
728             telrcv_state = TS_CR;
729          }
730
731          data->fwrite((char *)&c, 1, 1, data->out);
732          continue;
733
734       case TS_IAC:
735         process_iac:
736         switch (c)
737         {
738         case WILL:
739            telrcv_state = TS_WILL;
740            continue;
741         case WONT:
742            telrcv_state = TS_WONT;
743            continue;
744         case DO:
745            telrcv_state = TS_DO;
746            continue;
747         case DONT:
748            telrcv_state = TS_DONT;
749            continue;
750         case SB:
751            SB_CLEAR();
752            telrcv_state = TS_SB;
753            continue;
754         case IAC:
755            data->fwrite((char *)&c, 1, 1, data->out);
756            break;
757         case DM:
758         case NOP:
759         case GA:
760         default:
761            printoption(data, "RCVD", IAC, c);
762            break;
763         }
764         telrcv_state = TS_DATA;
765         continue;
766
767       case TS_WILL:
768          printoption(data, "RCVD", WILL, c);
769          rec_will(data, c);
770          telrcv_state = TS_DATA;
771          continue;
772       
773       case TS_WONT:
774          printoption(data, "RCVD", WONT, c);
775          rec_wont(data, c);
776          telrcv_state = TS_DATA;
777          continue;
778       
779       case TS_DO:
780          printoption(data, "RCVD", DO, c);
781          rec_do(data, c);
782          telrcv_state = TS_DATA;
783          continue;
784       
785       case TS_DONT:
786          printoption(data, "RCVD", DONT, c);
787          rec_dont(data, c);
788          telrcv_state = TS_DATA;
789          continue;
790
791       case TS_SB:
792          if (c == IAC)
793          {
794             telrcv_state = TS_SE;
795          }
796          else
797          {
798             SB_ACCUM(c);
799          }
800          continue;
801
802       case TS_SE:
803          if (c != SE)
804          {
805             if (c != IAC)
806             {
807                /*
808                 * This is an error.  We only expect to get
809                 * "IAC IAC" or "IAC SE".  Several things may
810                 * have happend.  An IAC was not doubled, the
811                 * IAC SE was left off, or another option got
812                 * inserted into the suboption are all possibilities.
813                 * If we assume that the IAC was not doubled,
814                 * and really the IAC SE was left off, we could
815                 * get into an infinate loop here.  So, instead,
816                 * we terminate the suboption, and process the
817                 * partial suboption if we can.
818                 */
819                SB_ACCUM((unsigned char)IAC);
820                SB_ACCUM(c);
821                subpointer -= 2;
822                SB_TERM();
823             
824                printoption(data, "In SUBOPTION processing, RCVD", IAC, c);
825                suboption(data);   /* handle sub-option */
826                telrcv_state = TS_IAC;
827                goto process_iac;
828             }
829             SB_ACCUM(c);
830             telrcv_state = TS_SB;
831          }
832          else
833          {
834             SB_ACCUM((unsigned char)IAC);
835             SB_ACCUM((unsigned char)SE);
836             subpointer -= 2;
837             SB_TERM();
838             suboption(data);   /* handle sub-option */
839             telrcv_state = TS_DATA;
840          }
841          break;
842       }
843    }
844 }
845
846 void telwrite(struct UrlData *data,
847               unsigned char *buffer,    /* Data to write */
848               int count)                /* Number of bytes to write */
849 {
850    unsigned char outbuf[2];
851    int out_count = 0;
852    int bytes_written;
853
854    while(count--)
855    {
856       outbuf[0] = *buffer++;
857       out_count = 1;
858       if(outbuf[0] == IAC)
859          outbuf[out_count++] = IAC;
860       
861 #ifndef USE_SSLEAY
862       bytes_written = swrite(data->firstsocket, outbuf, out_count);
863 #else
864       if (data->use_ssl) {
865         bytes_written = SSL_write(data->ssl, (char *)outbuf, out_count);
866       }
867       else {
868         bytes_written = swrite(data->firstsocket, outbuf, out_count);
869       }
870 #endif /* USE_SSLEAY */
871    }
872 }
873
874 CURLcode telnet_done(struct connectdata *conn)
875 {
876   return CURLE_OK;
877 }
878
879 CURLcode telnet(struct connectdata *conn)
880 {
881   struct UrlData *data = conn->data;
882   int sockfd = data->firstsocket;
883   fd_set readfd;
884   fd_set keepfd;
885
886   bool keepon = TRUE;
887   char *buf = data->buffer;
888   int nread;
889
890   init_telnet(data);
891    
892   FD_ZERO (&readfd);            /* clear it */
893   FD_SET (sockfd, &readfd);
894   FD_SET (1, &readfd);
895
896   keepfd = readfd;
897
898    while (keepon)
899    {
900       readfd = keepfd;          /* set this every lap in the loop */
901
902       switch (select (sockfd + 1, &readfd, NULL, NULL, NULL))
903       {
904       case -1:                  /* error, stop reading */
905          keepon = FALSE;
906          continue;
907       case 0:                   /* timeout */
908          break;
909       default:                  /* read! */
910          if(FD_ISSET(1, &readfd))
911          {
912             nread = read(1, buf, 255);
913             telwrite(data, (unsigned char *)buf, nread);
914          }
915
916          if(FD_ISSET(sockfd, &readfd))
917          {
918 #ifndef USE_SSLEAY
919             nread = sread (sockfd, buf, BUFSIZE - 1);
920 #else
921             if (data->use_ssl) {
922                nread = SSL_read (data->ssl, buf, BUFSIZE - 1);
923             }
924             else {
925                nread = sread (sockfd, buf, BUFSIZE - 1);
926             }
927 #endif /* USE_SSLEAY */
928          }
929
930          /* if we receive 0 or less here, the server closed the connection and
931            we bail out from this! */
932         if (nread <= 0) {
933           keepon = FALSE;
934           break;
935         }
936
937          telrcv(data, (unsigned char *)buf, nread);
938       }
939    }
940    return CURLE_OK;
941 }
942
943