From b4cf201d6f4ee91eea9adf7b6f73f095a40d167a Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows 11)" <rob@synchro.net>
Date: Thu, 5 Dec 2024 21:37:52 -0800
Subject: [PATCH] Verify QWK messagse files (e.g. MESSAGES.DAT) is multiple of
 QWK block size

(128 bytes)

Fix up the filename in error messages reported during unpacking QWK packets
(MESSAGES.DAT not BBSID.QWK).
---
 src/sbbs3/un_qwk.cpp | 31 +++++++++++++++++++++----------
 src/sbbs3/un_rep.cpp |  5 +++++
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/sbbs3/un_qwk.cpp b/src/sbbs3/un_qwk.cpp
index 45c2169a45..3534b7b0f7 100644
--- a/src/sbbs3/un_qwk.cpp
+++ b/src/sbbs3/un_qwk.cpp
@@ -39,6 +39,7 @@ static void log_qwk_import_stats(sbbs_t* sbbs, ulong msgs, time_t start)
 bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 {
 	char	str[MAX_PATH+1],fname[MAX_PATH+1];
+	char	msg_fname[MAX_PATH + 1];
 	char 	tmp[512];
 	char	error[256] = "";
 	char	inbox[MAX_PATH+1];
@@ -94,13 +95,18 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 			return(false);
 		}
 	}
-	SAFEPRINTF(str,"%sMESSAGES.DAT",cfg.temp_dir);
-	if(!fexistcase(str)) {
-		lprintf(LOG_WARNING,"%s doesn't contain MESSAGES.DAT (%s)",packet,str);
+	SAFEPRINTF(msg_fname,"%sMESSAGES.DAT",cfg.temp_dir);
+	if(!fexistcase(msg_fname)) {
+		lprintf(LOG_WARNING,"%s doesn't contain MESSAGES.DAT (%s)",packet,msg_fname);
 		return(false);
 	}
-	if((qwk=fnopen(&file,str,O_RDONLY))==NULL) {
-		errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
+	size = (long)flength(msg_fname);
+	if(size < QWK_BLOCK_LEN || (size % QWK_BLOCK_LEN) != 0) {
+		errormsg(WHERE, ERR_LEN, msg_fname, size);
+		return false;
+	}
+	if((qwk=fnopen(&file,msg_fname,O_RDONLY))==NULL) {
+		errormsg(WHERE,ERR_OPEN,msg_fname,O_RDONLY);
 		return(false);
 	}
 	size=(long)filelength(file);
@@ -146,16 +152,21 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 			lprintf(LOG_NOTICE,"!Terminated");
 			break;
 		}
-		fseek(qwk,l,SEEK_SET);
+		if(fseek(qwk,l,SEEK_SET) != 0) {
+			errormsg(WHERE, ERR_SEEK, msg_fname, l);
+			blocks=1;
+			errors++;
+			continue;
+		}
 		if(fread(block,QWK_BLOCK_LEN,1,qwk) != 1) {
-			errormsg(WHERE, ERR_READ, packet, QWK_BLOCK_LEN);
+			errormsg(WHERE, ERR_READ, msg_fname, QWK_BLOCK_LEN);
 			blocks=1;
 			errors++;
 			continue;
 		}
 		if(block[0]<' ' || block[0]&0x80) {
 			lprintf(LOG_NOTICE,"!Invalid QWK message status (%02X) at offset %lu in %s"
-				,block[0], l, packet);
+				,block[0], l, msg_fname);
 			blocks=1;
 			errors++;
 			continue;
@@ -166,13 +177,13 @@ bool sbbs_t::unpack_qwk(char *packet,uint hubnum)
 		if(blocks<2) {
 			if(block[0] == 'V' && blocks == 1 && voting != NULL) {	/* VOTING DATA */
 				if(!qwk_voting(&voting, l, NET_QWK, cfg.qhub[hubnum]->id, n, msg_filters, hubnum)) {
-					lprintf(LOG_WARNING, "QWK vote failure, offset %lu in %s", l, packet);
+					lprintf(LOG_WARNING, "QWK vote failure, offset %lu in %s", l, msg_fname);
 					errors++;
 				}
 				continue;
 			}
 			lprintf(LOG_NOTICE,"!Invalid number of QWK blocks (%d) at offset %lu in %s"
-				,blocks, l+116, packet);
+				,blocks, l+116, msg_fname);
 			errors++;
 			blocks=1;
 			continue;
diff --git a/src/sbbs3/un_rep.cpp b/src/sbbs3/un_rep.cpp
index 1c1a416047..a48aebed57 100644
--- a/src/sbbs3/un_rep.cpp
+++ b/src/sbbs3/un_rep.cpp
@@ -110,6 +110,11 @@ bool sbbs_t::unpack_rep(char* repfile)
 		logline(LOG_NOTICE,nulstr,"MSG file not received");
 		return(false);
 	}
+	size = (long)flength(msg_fname);
+	if(size < QWK_BLOCK_LEN || (size % QWK_BLOCK_LEN) != 0) {
+		errormsg(WHERE, ERR_LEN, msg_fname, size);
+		return false;
+	}
 	if((rep=fnopen(&file,msg_fname,O_RDONLY))==NULL) {
 		errormsg(WHERE,ERR_OPEN,msg_fname,O_RDONLY);
 		return(false);
-- 
GitLab