|
|
1.1 ! root 1: /* telgate.cpp */ ! 2: ! 3: /* Synchronet telnet gateway routines */ ! 4: ! 5: /* $Id: telgate.cpp,v 1.28 2005/10/13 06:49:14 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "telnet.h" ! 40: ! 41: void sbbs_t::telnet_gate(char* destaddr, ulong mode) ! 42: { ! 43: char* p; ! 44: uchar buf[512]; ! 45: int i; ! 46: int rd; ! 47: uint attempts; ! 48: ulong l; ! 49: bool gotline; ! 50: ushort port; ! 51: ulong ip_addr; ! 52: ulong save_console; ! 53: SOCKET remote_socket; ! 54: SOCKADDR_IN addr; ! 55: ! 56: if(mode&TG_RLOGIN) ! 57: port=513; ! 58: else ! 59: port=IPPORT_TELNET; ! 60: ! 61: p=strchr(destaddr,':'); ! 62: if(p!=NULL) { ! 63: *p=0; ! 64: port=atoi(p+1); ! 65: } ! 66: ! 67: ip_addr=resolve_ip(destaddr); ! 68: if(ip_addr==INADDR_NONE) { ! 69: lprintf(LOG_NOTICE,"!TELGATE Failed to resolve address: %s",destaddr); ! 70: bprintf("!Failed to resolve address: %s\r\n",destaddr); ! 71: return; ! 72: } ! 73: ! 74: if((remote_socket = open_socket(SOCK_STREAM, client.protocol)) == INVALID_SOCKET) { ! 75: errormsg(WHERE,ERR_OPEN,"socket",0); ! 76: return; ! 77: } ! 78: ! 79: memset(&addr,0,sizeof(addr)); ! 80: addr.sin_addr.s_addr = htonl(startup->telnet_interface); ! 81: addr.sin_family = AF_INET; ! 82: ! 83: if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) { ! 84: lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, remote_socket); ! 85: bprintf("!ERROR %d (%d) binding to socket\r\n",i, ERROR_VALUE); ! 86: close_socket(remote_socket); ! 87: return; ! 88: } ! 89: ! 90: memset(&addr,0,sizeof(addr)); ! 91: addr.sin_addr.s_addr = ip_addr; ! 92: addr.sin_family = AF_INET; ! 93: addr.sin_port = htons(port); ! 94: ! 95: if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) { ! 96: lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) connecting to server: %s" ! 97: ,i,ERROR_VALUE, destaddr); ! 98: bprintf("!ERROR %d (%d) connecting to server: %s\r\n" ! 99: ,i,ERROR_VALUE, destaddr); ! 100: close_socket(remote_socket); ! 101: return; ! 102: } ! 103: ! 104: l=1; ! 105: ! 106: if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) { ! 107: lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) disabling socket blocking" ! 108: ,i, ERROR_VALUE); ! 109: close_socket(remote_socket); ! 110: return; ! 111: } ! 112: ! 113: lprintf(LOG_INFO,"Node %d %s gate to %s port %d on socket %d" ! 114: ,cfg.node_num ! 115: ,mode&TG_RLOGIN ? "RLogin" : "Telnet" ! 116: ,destaddr,port,remote_socket); ! 117: ! 118: if(mode&(TG_PASSTHRU|TG_RLOGIN)) ! 119: telnet_mode|=TELNET_MODE_GATE; // Pass-through telnet commands ! 120: ! 121: if(!(mode&TG_CTRLKEYS)) ! 122: console|=CON_RAW_IN; ! 123: ! 124: if(mode&TG_RLOGIN) { ! 125: p=(char*)buf; ! 126: *(p++)=0; ! 127: p+=sprintf(p,"%s",useron.alias); ! 128: p++; // Add NULL ! 129: p+=sprintf(p,"%s",useron.name); ! 130: p++; // Add NULL ! 131: p+=sprintf(p,"%s/57600",terminal); ! 132: p++; // Add NULL ! 133: l=p-(char*)buf; ! 134: sendsocket(remote_socket,(char*)buf,l); ! 135: } ! 136: ! 137: /* This is required for gating to Unix telnetd */ ! 138: if(mode&TG_NOTERMTYPE) ! 139: request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE); // Re-negotiation of terminal type ! 140: ! 141: /* Text/NVT mode by default */ ! 142: request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX); ! 143: ! 144: while(online) { ! 145: if(!(mode&TG_NOCHKTIME)) ! 146: gettimeleft(); ! 147: rd=RingBufRead(&inbuf,buf,sizeof(buf)); ! 148: if(rd) { ! 149: #if 0 ! 150: if(memchr(buf,TELNET_IAC,rd)) { ! 151: char dump[2048]; ! 152: dump[0]; ! 153: p=dump; ! 154: for(int i=0;i<rd;i++) ! 155: p+=sprintf(p,"%u ",buf[i]); ! 156: lprintf(LOG_DEBUG,"Node %d Telnet cmd from client: %s", cfg.node_num, dump); ! 157: } ! 158: #endif ! 159: if(telnet_remote_option[TELNET_BINARY_TX]!=TELNET_WILL) { ! 160: if(*buf==0x1d) { // ^] ! 161: save_console=console; ! 162: console&=~CON_RAW_IN; // Allow Ctrl-U/Ctrl-P ! 163: CRLF; ! 164: while(online) { ! 165: SYNC; ! 166: mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, " ! 167: "\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, " ! 168: "\1y~Q\1wuit: "); ! 169: switch(getkeys("DELPQ",0)) { ! 170: case 'D': ! 171: closesocket(remote_socket); ! 172: break; ! 173: case 'E': ! 174: mode^=TG_ECHO; ! 175: bprintf(text[EchoIsNow] ! 176: ,mode&TG_ECHO ! 177: ? text[ON]:text[OFF]); ! 178: continue; ! 179: case 'L': ! 180: whos_online(true); ! 181: continue; ! 182: case 'P': ! 183: nodemsg(); ! 184: continue; ! 185: } ! 186: break; ! 187: } ! 188: attr(LIGHTGRAY); ! 189: console=save_console; ! 190: } ! 191: else if(*buf<' ' && mode&TG_CTRLKEYS) ! 192: handle_ctrlkey(*buf, K_NONE); ! 193: gotline=false; ! 194: if(mode&TG_LINEMODE && buf[0]!='\r') { ! 195: ungetkey(buf[0]); ! 196: l=K_CHAT; ! 197: if(!(mode&TG_ECHO)) ! 198: l|=K_NOECHO; ! 199: rd=getstr((char*)buf,sizeof(buf)-1,l); ! 200: if(!rd) ! 201: continue; ! 202: strcat((char*)buf,crlf); ! 203: rd+=2; ! 204: gotline=true; ! 205: } ! 206: if(mode&TG_CRLF && buf[rd-1]=='\r') ! 207: buf[rd++]='\n'; ! 208: if(!gotline && mode&TG_ECHO) { ! 209: RingBufWrite(&outbuf,buf,rd); ! 210: } ! 211: } ! 212: for(attempts=0;attempts<60 && online; attempts++) /* added retry loop here, Jan-20-2003 */ ! 213: { ! 214: if((i=sendsocket(remote_socket,(char*)buf,rd))>=0) ! 215: break; ! 216: if(ERROR_VALUE!=EWOULDBLOCK) ! 217: break; ! 218: mswait(500); ! 219: } ! 220: if(i<0) { ! 221: lprintf(LOG_NOTICE,"!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket); ! 222: break; ! 223: } ! 224: } ! 225: rd=recv(remote_socket,(char*)buf,sizeof(buf),0); ! 226: if(rd<0) { ! 227: if(ERROR_VALUE==EWOULDBLOCK) { ! 228: if(mode&TG_NODESYNC) { ! 229: SYNC; ! 230: } else { ! 231: // Check if the node has been interrupted ! 232: getnodedat(cfg.node_num,&thisnode,0); ! 233: if(thisnode.misc&NODE_INTR) ! 234: break; ! 235: } ! 236: YIELD(); ! 237: continue; ! 238: } ! 239: lprintf(LOG_NOTICE,"!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket); ! 240: break; ! 241: } ! 242: if(!rd) { ! 243: lprintf(LOG_INFO,"Node %d Telnet gate disconnected",cfg.node_num); ! 244: break; ! 245: } ! 246: #if 0 ! 247: if(memchr(buf,TELNET_IAC,rd)) { ! 248: char dump[2048]; ! 249: dump[0]; ! 250: p=dump; ! 251: for(int i=0;i<rd;i++) ! 252: p+=sprintf(p,"%u ",buf[i]); ! 253: lprintf(LOG_DEBUG,"Node %d Telnet cmd from remote: %s", cfg.node_num, dump); ! 254: } ! 255: #endif ! 256: RingBufWrite(&outbuf,buf,rd); ! 257: } ! 258: console&=~CON_RAW_IN; ! 259: telnet_mode&=~TELNET_MODE_GATE; ! 260: ! 261: /* Disable Telnet Terminal Echo */ ! 262: request_telnet_opt(TELNET_WILL,TELNET_ECHO); ! 263: ! 264: close_socket(remote_socket); ! 265: ! 266: lprintf(LOG_INFO,"Node %d Telnet gate to %s finished",cfg.node_num,destaddr); ! 267: } ! 268:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.