|
|
1.1 ! root 1: /* answer.cpp */ ! 2: ! 3: /* Synchronet answer "caller" function */ ! 4: ! 5: /* $Id: answer.cpp,v 1.51 2006/12/29 19:32:36 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 2006 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: bool sbbs_t::answer() ! 42: { ! 43: char str[MAX_PATH+1],str2[MAX_PATH+1],c; ! 44: char tmp[MAX_PATH+1]; ! 45: char path[MAX_PATH+1]; ! 46: int i,l,in; ! 47: struct tm tm; ! 48: struct in_addr addr; ! 49: ! 50: useron.number=0; ! 51: answertime=logontime=starttime=now=time(NULL); ! 52: /* Caller ID is IP address */ ! 53: addr.s_addr=client_addr; ! 54: SAFECOPY(cid,inet_ntoa(addr)); ! 55: ! 56: memset(&tm,0,sizeof(tm)); ! 57: localtime_r(&now,&tm); ! 58: ! 59: sprintf(str,"%s %s %s %02d %u Node %3u" ! 60: ,hhmmtostr(&cfg,&tm,str2) ! 61: ,wday[tm.tm_wday] ! 62: ,mon[tm.tm_mon],tm.tm_mday,tm.tm_year+1900,cfg.node_num); ! 63: logline("@ ",str); ! 64: ! 65: sprintf(str,"%s %s [%s]", connection, client_name, cid); ! 66: logline("@+:",str); ! 67: ! 68: if(client_ident[0]) { ! 69: sprintf(str,"Identity: %s",client_ident); ! 70: logline("@*",str); ! 71: } ! 72: ! 73: online=ON_REMOTE; ! 74: ! 75: rlogin_name[0]=0; ! 76: if(sys_status&SS_RLOGIN) { ! 77: if(incom(1000)==0) { ! 78: for(i=0;i<(int)sizeof(str)-1;i++) { ! 79: in=incom(1000); ! 80: if(in==0 || in==NOINP) ! 81: break; ! 82: str[i]=in; ! 83: } ! 84: str[i]=0; ! 85: for(i=0;i<(int)sizeof(str2)-1;i++) { ! 86: in=incom(1000); ! 87: if(in==0 || in==NOINP) ! 88: break; ! 89: str2[i]=in; ! 90: } ! 91: str2[i]=0; ! 92: for(i=0;i<(int)sizeof(terminal)-1;i++) { ! 93: in=incom(1000); ! 94: if(in==0 || in==NOINP) ! 95: break; ! 96: terminal[i]=in; ! 97: } ! 98: terminal[i]=0; ! 99: truncstr(terminal,"/"); ! 100: lprintf(LOG_DEBUG,"Node %d RLogin: '%.*s' / '%.*s' / '%s'" ! 101: ,cfg.node_num ! 102: ,LEN_ALIAS*2,str ! 103: ,LEN_ALIAS*2,str2 ! 104: ,terminal); ! 105: SAFECOPY(rlogin_name ! 106: ,startup->options&BBS_OPT_USE_2ND_RLOGIN ? str2 : str); ! 107: SAFECOPY(rlogin_pass ! 108: ,startup->options&BBS_OPT_USE_2ND_RLOGIN ? str : str2); ! 109: useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name, 0); ! 110: if(useron.number) { ! 111: getuserdat(&cfg,&useron); ! 112: useron.misc&=~(ANSI|COLOR|RIP|WIP); ! 113: SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir); ! 114: if(!findstr(client.addr,path)) { ! 115: SAFECOPY(tmp ! 116: ,rlogin_pass); ! 117: for(i=0;i<3;i++) { ! 118: if(stricmp(tmp,useron.pass)) { ! 119: rioctl(IOFI); /* flush input buffer */ ! 120: bputs(text[InvalidLogon]); ! 121: if(cfg.sys_misc&SM_ECHO_PW) ! 122: sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" ! 123: ,0,useron.alias,tmp); ! 124: else ! 125: sprintf(str,"(%04u) %-25s FAILED Password attempt" ! 126: ,0,useron.alias); ! 127: logline("+!",str); ! 128: bputs(text[PasswordPrompt]); ! 129: console|=CON_R_ECHOX; ! 130: getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); ! 131: console&=~(CON_R_ECHOX|CON_L_ECHOX); ! 132: } ! 133: else { ! 134: if(REALSYSOP) { ! 135: rioctl(IOFI); /* flush input buffer */ ! 136: if(!chksyspass()) ! 137: bputs(text[InvalidLogon]); ! 138: else { ! 139: i=0; ! 140: break; ! 141: } ! 142: } ! 143: else ! 144: break; ! 145: } ! 146: } ! 147: if(i) { ! 148: if(stricmp(tmp,useron.pass)) { ! 149: bputs(text[InvalidLogon]); ! 150: if(cfg.sys_misc&SM_ECHO_PW) ! 151: sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" ! 152: ,0,useron.alias,tmp); ! 153: else ! 154: sprintf(str,"(%04u) %-25s FAILED Password attempt" ! 155: ,0,useron.alias); ! 156: logline("+!",str); ! 157: } ! 158: lprintf(LOG_WARNING,"%04d !CLIENT IP NOT LISTED in %s",client_socket,path); ! 159: useron.number=0; ! 160: hangup(); ! 161: } ! 162: } ! 163: } ! 164: else ! 165: lprintf(LOG_DEBUG,"Node %d RLogin: Unknown user: %s",cfg.node_num,rlogin_name); ! 166: } ! 167: if(rlogin_name[0]==0) { ! 168: lprintf(LOG_DEBUG,"Node %d !RLogin: No user name received",cfg.node_num); ! 169: sys_status&=~SS_RLOGIN; ! 170: } ! 171: } ! 172: ! 173: if(!(telnet_mode&TELNET_MODE_OFF)) { ! 174: /* Disable Telnet Terminal Echo */ ! 175: request_telnet_opt(TELNET_WILL,TELNET_ECHO); ! 176: /* Will suppress Go Ahead */ ! 177: request_telnet_opt(TELNET_WILL,TELNET_SUP_GA); ! 178: /* Retrieve terminal type from telnet client --RS */ ! 179: request_telnet_opt(TELNET_DO,TELNET_TERM_TYPE); ! 180: } ! 181: #ifdef USE_CRYPTLIB ! 182: if(sys_status&SS_SSH) { ! 183: cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_USERNAME, rlogin_name, &i); ! 184: rlogin_name[i]=0; ! 185: cryptGetAttributeString(ssh_session, CRYPT_SESSINFO_PASSWORD, rlogin_pass, &i); ! 186: rlogin_pass[i]=0; ! 187: lprintf(LOG_DEBUG,"Node %d SSH login: '%s'" ! 188: ,cfg.node_num, rlogin_name); ! 189: useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name, 0); ! 190: if(useron.number) { ! 191: getuserdat(&cfg,&useron); ! 192: useron.misc&=~(ANSI|COLOR|RIP|WIP); ! 193: SAFECOPY(tmp ! 194: ,rlogin_pass); ! 195: for(i=0;i<3;i++) { ! 196: if(stricmp(tmp,useron.pass)) { ! 197: rioctl(IOFI); /* flush input buffer */ ! 198: bputs(text[InvalidLogon]); ! 199: if(cfg.sys_misc&SM_ECHO_PW) ! 200: sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" ! 201: ,0,useron.alias,tmp); ! 202: else ! 203: sprintf(str,"(%04u) %-25s FAILED Password attempt" ! 204: ,0,useron.alias); ! 205: logline("+!",str); ! 206: bputs(text[PasswordPrompt]); ! 207: console|=CON_R_ECHOX; ! 208: getstr(tmp,LEN_PASS*2,K_UPPER|K_LOWPRIO|K_TAB); ! 209: console&=~(CON_R_ECHOX|CON_L_ECHOX); ! 210: } ! 211: else { ! 212: if(REALSYSOP) { ! 213: rioctl(IOFI); /* flush input buffer */ ! 214: if(!chksyspass()) ! 215: bputs(text[InvalidLogon]); ! 216: else { ! 217: i=0; ! 218: break; ! 219: } ! 220: } ! 221: else ! 222: break; ! 223: } ! 224: } ! 225: if(i) { ! 226: if(stricmp(tmp,useron.pass)) { ! 227: bputs(text[InvalidLogon]); ! 228: if(cfg.sys_misc&SM_ECHO_PW) ! 229: sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" ! 230: ,0,useron.alias,tmp); ! 231: else ! 232: sprintf(str,"(%04u) %-25s FAILED Password attempt" ! 233: ,0,useron.alias); ! 234: logline("+!",str); ! 235: } ! 236: useron.number=0; ! 237: hangup(); ! 238: } ! 239: } ! 240: else ! 241: lprintf(LOG_DEBUG,"Node %d SSH: Unknown user: %s",cfg.node_num,rlogin_name); ! 242: } ! 243: #endif ! 244: ! 245: /* Detect terminal type */ ! 246: mswait(200); ! 247: rioctl(IOFI); /* flush input buffer */ ! 248: putcom( "\r\n" /* locate cursor at column 1 */ ! 249: "\x1b[s" /* save cursor position (necessary for HyperTerm auto-ANSI) */ ! 250: "\x1b[99B_" /* locate cursor as far down as possible */ ! 251: "\x1b[6n" /* Get cursor position */ ! 252: "\x1b[u" /* restore cursor position */ ! 253: "\x1b[!_" /* RIP? */ ! 254: "\x1b[0t_" /* WIP? */ ! 255: "\2\2?HTML?"/* HTML? */ ! 256: "\x1b[0m_" /* "Normal" colors */ ! 257: "\x1b[2J" /* clear screen */ ! 258: "\x1b[H" /* home cursor */ ! 259: "\xC" /* clear screen (in case not ANSI) */ ! 260: "\r" /* Move cursor left (in case previous char printed) */ ! 261: ); ! 262: i=l=0; ! 263: tos=1; ! 264: lncntr=0; ! 265: strcpy(str,VERSION_NOTICE); ! 266: strcat(str," "); ! 267: strcat(str,COPYRIGHT_NOTICE); ! 268: strip_ctrl(str); ! 269: center(str); ! 270: ! 271: while(i++<50 && l<(int)sizeof(str)-1) { /* wait up to 5 seconds for response */ ! 272: c=incom(100)&0x7f; ! 273: if(c==0) ! 274: continue; ! 275: i=0; ! 276: if(l==0 && c!=ESC) // response must begin with escape char ! 277: continue; ! 278: str[l++]=c; ! 279: if(c=='R') { /* break immediately if ANSI response */ ! 280: mswait(500); ! 281: break; ! 282: } ! 283: } ! 284: ! 285: while((c=(incom(100)&0x7f))!=0 && l<(int)sizeof(str)-1) ! 286: str[l++]=c; ! 287: str[l]=0; ! 288: ! 289: if(l) { ! 290: if(str[0]==ESC && str[1]=='[') { ! 291: if(terminal[0]==0) ! 292: SAFECOPY(terminal,"ANSI"); ! 293: autoterm|=(ANSI|COLOR); ! 294: rows=atoi(str+2); ! 295: lprintf(LOG_DEBUG,"Node %d ANSI cursor position report: %u rows" ! 296: ,cfg.node_num, rows); ! 297: if(rows<10 || rows>99) rows=24; ! 298: } ! 299: truncsp(str); ! 300: if(strstr(str,"RIPSCRIP")) { ! 301: if(terminal[0]==0) ! 302: SAFECOPY(terminal,"RIP"); ! 303: logline("@R",strstr(str,"RIPSCRIP")); ! 304: autoterm|=(RIP|COLOR|ANSI); } ! 305: else if(strstr(str,"DC-TERM") ! 306: && toupper(*(strstr(str,"DC-TERM")+12))=='W') { ! 307: if(terminal[0]==0) ! 308: SAFECOPY(terminal,"WIP"); ! 309: logline("@W",strstr(str,"DC-TERM")); ! 310: autoterm|=(WIP|COLOR|ANSI); } ! 311: else if(strstr(str,"!HTML!")) { ! 312: if(terminal[0]==0) ! 313: SAFECOPY(terminal,"HTML"); ! 314: logline("@H",strstr(str,"!HTML!")); ! 315: autoterm|=HTML; ! 316: } ! 317: } ! 318: else if(terminal[0]==0) ! 319: SAFECOPY(terminal,"DUMB"); ! 320: ! 321: rioctl(IOFI); /* flush left-over or late response chars */ ! 322: ! 323: if(!autoterm && str[0]) { ! 324: lputs(LOG_DEBUG,"Terminal Auto-detect failed, Response: "); ! 325: str2[0]=0; ! 326: for(i=0;str[i];i++) { ! 327: if(str[i]>=' ' && str[i]<='~') ! 328: sprintf(tmp,"%c", str[i]); ! 329: else ! 330: sprintf(tmp,"<%02X>", (uchar)str[i]); ! 331: strcat(str2,tmp); ! 332: } ! 333: lputs(LOG_DEBUG,str2); ! 334: } ! 335: ! 336: /* AutoLogon via IP or Caller ID here */ ! 337: if(!useron.number && !(sys_status&SS_RLOGIN) ! 338: && startup->options&BBS_OPT_AUTO_LOGON && cid[0]) { ! 339: useron.number=userdatdupe(0, U_NOTE, LEN_NOTE, cid, 0); ! 340: if(useron.number) { ! 341: getuserdat(&cfg, &useron); ! 342: if(!(useron.misc&AUTOLOGON) || !(useron.exempt&FLAG('V'))) ! 343: useron.number=0; ! 344: } ! 345: } ! 346: ! 347: if(!online) ! 348: return(false); ! 349: ! 350: useron.misc&=~(ANSI|COLOR|RIP|WIP); ! 351: useron.misc|=autoterm; ! 352: SAFECOPY(useron.comp,client_name); ! 353: ! 354: if(!useron.number && sys_status&SS_RLOGIN) { ! 355: CRLF; ! 356: newuser(); ! 357: } ! 358: ! 359: if(!useron.number) { /* manual/regular logon */ ! 360: ! 361: /* Display ANSWER screen */ ! 362: sprintf(str,"%sanswer",cfg.text_dir); ! 363: sprintf(tmp,"%s.%s",str,autoterm&WIP ? "wip":"rip"); ! 364: sprintf(path,"%s.html",str); ! 365: sprintf(str2,"%s.ans",str); ! 366: if(autoterm&(RIP|WIP) && fexist(tmp)) ! 367: strcat(str,autoterm&WIP ? ".wip":".rip"); ! 368: else if(autoterm&HTML && fexist(path)) ! 369: strcat(str,".html"); ! 370: else if(autoterm&ANSI && fexist(str2)) ! 371: strcat(str,".ans"); ! 372: else ! 373: strcat(str,".asc"); ! 374: rioctl(IOSM|PAUSE); ! 375: sys_status|=SS_PAUSEON; ! 376: printfile(str,P_NOABORT); ! 377: sys_status&=~SS_PAUSEON; ! 378: exec_bin(cfg.login_mod,&main_csi); ! 379: } else /* auto logon here */ ! 380: if(logon()==false) ! 381: return(false); ! 382: ! 383: ! 384: if(!useron.number) ! 385: hangup(); ! 386: if(!online) ! 387: return(false); ! 388: ! 389: /* Save the IP to the user's note */ ! 390: if(cid[0]) { ! 391: SAFECOPY(useron.note,cid); ! 392: putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note); ! 393: } ! 394: ! 395: /* Save host name to the user's computer description */ ! 396: if(client_name[0]) { ! 397: SAFECOPY(useron.comp,client_name); ! 398: putuserrec(&cfg,useron.number,U_COMP,LEN_COMP,useron.comp); ! 399: } ! 400: ! 401: if(!(sys_status&SS_USERON)) { ! 402: errormsg(WHERE,ERR_CHK,"User not logged on",0); ! 403: hangup(); ! 404: return(false); } ! 405: ! 406: return(true); ! 407: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.