/* rtlntb.c */ /* * Includes */ #include #include #include "vrtel.h" #include "dfault.h" #include "evtdef.h" #include "hstdef.h" #include "prodef.h" #include "kbkeys.h" #include "cliutl.h" #include "tsxutl.h" #include "rtfile.h" #include "kbdutl.h" #include "inicli.h" #include "jobmon.h" #include "usrblk.h" #include "suspnd.h" /* * Internal routines */ extern VOID printtxt(); extern int cltsxline(); extern int setrtel(); extern int dosess(); extern VOID rctresp(); extern VOID transfer(); extern VOID lsterr(); extern int rtresp(); extern char *stptok(); extern char *stpblk(); extern VOID strlwr(); extern int getword(); extern VOID rteld(); extern VOID initsession(); extern int parse(); extern int cparse(); extern int Scheckpass(); extern int Scompass(); /* * debug - * * bit 0 (0x01) enable printing of internal events * bit 1 (0x02) enable printing of telnet negotiations */ #define DBUGTRUE -1 /* all debuggers */ extern char *usetxt[]; /* Definitions for telnet protocol */ #define ABORT (-3) #define SE 240 /* \360 */ #define NOP 241 /* \361 */ #define DM 242 /* \362 */ #define BREAK 243 /* \363 */ #define IP 244 /* \364 */ #define AO 245 /* \365 */ #define AYT 246 /* \366 */ #define EC 247 /* \367 */ #define EL 248 /* \370 */ #define GOAHEAD 249 /* \371 */ #define SB 250 /* \372 */ #define WILLTEL 251 /* \373 */ #define WONTTEL 252 /* \374 */ #define DOTEL 253 /* \375 */ #define DONTTEL 254 /* \376 */ #define IAC 255 /* \377 */ /* Assigned Telnet Options */ #define BINARY 0 #define ECHO 1 #define RECONNECT 2 #define SGA 3 #define AMSN 4 #define STATUS 5 #define TIMING 6 #define RCTAN 7 #define OLW 8 #define OPS 9 #define OCRD 10 #define OHTS 11 #define OHTD 12 #define OFFD 13 #define OVTS 14 #define OVTD 15 #define OLFD 16 #define XASCII 17 #define LOGOUT 18 #define BYTEM 19 #define DET 20 #define SUPDUP 21 #define SUPDUPOUT 22 #define SENDLOC 23 #define TERMTYPE 24 #define EOR 25 #define TACACSUID 26 #define OUTPUTMARK 27 #define TERMLOCNUM 28 #define REGIME3270 29 #define X3PAD 30 #define NAWS 31 #define TERMSPEED 32 #define TFLOWCNTRL 33 #define LINEMODE 34 #define MODE 1 #define EDIT 1 #define TRAPSIG 2 #define MODE_ACK 4 #define FORWARDMASK 2 #define SLC 3 #define NO_SUPPORT 0 #define CANTCHANGE 1 #define SLC_VALUE 2 #define SLC_DEFAULT 3 #define SLC_LEVELBITS 3 #define SLC_AWK 128 #define SLC_SYNCH 1 #define SLC_BRK 2 #define SLC_IP 3 #define SLC_AO 4 #define SLC_AYT 5 #define SLC_EOR 6 #define SLC_ABORT 7 #define SLC_EOF 8 #define SLC_SUSP 9 #define SLC_EC 10 #define SLC_EL 11 #define SLC_EW 12 #define SLC_RP 13 #define SLC_LNEXT 14 #define SLC_XON 15 #define SLC_XOFF 16 #define SLC_FORW1 17 #define SLC_FORW2 18 #define XDISPLOC 35 #define XOPTIONS 255 #define IACFOUND 6 #define CRFOUND 3 #define WILLSB 2 #define NEGOTIATE 1 #define STNORM 0 extern char *telstates[]; extern char *teloptions[]; extern char *LMoptions[]; extern char *LMflags[]; /* * Global Buffers / Pointers */ extern char pathname[], /* path */ username[], /* username */ password[], /* password */ command[], /* command string */ rsp[], /* response string */ scratch[]; /* scratch string */ extern struct userblock user; /* usernames / passwords / mailboxes */ extern char xs[]; /* dumby buffer required by TSXUTL.C */ extern int aflag, /* attach flag */ rflag, /* restart flag */ mflag, /* monitor flag */ pswdreqd, /* password required */ clunit, /* CL unit number */ tsxline, /* TSX line number */ ctpairs, /* CL/TSX line pairs */ cline, /* CLn line in use */ tline, /* TSX line in use */ cltl, /* CL/TSX line error */ rtelcskt, /* RTELNT socket number */ rfstate, /* current process state */ retstate, /* return state */ waitpos, /* incoming command index */ echo, /* echo flag */ cnctopen, /* connection open flag */ cnctclose, /* connection to be closed flag */ logincnt; /* login retry counter */ extern struct socket *skt; /* socket structure */ extern struct twin *tw; /* window structure */ extern char parsedat[]; /* Telnet parsing */ extern int pindex; /* parsing index */ extern char outbuffer[]; extern int outcnt, /* count to transfer */ outotal, /* count left to transfer */ outidx; /* array index */ extern char inpbuffer[]; extern int inpcnt, /* count to transfer */ rdidx, /* read array index */ wrtidx; /* write array index */ extern char *pass; /* password file */ extern char *mesg; /* message file */ extern char *help; /* help file */ /* * parse * * Do the telnet negotiation parsing. * * look at the character which has just come in from outside and * check for special sequences that we are interested in. * */ int parse(c) int c; { c = cparse(c); if(pushsk) { skenque(tw->pnum,1); } return(c); } int cparse(c) register int c; { register char *ss; register int i; char s[80]; c &= 0xFF; switch(tw->telstate) { case CRFOUND: tw->telstate = STNORM; if(c == '\012') { break; } case STNORM: if(c == IAC) { tw->telstate = IACFOUND; break; } else if(c == '\015') { tw->telstate = CRFOUND; } return(c); case IACFOUND: /* telnet option negotiation */ switch(c) { case IAC: /* real data=255 */ tw->telstate = STNORM; return('\377'); case IP: tw->telstate = STNORM; return(tw->slc[SLC_IP]); case AO: tw->telstate = STNORM; return('O' & 0x1F); case AYT: rctresp( /*Net*/ "\r\nRemote TELNET Running\r\n" /*Net*/ ); tw->telstate = STNORM; break; default: if(248telstate = c; /* by what the option is */ break; } kbprintf("\r\n strange telnet option %d\r\n", c & 0xFF); tw->telstate = STNORM; break; } break; case DOTEL: #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("RECV: %s %s\r\n", telstates[tw->telstate-WILLTEL],teloptions[c]); } #endif switch(c) { case ECHO: break; case SGA: if(!tw->igoahead) { /* suppress go-ahead */ /* IAC, WILLTEL, c */ skwrite(tw->pnum,"\377\373",2); skwchar(tw->pnum,c); tw->igoahead = 1; #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("SEND: %s %s\r\n", telstates[WILLTEL-WILLTEL],teloptions[c]); } #endif } else { #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("NO REPLY NEEDED: %s %s\r\n", telstates[WILLTEL-WILLTEL],teloptions[SGA]); } #endif } break; case LINEMODE: /* IAC, WILLTEL, LINEMODE, IAC, SB, LINEMODE, SLC */ skwrite(tw->pnum,"\377\373\042\377\372\042\003",7); #ifdef DEBUGOPTION if(debug&0x02) { kb_puts("SEND: SB LINEMODE SLC\r\n"); } #endif for (i=1; i<19; i++) { ss = s; *ss++ = i; if (tw->slc[i]==-1) { *ss++ = NO_SUPPORT; *ss++ = 0; } else { *ss++ = CANTCHANGE; *ss++ = tw->slc[i]; } skwrite(tw->pnum,s,3); #ifdef DEBUGOPTION if(debug&0x02) { if(tw->slc[i]==-1) { kbprintf(" %s NO_SUPPORT 0\r\n", LMoptions[i]); } else { kbprintf(" %s CANTCHANGE %d\r\n", LMoptions[i], tw->slc[i]); } } #endif } /* IAC, SE */ skwrite(tw->pnum,"\377\360",2); break; default: /* refuse it */ /* IAC, WONTTEL, c */ skwrite(tw->pnum,"\377\374",2); skwchar(tw->pnum,c); #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("SEND: %s %s\r\n", telstates[WONTTEL-WILLTEL],teloptions[c]); } #endif break; } tw->telstate = STNORM; break; case DONTTEL: #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("RECV: %s %s\r\n", telstates[tw->telstate-WILLTEL],teloptions[c]); } #endif switch(c) { /* which option? */ case ECHO: /* will always echo */ /* IAC, WILLTEL, ECHO */ skwrite(tw->pnum,"\377\373\001",3); break; default: break; } tw->telstate = STNORM; break; case WILLTEL: #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("RECV: %s %s\r\n", telstates[tw->telstate-WILLTEL],teloptions[c]); } #endif #ifdef aaa tw->telstate = WILLSB; tw->substate = c; break; case WILLSB: switch(tw->substate) { #endif switch(c) { case SGA: /* suppress go-ahead */ if(tw->ugoahead) break; /* IAC, DOTEL, SGA */ skwrite(tw->pnum,"\377\375\003",3); tw->ugoahead = 1; #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("SEND: %s %s\r\n", telstates[DOTEL-WILLTEL],teloptions[c]); } #endif break; case TIMING: break; default: /* refuse it */ /* IAC, DONTTEL, c */ skwrite(tw->pnum,"\377\376",2); skwchar(tw->pnum,c); #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("SEND: %s %s\r\n", telstates[DONTTEL-WILLTEL],teloptions[c]); } #endif break; } tw->telstate = STNORM; break; case WONTTEL: #ifdef DEBUGOPTION if(debug&0x02) { kbprintf("RECV: %s %s\r\n", telstates[tw->telstate-WILLTEL],teloptions[c]); } #endif tw->telstate = STNORM; break; case SB: tw->telstate = NEGOTIATE; tw->substate = 0; pindex = 0; break; case NEGOTIATE: if(tw->substate <200) { switch(c) { case IAC: parsedat[pindex] = 0; tw->substate = c; break; default: parsedat[pindex++] = c; break; } } else { switch( tw->substate) { case IAC: tw->substate = c; break; case SE: switch( parsedat[0]) { case LINEMODE: switch( parsedat[1] ) { case DOTEL: /* IAC, SB, LINEMODE */ /* WONTTEL, TRAPSIG */ /* IAC, SE */ skwrite(tw->pnum, "\377\372\042\374\002\377\360",7); break; case WILLTEL: /* IAC, SB, LINEMODE */ /* DONTTEL, TRAPSIG */ /* IAC, SE */ skwrite(tw->pnum, "\377\372\042\376\002\377\360",7); break; case SLC: #ifdef DEBUGOPTION if(debug&0x02) { kb_puts("RECV: SB LINEMODE SLC\r\n"); for(i=2;(parsedat[i]!=0) && (parsedat[i]!=IAC); i+=3) { if(parsedat[i+1] & SLC_AWK) { kbprintf(" %s %s|AWK %d\r\n", LMoptions[parsedat[i]], LMflags[parsedat[i+1] & SLC_LEVELBITS], parsedat[i+2]); } else { kbprintf(" %s %s %d\r\n", LMoptions[parsedat[i]], LMflags[parsedat[i+1] & SLC_LEVELBITS], parsedat[i+2]); } } } #endif /* First check to see if we need to reply */ for(i=2;(parsedat[i]!=0) && (parsedat[i]!=IAC); i+=3) { if(!(parsedat[i+1] & SLC_AWK)) break; } /* if we do then send a reply */ #ifdef DEBUGOPTION if(debug&0x02) { kb_puts("SEND: SB LINEMODE SLC\r\n"); } #endif if ((parsedat[i]!=IAC) && (parsedat[i]!=0)) { /* IAC, SB, LINEMODE, SLC */ skwrite(tw->pnum,"\377\372\042\003",4); for (i=2; (parsedat[i]!=0) && (parsedat[i]!=IAC); i+=3) { if (!(parsedat[i+1] & SLC_AWK)) { ss = s; *ss++ = i; if (tw->slc[parsedat[i]]==-1) { *ss++ = NO_SUPPORT; *ss++ = 0; } else { *ss++ = CANTCHANGE; *ss++ = tw->slc[parsedat[i]]; } skwrite(tw->pnum,s,3); #ifdef DEBUGOPTION if(debug&0x02) { if(tw->slc[parsedat[i]]==-1) { kbprintf(" %s NO_SUPPORT 0\r\n", LMoptions[parsedat[i]]); } else { kbprintf(" %s CANTCHANGE %d\r\n", LMoptions[parsedat[i]], tw->slc[parsedat[i]]); } } #endif } } /* IAC, SE */ skwrite(tw->pnum,"\377\360",2); } /* otherwise just exit */ break; default: break; } break; default: break; } tw->telstate = STNORM; break; default: tw->telstate = STNORM; break; } } break; default: tw->telstate = STNORM; break; } return('\0'); }