|
|
1.1 root 1: /* answer.cpp */
2:
3: /* Synchronet answer "caller" function */
4:
1.1.1.2 ! root 5: /* $Id: answer.cpp,v 1.44 2004/12/07 08:53:32 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: {
1.1.1.2 ! root 43: char str[MAX_PATH+1],str2[MAX_PATH+1],c;
! 44: char tmp[MAX_PATH+1];
! 45: char path[MAX_PATH+1];
1.1 root 46: int i,l,in;
1.1.1.2 ! root 47: struct tm tm;
1.1 root 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;
1.1.1.2 ! root 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);
1.1 root 63: logline("@ ",str);
64:
65: sprintf(str,"%s %s [%s]", connection, client_name, cid);
66: logline("@+:",str);
67:
1.1.1.2 ! root 68: if(client_ident[0]) {
! 69: sprintf(str,"Identity: %s",client_ident);
! 70: logline("@*",str);
! 71: }
! 72:
1.1 root 73: online=ON_REMOTE;
74:
75: rlogin_name[0]=0;
76: if(sys_status&SS_RLOGIN) {
1.1.1.2 ! root 77: if(incom(1000)==0) {
! 78: for(i=0;i<(int)sizeof(str)-1;i++) {
! 79: in=incom(1000);
1.1 root 80: if(in==0 || in==NOINP)
81: break;
82: str[i]=in;
83: }
84: str[i]=0;
1.1.1.2 ! root 85: for(i=0;i<(int)sizeof(str2)-1;i++) {
! 86: in=incom(1000);
1.1 root 87: if(in==0 || in==NOINP)
88: break;
89: str2[i]=in;
90: }
91: str2[i]=0;
1.1.1.2 ! root 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);
1.1 root 107: useron.number=userdatdupe(0, U_ALIAS, LEN_ALIAS, rlogin_name, 0);
1.1.1.2 ! root 108: if(useron.number) {
1.1 root 109: getuserdat(&cfg,&useron);
1.1.1.2 ! root 110: useron.misc&=~(ANSI|COLOR|RIP|WIP);
! 111: SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir);
! 112: if(!findstr(client.addr,path)) {
! 113: SAFECOPY(tmp
! 114: ,startup->options&BBS_OPT_USE_2ND_RLOGIN ? str : str2);
! 115: for(i=0;i<3;i++) {
! 116: if(stricmp(tmp,useron.pass)) {
! 117: rioctl(IOFI); /* flush input buffer */
! 118: bputs(text[InvalidLogon]);
! 119: if(cfg.sys_misc&SM_ECHO_PW)
! 120: sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'"
! 121: ,0,useron.alias,tmp);
! 122: else
! 123: sprintf(str,"(%04u) %-25s FAILED Password attempt"
! 124: ,0,useron.alias);
! 125: logline("+!",str);
! 126: bputs(text[PasswordPrompt]);
! 127: console|=CON_R_ECHOX;
! 128: if(!(cfg.sys_misc&SM_ECHO_PW))
! 129: console|=CON_L_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);
1.1 root 166: }
1.1.1.2 ! root 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);
1.1 root 180: }
181:
182: /* Detect terminal type */
183: mswait(200);
184: rioctl(IOFI); /* flush input buffer */
185: putcom( "\r\n" /* locate cursor at column 1 */
1.1.1.2 ! root 186: "\x1b[s" /* save cursor position (necessary for HyperTerm auto-ANSI) */
! 187: "\x1b[99B_" /* locate cursor as far down as possible */
1.1 root 188: "\x1b[6n" /* Get cursor position */
1.1.1.2 ! root 189: "\x1b[u" /* restore cursor position */
1.1 root 190: "\x1b[!_" /* RIP? */
191: "\x1b[0t_" /* WIP? */
1.1.1.2 ! root 192: "\2\2?HTML?"/* HTML? */
1.1 root 193: "\x1b[0m_" /* "Normal" colors */
194: "\x1b[2J" /* clear screen */
195: "\x1b[H" /* home cursor */
196: "\xC" /* clear screen (in case not ANSI) */
197: "\r" /* Move cursor left (in case previous char printed) */
198: );
199: i=l=0;
200: tos=1;
1.1.1.2 ! root 201: lncntr=0;
1.1 root 202: strcpy(str,VERSION_NOTICE);
1.1.1.2 ! root 203: strcat(str," ");
1.1 root 204: strcat(str,COPYRIGHT_NOTICE);
1.1.1.2 ! root 205: strip_ctrl(str);
1.1 root 206: center(str);
1.1.1.2 ! root 207:
! 208: while(i++<50 && l<(int)sizeof(str)-1) { /* wait up to 5 seconds for response */
! 209: c=incom(100)&0x7f;
! 210: if(c==0)
1.1 root 211: continue;
212: i=0;
213: if(l==0 && c!=ESC) // response must begin with escape char
214: continue;
215: str[l++]=c;
1.1.1.2 ! root 216: if(c=='R') { /* break immediately if ANSI response */
! 217: mswait(500);
1.1 root 218: break;
219: }
220: }
221:
1.1.1.2 ! root 222: while((c=(incom(100)&0x7f))!=0 && l<(int)sizeof(str)-1)
1.1 root 223: str[l++]=c;
224: str[l]=0;
225:
226: if(l) {
227: if(str[0]==ESC && str[1]=='[') {
1.1.1.2 ! root 228: if(terminal[0]==0)
! 229: SAFECOPY(terminal,"ANSI");
1.1 root 230: autoterm|=(ANSI|COLOR);
1.1.1.2 ! root 231: rows=atoi(str+2);
! 232: lprintf(LOG_DEBUG,"Node %d ANSI cursor position report: %u rows"
! 233: ,cfg.node_num, rows);
! 234: if(rows<10 || rows>99) rows=24;
! 235: }
1.1 root 236: truncsp(str);
237: if(strstr(str,"RIPSCRIP")) {
1.1.1.2 ! root 238: if(terminal[0]==0)
! 239: SAFECOPY(terminal,"RIP");
1.1 root 240: logline("@R",strstr(str,"RIPSCRIP"));
241: autoterm|=(RIP|COLOR|ANSI); }
242: else if(strstr(str,"DC-TERM")
243: && toupper(*(strstr(str,"DC-TERM")+12))=='W') {
1.1.1.2 ! root 244: if(terminal[0]==0)
! 245: SAFECOPY(terminal,"WIP");
1.1 root 246: logline("@W",strstr(str,"DC-TERM"));
1.1.1.2 ! root 247: autoterm|=(WIP|COLOR|ANSI); }
! 248: else if(strstr(str,"!HTML!")) {
! 249: if(terminal[0]==0)
! 250: SAFECOPY(terminal,"HTML");
! 251: logline("@H",strstr(str,"!HTML!"));
! 252: autoterm|=HTML;
! 253: }
! 254: }
! 255: else if(terminal[0]==0)
! 256: SAFECOPY(terminal,"DUMB");
! 257:
1.1 root 258: rioctl(IOFI); /* flush left-over or late response chars */
259:
260: if(!autoterm && str[0]) {
1.1.1.2 ! root 261: lputs(LOG_DEBUG,"Terminal Auto-detect failed, Response: ");
1.1 root 262: str2[0]=0;
263: for(i=0;str[i];i++) {
264: if(str[i]>=' ' && str[i]<='~')
265: sprintf(tmp,"%c", str[i]);
266: else
267: sprintf(tmp,"<%02X>", (uchar)str[i]);
268: strcat(str2,tmp);
269: }
1.1.1.2 ! root 270: lputs(LOG_DEBUG,str2);
1.1 root 271: }
272:
273: /* AutoLogon via IP or Caller ID here */
274: if(!useron.number && !(sys_status&SS_RLOGIN)
1.1.1.2 ! root 275: && startup->options&BBS_OPT_AUTO_LOGON && cid[0]) {
1.1 root 276: useron.number=userdatdupe(0, U_NOTE, LEN_NOTE, cid, 0);
277: if(useron.number) {
278: getuserdat(&cfg, &useron);
279: if(!(useron.misc&AUTOLOGON) || !(useron.exempt&FLAG('V')))
280: useron.number=0;
281: }
282: }
283:
284: if(!online)
285: return(false);
286:
287: useron.misc&=~(ANSI|COLOR|RIP|WIP);
288: useron.misc|=autoterm;
1.1.1.2 ! root 289: SAFECOPY(useron.comp,client_name);
1.1 root 290:
291: if(!useron.number && sys_status&SS_RLOGIN) {
292: CRLF;
293: newuser();
294: }
295:
296: if(!useron.number) { /* manual/regular logon */
297:
298: /* Display ANSWER screen */
299: sprintf(str,"%sanswer",cfg.text_dir);
300: sprintf(tmp,"%s.%s",str,autoterm&WIP ? "wip":"rip");
1.1.1.2 ! root 301: sprintf(path,"%s.html",str);
1.1 root 302: sprintf(str2,"%s.ans",str);
303: if(autoterm&(RIP|WIP) && fexist(tmp))
304: strcat(str,autoterm&WIP ? ".wip":".rip");
1.1.1.2 ! root 305: else if(autoterm&HTML && fexist(path))
! 306: strcat(str,".html");
1.1 root 307: else if(autoterm&ANSI && fexist(str2))
308: strcat(str,".ans");
309: else
310: strcat(str,".asc");
311: rioctl(IOSM|PAUSE);
312: sys_status|=SS_PAUSEON;
313: printfile(str,P_NOABORT);
314: sys_status&=~SS_PAUSEON;
315: exec_bin(cfg.login_mod,&main_csi);
316: } else /* auto logon here */
317: if(logon()==false)
318: return(false);
319:
320:
321: if(!useron.number)
322: hangup();
323: if(!online)
324: return(false);
325:
326: /* Save the IP to the user's note */
327: if(cid[0]) {
1.1.1.2 ! root 328: SAFECOPY(useron.note,cid);
1.1 root 329: putuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
330: }
331:
332: /* Save host name to the user's computer description */
333: if(client_name[0]) {
1.1.1.2 ! root 334: SAFECOPY(useron.comp,client_name);
1.1 root 335: putuserrec(&cfg,useron.number,U_COMP,LEN_COMP,useron.comp);
336: }
337:
338: if(!(sys_status&SS_USERON)) {
339: errormsg(WHERE,ERR_CHK,"User not logged on",0);
340: hangup();
341: return(false); }
342:
343: return(true);
344: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.