From da141f4c733c7ce1af4b15bf230a9bea439a2fb8 Mon Sep 17 00:00:00 2001 From: rswindell <> Date: Wed, 14 Sep 2011 03:09:44 +0000 Subject: [PATCH] Implement login attempt tracking/throttling/filtering in the terminal server. --- src/sbbs3/answer.cpp | 11 ++++++++--- src/sbbs3/login.cpp | 20 +++++++++++++++++++- src/sbbs3/main.cpp | 20 +++++++++++++------- src/sbbs3/sbbs.h | 20 ++++++++++++++------ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp index 5102f87967..2b0bd9ddee 100644 --- a/src/sbbs3/answer.cpp +++ b/src/sbbs3/answer.cpp @@ -47,13 +47,11 @@ bool sbbs_t::answer() char path[MAX_PATH+1]; int i,l,in; struct tm tm; - struct in_addr addr; useron.number=0; answertime=logontime=starttime=now=time(NULL); /* Caller ID is IP address */ - addr.s_addr=client_addr; - SAFECOPY(cid,inet_ntoa(addr)); + SAFECOPY(cid,inet_ntoa(client_addr.sin_addr)); memset(&tm,0,sizeof(tm)); localtime_r(&now,&tm); @@ -118,6 +116,7 @@ bool sbbs_t::answer() ,rlogin_pass); for(i=0;i<3;i++) { if(stricmp(tmp,useron.pass)) { + badlogin(useron.alias, tmp); rioctl(IOFI); /* flush input buffer */ bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) @@ -148,6 +147,7 @@ bool sbbs_t::answer() } if(i) { if(stricmp(tmp,useron.pass)) { + badlogin(useron.alias, tmp); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" @@ -200,6 +200,7 @@ bool sbbs_t::answer() ,rlogin_pass); for(i=0;i<3;i++) { if(stricmp(tmp,useron.pass)) { + badlogin(useron.alias, tmp); rioctl(IOFI); /* flush input buffer */ bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) @@ -236,6 +237,7 @@ bool sbbs_t::answer() } if(i) { if(stricmp(tmp,useron.pass)) { + badlogin(useron.alias, tmp); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) sprintf(str,"(%04u) %-25s FAILED Password attempt: '%s'" @@ -443,5 +445,8 @@ bool sbbs_t::answer() return(false); } + if(useron.pass[0]) + loginSuccess(startup->login_attempt_list, &client_addr); + return(true); } diff --git a/src/sbbs3/login.cpp b/src/sbbs3/login.cpp index 5e0acff77b..838268af84 100644 --- a/src/sbbs3/login.cpp +++ b/src/sbbs3/login.cpp @@ -116,6 +116,7 @@ int sbbs_t::login(char *username, char *pw) return(LOGIC_FALSE); } if(stricmp(useron.pass,str)) { + badlogin(useron.alias, str); bputs(text[InvalidLogon]); if(cfg.sys_misc&SM_ECHO_PW) sprintf(tmp,"(%04u) %-25s FAILED Password: '%s' Attempt: '%s'" @@ -132,8 +133,25 @@ int sbbs_t::login(char *username, char *pw) bputs(text[InvalidLogon]); useron.number=0; useron.misc=useron_misc; - return(LOGIC_FALSE); } + return(LOGIC_FALSE); + } } return(LOGIC_TRUE); } + +void sbbs_t::badlogin(char* user, char* passwd) +{ + char reason[128]; + ulong count; + + SAFEPRINTF(reason,"%s LOGIN", connection); + count=loginFailure(startup->login_attempt_list, &client_addr, connection, user, passwd); + if(startup->login_attempt_hack_threshold && count>=startup->login_attempt_hack_threshold) + hacklog(&cfg, reason, user, passwd, client_name, &client_addr); + if(startup->login_attempt_filter_threshold && count>=startup->login_attempt_filter_threshold) + filter_ip(&cfg, connection, "- TOO MANY CONSECUTIVE FAILED LOGIN ATTEMPTS" + ,client_name, inet_ntoa(client_addr.sin_addr), user, /* fname: */NULL); + + mswait(startup->login_attempt_delay); +} diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 2457fdab3e..fdfa73c488 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -2818,7 +2818,7 @@ void event_thread(void* arg) //**************************************************************************** -sbbs_t::sbbs_t(ushort node_num, DWORD addr, const char* name, SOCKET sd, +sbbs_t::sbbs_t(ushort node_num, SOCKADDR_IN addr, const char* name, SOCKET sd, scfg_t* global_cfg, char* global_text[], client_t* client_info) { char nodestr[32]; @@ -3442,14 +3442,12 @@ int sbbs_t::nopen(char *str, int access) void sbbs_t::spymsg(const char* msg) { char str[512]; - struct in_addr addr; if(cfg.node_num<1) return; - addr.s_addr=client_addr; SAFEPRINTF4(str,"\r\n\r\n*** Spy Message ***\r\nNode %d: %s [%s]\r\n*** %s ***\r\n\r\n" - ,cfg.node_num,client_name,inet_ntoa(addr),msg); + ,cfg.node_num,client_name,inet_ntoa(client_addr.sin_addr),msg); if(startup->node_spybuf!=NULL && startup->node_spybuf[cfg.node_num-1]!=NULL) { RingBufWrite(startup->node_spybuf[cfg.node_num-1],(uchar*)str,strlen(str)); @@ -3876,6 +3874,7 @@ void node_thread(void* arg) int file; uint curshell=0; node_t node; + ulong login_attempts; sbbs_t* sbbs = (sbbs_t*) arg; update_clients(); @@ -3895,6 +3894,13 @@ void node_thread(void* arg) } #endif + if(startup->login_attempt_throttle + && (login_attempts=loginAttempts(startup->login_attempt_list, &sbbs->client_addr)) > 1) { + lprintf(LOG_DEBUG,"Node %d Throttling suspicious connection from: %s (%u login attempts)" + ,sbbs->cfg.node_num, inet_ntoa(sbbs->client_addr.sin_addr), login_attempts); + mswait(login_attempts*startup->login_attempt_throttle); + } + if(sbbs->answer()) { if(sbbs->qwklogon) { @@ -4715,7 +4721,7 @@ void DLLCALL bbs_thread(void* arg) NO_SSH: #endif - sbbs = new sbbs_t(0, server_addr.sin_addr.s_addr + sbbs = new sbbs_t(0, server_addr ,"Terminal Server", telnet_socket, &scfg, text, NULL); sbbs->online = 0; if(sbbs->init()==false) { @@ -4726,7 +4732,7 @@ NO_SSH: _beginthread(output_thread, 0, sbbs); if(!(startup->options&BBS_OPT_NO_EVENTS)) { - events = new sbbs_t(0, server_addr.sin_addr.s_addr + events = new sbbs_t(0, server_addr ,"BBS Events", INVALID_SOCKET, &scfg, text, NULL); events->online = 0; if(events->init()==false) { @@ -5253,7 +5259,7 @@ NO_SSH: node_socket[i-1]=client_socket; - sbbs_t* new_node = new sbbs_t(i, client_addr.sin_addr.s_addr, host_name + sbbs_t* new_node = new sbbs_t(i, client_addr, host_name ,client_socket ,&scfg, text, &client); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 1b78f1b0a9..7a380ba56d 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -163,7 +163,7 @@ class sbbs_t public: - sbbs_t(ushort node_num, DWORD addr, const char* host_name, SOCKET + sbbs_t(ushort node_num, SOCKADDR_IN addr, const char* host_name, SOCKET ,scfg_t*, char* text[], client_t* client_info); ~sbbs_t(); @@ -175,7 +175,7 @@ public: client_t client; SOCKET client_socket; SOCKET client_socket_dup; - DWORD client_addr; + SOCKADDR_IN client_addr; char client_name[128]; char client_ident[128]; DWORD local_addr; @@ -584,15 +584,23 @@ public: int putnodedat(uint number, node_t * node); int putnodeext(uint number, char * str); - /* logonoff.cpp */ - bool answer(); + /* login.ccp */ int login(char *str, char *pw); + void badlogin(char* user, char* passwd); + + /* answer.cpp */ + bool answer(); + + /* logon.ccp */ bool logon(void); + + /* logout.cpp */ void logout(void); - void logoff(void); - BOOL newuser(void); /* Get new user */ void backout(void); + /* newuser.cpp */ + BOOL newuser(void); /* Get new user */ + /* text_sec.cpp */ int text_sec(void); /* Text sections */ -- GitLab