From 967a8ad90e47ea4d8f6a3e6ed8c185652f11da5c Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Fri, 23 Dec 2022 15:40:05 -0800 Subject: [PATCH] Publish hack-attempts, SPAM-attempts, and errors to MQTT <host>/error .../spam .../hack --- src/sbbs3/ftpsrvr.c | 4 ++-- src/sbbs3/js_system.c | 4 ++-- src/sbbs3/logfile.cpp | 35 +++++++++++++++++++++++++++++------ src/sbbs3/login.cpp | 2 +- src/sbbs3/mailsrvr.c | 28 ++++++++++++++-------------- src/sbbs3/main.cpp | 4 ++-- src/sbbs3/sbbs.h | 6 +++--- src/sbbs3/services.c | 4 ++-- src/sbbs3/websrvr.c | 6 +++--- 9 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c index bd5b67ccb9..f21067e1ef 100644 --- a/src/sbbs3/ftpsrvr.c +++ b/src/sbbs3/ftpsrvr.c @@ -143,7 +143,7 @@ static int lprintf(int level, const char *fmt, ...) if(level <= LOG_ERR) { char errmsg[sizeof(sbuf)+16]; SAFEPRINTF2(errmsg, "%s %s", server_abbrev, sbuf); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name, errmsg); + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name, errmsg); if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata,level,errmsg); } @@ -1723,7 +1723,7 @@ static BOOL ftp_hacklog(char* prot, char* user, char* text, char* host, union xp PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); #endif - return hacklog(&scfg, prot, user, text, host, addr); + return hacklog(&scfg, &startup->mqtt, prot, user, text, host, addr); } /****************************************************************************/ diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c index f6991013f4..7a61ccc7f9 100644 --- a/src/sbbs3/js_system.c +++ b/src/sbbs3/js_system.c @@ -1258,7 +1258,7 @@ js_spamlog(JSContext *cx, uintN argc, jsval *arglist) from=p; } rc=JS_SUSPENDREQUEST(cx); - ret=spamlog(sys->cfg,prot,action,reason,host,ip_addr,to,from); + ret=spamlog(sys->cfg,/* mqtt: */NULL,prot,action,reason,host,ip_addr,to,from); free(prot); free(action); free(reason); @@ -1325,7 +1325,7 @@ js_hacklog(JSContext *cx, uintN argc, jsval *arglist) } } rc=JS_SUSPENDREQUEST(cx); - ret=hacklog(sys->cfg,prot,user,text,host,&addr); + ret=hacklog(sys->cfg,/* MQTT: */NULL,prot,user,text,host,&addr); free(prot); free(user); free(text); diff --git a/src/sbbs3/logfile.cpp b/src/sbbs3/logfile.cpp index dd1b948ac6..8e1b209e65 100644 --- a/src/sbbs3/logfile.cpp +++ b/src/sbbs3/logfile.cpp @@ -25,7 +25,7 @@ const char* log_line_ending = "\r\n"; -extern "C" BOOL hacklog(scfg_t* cfg, const char* prot, const char* user, const char* text, const char* host, union xp_sockaddr* addr) +extern "C" BOOL hacklog(scfg_t* cfg, struct mqtt* mqtt, const char* prot, const char* user, const char* text, const char* host, union xp_sockaddr* addr) { char tstr[64]; char fname[MAX_PATH+1]; @@ -54,15 +54,23 @@ extern "C" BOOL hacklog(scfg_t* cfg, const char* prot, const char* user, const c fputs(log_line_ending, fp); fcloselog(fp); + if(mqtt != NULL) { + char str[1024]; + if(text == NULL) + text= ""; + snprintf(str, sizeof(str), "%s\t%s\t%u\t%s\t%s\t%s", prot, user, inet_addrport(addr), host, ip, text); + mqtt_pub_strval(mqtt, TOPIC_HOST, "hack", str); + } + return true; } BOOL sbbs_t::hacklog(const char* prot, const char* text) { - return ::hacklog(&cfg, prot, useron.alias, text, client_name, &client_addr); + return ::hacklog(&cfg, &startup->mqtt, prot, useron.alias, text, client_name, &client_addr); } -extern "C" BOOL spamlog(scfg_t* cfg, char* prot, char* action +extern "C" BOOL spamlog(scfg_t* cfg, struct mqtt* mqtt, char* prot, char* action ,char* reason, char* host, char* ip_addr ,char* to, char* from) { @@ -102,16 +110,27 @@ extern "C" BOOL spamlog(scfg_t* cfg, char* prot, char* action fputs(log_line_ending, fp); fcloselog(fp); + if(mqtt != NULL) { + char str[1024]; + if(reason == NULL) + reason= ""; + snprintf(str, sizeof(str), "%s\t%s\t%s\t%s\t%s\t%s\t%s", prot, action, host, ip_addr, from, to_user, reason); + mqtt_pub_strval(mqtt, TOPIC_HOST, "spam", str); + } + return true; } -extern "C" int errorlog(scfg_t* cfg, int level, const char* host, const char* text) +extern "C" int errorlog(scfg_t* cfg, struct mqtt* mqtt, int level, const char* host, const char* text) { FILE* fp; char buf[128]; char path[MAX_PATH+1]; time_t now = time(NULL); + if(host == NULL) + host = ""; + SAFEPRINTF(path, "%serror.log", cfg->logs_dir); if((fp = fopenlog(cfg, path))==NULL) return -1; @@ -119,7 +138,7 @@ extern "C" int errorlog(scfg_t* cfg, int level, const char* host, const char* te ,ctime_r(&now, buf) ,GIT_BRANCH ,GIT_HASH - ,host==NULL ? "":host + ,host ,log_line_ending ,text ,log_line_ending @@ -128,9 +147,13 @@ extern "C" int errorlog(scfg_t* cfg, int level, const char* host, const char* te fcloselog(fp); if(cfg->node_erruser && level <= cfg->node_errlevel) { char subject[128]; - SAFEPRINTF2(subject, "%s %sERROR occurred", host == NULL ? "" : host, level <= LOG_CRIT ? "CRITICAL " : ""); + SAFEPRINTF2(subject, "%s %sERROR occurred", host, level <= LOG_CRIT ? "CRITICAL " : ""); notify(cfg, cfg->node_erruser, subject, text); } + if(mqtt != NULL) { + mqtt_pub_strval(mqtt, TOPIC_HOST, "error", text); + } + return 0; } diff --git a/src/sbbs3/login.cpp b/src/sbbs3/login.cpp index 2e67e3e210..9d3c7d4777 100644 --- a/src/sbbs3/login.cpp +++ b/src/sbbs3/login.cpp @@ -157,7 +157,7 @@ void sbbs_t::badlogin(char* user, char* passwd, const char* protocol, xp_sockadd count=loginFailure(startup->login_attempt_list, addr, protocol, user, passwd); if(user!=NULL && startup->login_attempt.hack_threshold && count>=startup->login_attempt.hack_threshold) { getnameinfo(&addr->addr, addr_len, host_name, sizeof(host_name), NULL, 0, NI_NAMEREQD); - ::hacklog(&cfg, reason, user, passwd, host_name, addr); + ::hacklog(&cfg, &startup->mqtt, reason, user, passwd, host_name, addr); #ifdef _WIN32 if(startup->sound.hack[0] && !sound_muted(&cfg)) PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c index 6b731fad9f..5a14e8f3c8 100644 --- a/src/sbbs3/mailsrvr.c +++ b/src/sbbs3/mailsrvr.c @@ -192,7 +192,7 @@ static int lprintf(int level, const char *fmt, ...) if(level <= LOG_ERR) { char errmsg[sizeof(sbuf)+16]; SAFEPRINTF2(errmsg, "%s %s", server_abbrev, sbuf); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name,errmsg), stats.errors++; + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name,errmsg), stats.errors++; if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata,level,errmsg); } @@ -978,7 +978,7 @@ static void badlogin(SOCKET sock, CRYPT_SESSION sess, const char* prot, const ch SAFEPRINTF(reason,"%s LOGIN", prot); count=loginFailure(startup->login_attempt_list, addr, prot, user, passwd); if(startup->login_attempt.hack_threshold && count>=startup->login_attempt.hack_threshold) { - hacklog(&scfg, reason, user, passwd, host, addr); + hacklog(&scfg, &startup->mqtt, reason, user, passwd, host, addr); #ifdef _WIN32 if(startup->sound.hack[0] && !sound_muted(&scfg)) PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); @@ -1913,7 +1913,7 @@ static BOOL chk_email_addr(SOCKET socket, const char* prot, char* p, char* host_ lprintf(LOG_NOTICE,"%04d %s [%s] !BLOCKED %s e-mail address: %s" ,socket, prot, host_ip, source, addr); SAFEPRINTF2(tmp,"Blocked %s e-mail address: %s", source, addr); - spamlog(&scfg, (char*)prot, "REFUSED", tmp, host_name, host_ip, to, from); + spamlog(&scfg, &startup->mqtt, (char*)prot, "REFUSED", tmp, host_name, host_ip, to, from); return(FALSE); } @@ -3109,7 +3109,7 @@ static void smtp_thread(void* arg) ,socket, client.protocol, dnsbl_ip, dnsbl, host_name, inet_ntoa(dnsbl_result)); if(startup->options&MAIL_OPT_DNSBL_REFUSE) { SAFEPRINTF2(str,"Listed on %s as %s", dnsbl, inet_ntoa(dnsbl_result)); - spamlog(&scfg, (char*)client.protocol, "SESSION REFUSED", str, host_name, dnsbl_ip, NULL, NULL); + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "SESSION REFUSED", str, host_name, dnsbl_ip, NULL, NULL); sockprintf(socket,client.protocol,session ,"550 Mail from %s refused due to listing at %s" ,dnsbl_ip, dnsbl); @@ -3235,7 +3235,7 @@ static void smtp_thread(void* arg) lprintf(LOG_NOTICE,"%04d %s %s !FILTERING TWIT-LISTED SENDER: '%s' <%s> (%lu total)" ,socket, client.protocol, client_id, sender, sender_addr, ++stats.msgs_refused); SAFEPRINTF2(tmp,"Twit-listed sender: '%s' <%s>", sender, sender_addr); - spamlog(&scfg, (char*)client.protocol, "REFUSED", tmp, host_name, host_ip, rcpt_addr, reverse_path); + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED", tmp, host_name, host_ip, rcpt_addr, reverse_path); sockprintf(socket,client.protocol,session, "554 Sender not allowed."); continue; } @@ -3509,7 +3509,7 @@ static void smtp_thread(void* arg) ,socket, client.protocol, client_id, p, reverse_path, ++stats.msgs_refused); SAFEPRINTF2(tmp,"Blocked subject (%s) from: %s" ,p, reverse_path); - spamlog(&scfg, (char*)client.protocol, "REFUSED" + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED" ,tmp, host_name, host_ip, rcpt_addr, reverse_path); errmsg="554 Subject not allowed."; smb_error=SMB_FAILURE; @@ -3612,7 +3612,7 @@ static void smtp_thread(void* arg) } if(startup->dnsbl_hdr[0] || startup->dnsbl_tag[0]) { SAFEPRINTF2(str,"Listed on %s as %s", dnsbl, inet_ntoa(dnsbl_result)); - spamlog(&scfg, (char*)client.protocol, "TAGGED", str, host_name, dnsbl_ip, rcpt_addr, reverse_path); + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "TAGGED", str, host_name, dnsbl_ip, rcpt_addr, reverse_path); } } if(dnsbl_recvhdr) /* DNSBL-listed IP found in Received header? */ @@ -3801,7 +3801,7 @@ static void smtp_thread(void* arg) ); lprintf(LOG_NOTICE,"%04d %s %s Message from %s %s", socket, client.protocol, client_id, sender_info, str); if(!is_spam) { - spamlog(&scfg, (char*)client.protocol, "IGNORED" + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "IGNORED" ,str, host_name, host_ip, rcpt_addr, reverse_path); is_spam=TRUE; } @@ -3846,7 +3846,7 @@ static void smtp_thread(void* arg) SAFEPRINTF2(str,"Listed on %s as %s", dnsbl, inet_ntoa(dnsbl_result)); lprintf(LOG_NOTICE,"%04d %s %s !IGNORED MAIL from %s to <%s> from server: %s (%lu total)" ,socket, client.protocol, client_id, sender_info, rcpt_addr, str, ++stats.msgs_ignored); - spamlog(&scfg, (char*)client.protocol, "IGNORED" + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "IGNORED" ,str, host_name, dnsbl_ip, rcpt_addr, reverse_path); } /* pretend we received it */ @@ -4505,7 +4505,7 @@ static void smtp_thread(void* arg) lprintf(LOG_NOTICE,"%04d %s %s !MAXIMUM RECIPIENTS (%d) REACHED" ,socket, client.protocol, client_id, startup->max_recipients); SAFEPRINTF(tmp,"Maximum recipient count (%d)",startup->max_recipients); - spamlog(&scfg, (char*)client.protocol, "REFUSED", tmp + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED", tmp ,host_name, host_ip, rcpt_addr, reverse_path); sockprintf(socket,client.protocol,session, "452 Too many recipients"); stats.msgs_refused++; @@ -4527,7 +4527,7 @@ static void smtp_thread(void* arg) ,socket, client.protocol, client_id, scfg.level_emailperday[relay_user.level], relay_user.number, relay_user.alias); SAFEPRINTF2(tmp,"Maximum emails per day (%u) for %s" ,scfg.level_emailperday[relay_user.level], relay_user.alias); - spamlog(&scfg, (char*)client.protocol, "REFUSED", tmp + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED", tmp ,host_name, host_ip, rcpt_addr, reverse_path); sockprintf(socket,client.protocol,session, "452 Too many emails today"); stats.msgs_refused++; @@ -4548,7 +4548,7 @@ static void smtp_thread(void* arg) filter_ip(&scfg, client.protocol, reason, host_name, host_ip, reverse_path, spam_block); strcat(tmp," and BLOCKED"); } - spamlog(&scfg, (char*)client.protocol, tmp, "Attempted recipient in SPAM BAIT list" + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, tmp, "Attempted recipient in SPAM BAIT list" ,host_name, host_ip, rcpt_addr, reverse_path); dnsbl_result.s_addr=0; } @@ -4569,7 +4569,7 @@ static void smtp_thread(void* arg) lprintf(LOG_NOTICE,"%04d %s %s !REFUSED MAIL from blacklisted server (%lu total)" ,socket, client.protocol, client_id, ++stats.sessions_refused); SAFEPRINTF2(str,"Listed on %s as %s", dnsbl, inet_ntoa(dnsbl_result)); - spamlog(&scfg, (char*)client.protocol, "REFUSED", str, host_name, host_ip, rcpt_addr, reverse_path); + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED", str, host_name, host_ip, rcpt_addr, reverse_path); sockprintf(socket,client.protocol,session ,"550 Mail from %s refused due to listing at %s" ,host_ip, dnsbl); @@ -4663,7 +4663,7 @@ static void smtp_thread(void* arg) lprintf(LOG_WARNING,"%04d %s %s !ILLEGAL RELAY ATTEMPT from %s [%s] to %s" ,socket, client.protocol, client_id, reverse_path, host_ip, p); SAFEPRINTF(tmp,"Relay attempt to: %s", p); - spamlog(&scfg, (char*)client.protocol, "REFUSED", tmp, host_name, host_ip, rcpt_addr, reverse_path); + spamlog(&scfg, &startup->mqtt, (char*)client.protocol, "REFUSED", tmp, host_name, host_ip, rcpt_addr, reverse_path); if(startup->options&MAIL_OPT_ALLOW_RELAY) sockprintf(socket,client.protocol,session, "553 Relaying through this server " "requires authentication. " diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 618e2ee638..ae2e702537 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -206,7 +206,7 @@ int lputs(int level, const char* str) if(level <= LOG_ERR) { char errmsg[1024]; SAFEPRINTF2(errmsg, "%s %s", server_abbrev, str); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name, errmsg); + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name, errmsg); if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata,level,errmsg); } @@ -233,7 +233,7 @@ int eputs(int level, const char *str) if(level <= LOG_ERR) { char errmsg[1024]; SAFEPRINTF(errmsg, "evnt %s", str); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name, errmsg); + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name, errmsg); if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata, level, errmsg); } diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index f20155827c..554e11cafb 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -1246,11 +1246,11 @@ extern "C" { DLLEXPORT int notify(scfg_t*, uint usernumber, const char* subject, const char* msg); /* logfile.cpp */ - DLLEXPORT int errorlog(scfg_t* cfg, int level, const char* host, const char* text); + DLLEXPORT int errorlog(scfg_t* cfg, struct mqtt*, int level, const char* host, const char* text); - DLLEXPORT BOOL hacklog(scfg_t* cfg, const char* prot, const char* user, const char* text + DLLEXPORT BOOL hacklog(scfg_t* cfg, struct mqtt*, const char* prot, const char* user, const char* text ,const char* host, union xp_sockaddr* addr); - DLLEXPORT BOOL spamlog(scfg_t* cfg, char* prot, char* action, char* reason + DLLEXPORT BOOL spamlog(scfg_t* cfg, struct mqtt*, char* prot, char* action, char* reason ,char* host, char* ip_addr, char* to, char* from); /* data.cpp */ diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 401060acc9..f70d035001 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -126,7 +126,7 @@ static int lprintf(int level, const char *fmt, ...) if(level <= LOG_ERR) { char errmsg[sizeof(sbuf)+16]; SAFEPRINTF2(errmsg, "%s %s", server_abbrev, sbuf); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name, errmsg); + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name, errmsg); if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata,level,errmsg); } @@ -333,7 +333,7 @@ static void badlogin(SOCKET sock, char* prot, char* user, char* passwd, char* ho SAFEPRINTF(reason,"%s LOGIN", prot); count=loginFailure(startup->login_attempt_list, addr, prot, user, passwd); if(startup->login_attempt.hack_threshold && count>=startup->login_attempt.hack_threshold) { - hacklog(&scfg, reason, user, passwd, host, addr); + hacklog(&scfg, &startup->mqtt, reason, user, passwd, host, addr); #ifdef _WIN32 if(startup->sound.hack[0] && !sound_muted(&scfg)) PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index fe7b67d125..c4da8b876b 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -551,7 +551,7 @@ static int lprintf(int level, const char *fmt, ...) if(level <= LOG_ERR) { char errmsg[sizeof(sbuf)+16]; SAFEPRINTF2(errmsg, "%s %s", server_abbrev, sbuf); - errorlog(&scfg, level, startup==NULL ? NULL:startup->host_name, errmsg); + errorlog(&scfg, &startup->mqtt, level, startup==NULL ? NULL:startup->host_name, errmsg); if(startup!=NULL && startup->errormsg!=NULL) startup->errormsg(startup->cbdata,level,errmsg); } @@ -1863,7 +1863,7 @@ static void badlogin(SOCKET sock, const char* prot, const char* user, const char SAFEPRINTF(reason,"%s LOGIN", prot); count=loginFailure(startup->login_attempt_list, addr, prot, user, passwd); if(startup->login_attempt.hack_threshold && count>=startup->login_attempt.hack_threshold) { - hacklog(&scfg, reason, user, passwd, host, addr); + hacklog(&scfg, &startup->mqtt, reason, user, passwd, host, addr); #ifdef _WIN32 if(startup->sound.hack[0] && !sound_muted(&scfg)) PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); @@ -3680,7 +3680,7 @@ static BOOL check_request(http_session_t * session) send_error(session,__LINE__,"400 Bad Request"); SAFEPRINTF2(str, "Request for '%s' is outside of web root: %s", path, root_dir); lprintf(LOG_NOTICE,"%04d %s [%s] !ERROR %s", session->socket, session->client.protocol, session->host_ip, str); - hacklog(&scfg, session->client.protocol, session->username, str, session->client.host, &session->addr); + hacklog(&scfg, &startup->mqtt, session->client.protocol, session->username, str, session->client.host, &session->addr); #ifdef _WIN32 if(startup->sound.hack[0] && !sound_muted(&scfg)) PlaySound(startup->sound.hack, NULL, SND_ASYNC|SND_FILENAME); -- GitLab