diff --git a/AGWAPI.c b/AGWAPI.c index e84a1d1..0f2d86c 100644 --- a/AGWAPI.c +++ b/AGWAPI.c @@ -36,14 +36,14 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses struct AGWHeader { - int Port; + unsigned int Port; unsigned char DataKind; unsigned char filler2; unsigned char PID; unsigned char filler3; unsigned char callfrom[10]; unsigned char callto[10]; - int DataLength; + unsigned int DataLength; int reserved; }; @@ -1063,6 +1063,8 @@ int AGWDataSocket_Read(struct AGWSocketConnectionInfo * sockptr, SOCKET sock) { if (DataLength > 35)// A header { + struct AGWHeader * AGW = &sockptr->AGWRXHeader; + i=recv(sock,(char *)&sockptr->AGWRXHeader, 36, 0); if (i == SOCKET_ERROR) @@ -1075,6 +1077,16 @@ int AGWDataSocket_Read(struct AGWSocketConnectionInfo * sockptr, SOCKET sock) sockptr->MsgDataLength = sockptr->AGWRXHeader.DataLength; + // Validate packet to protect against accidental (or malicious!) connects from a non-agw application + + + if (AGW->Port > 64 || AGW->filler2 != 0 || AGW->filler3 != 0 || AGW->DataLength > 400) + { + Debugprintf("Corrupt AGW Packet Received"); + AGWDataSocket_Disconnect(sockptr); + return 0; + } + if (sockptr->MsgDataLength > 500) OutputDebugString("Corrupt AGW message"); diff --git a/BBSHTMLConfig.c b/BBSHTMLConfig.c index d1a62ce..3234c00 100644 --- a/BBSHTMLConfig.c +++ b/BBSHTMLConfig.c @@ -405,41 +405,20 @@ int SendHeader(char * Reply, char * Key) void ConvertTitletoUTF8(WebMailInfo * WebMail, char * Title, char * UTF8Title, int Len) { - if (WebIsUTF8(Title, (int)strlen(Title)) == FALSE) - { - // With Windows it is simple - convert using current codepage - // I think the only reliable way is to convert to unicode and back - - int origlen = (int)strlen(Title) + 1; -#ifdef WIN32 - WCHAR BufferW[128]; - int wlen; - int len = origlen; - - wlen = MultiByteToWideChar(CP_ACP, 0, Title, len, BufferW, origlen * 2); - len = WideCharToMultiByte(CP_UTF8, 0, BufferW, wlen, UTF8Title, origlen * 2, NULL, NULL); -#else - size_t left = Len - 1; - size_t len = origlen; - - iconv_t * icu = WebMail->iconv_toUTF8; - - if (WebMail->iconv_toUTF8 == NULL) - icu = WebMail->iconv_toUTF8 = iconv_open("UTF-8//IGNORE", "CP1252"); + Len = strlen(Title); - if (icu == (iconv_t)-1) - { - strcpy(UTF8Title, Title); - WebMail->iconv_toUTF8 = NULL; - return; - } - - char * orig = UTF8Title; + if (WebIsUTF8(Title, Len) == FALSE) + { + int code = TrytoGuessCode(Title, Len); - iconv(icu, NULL, NULL, NULL, NULL); // Reset State Machine - iconv(icu, &Title, &len, (char ** __restrict__)&UTF8Title, &left); + if (code == 437) + Len = Convert437toUTF8(Title, Len, UTF8Title); + else if (code == 1251) + Len = Convert1251toUTF8(Title, Len, UTF8Title); + else + Len = Convert1252toUTF8(Title, Len, UTF8Title); -#endif + UTF8Title[Len] = 0; } else strcpy(UTF8Title, Title); diff --git a/BPQMail.c b/BPQMail.c index 51216bc..08d5818 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1142,6 +1142,7 @@ // Log Our HA when checking for flood bulls (45) // Semaphore calls to SaveConfig // Include SERVIC as valid from call (for Winlink Service messages) (49) +// Attempt to detect line draw characters in Webmail (50) #include "bpqmail.h" #include "winstdint.h" diff --git a/Bpq32.c b/Bpq32.c index 2916d7c..f7e1f59 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1233,6 +1233,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Fix possible crash if MQTT not in use (47) // Add optional ATTACH time limit for VARA (48) // API format fixes (48) +// AGWAPI Add protection against accidental connects from a non-agw application (50) #define CKernel diff --git a/MailTCP.c b/MailTCP.c index a08632d..49478e1 100644 --- a/MailTCP.c +++ b/MailTCP.c @@ -2656,6 +2656,7 @@ VOID ProcessPOP3ServerMessage(SocketConn * sockptr, char * Buffer, int Len) // Must be some other coding int code = TrytoGuessCode(msgbytes, Len); + UCHAR * UTF = malloc(Len * 3); if (code == 437) diff --git a/Versions.h b/Versions.h index efe04b6..5f0f730 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,24,49 -#define KVerstring "6.0.24.49\0" +#define KVers 6,0,24,50 +#define KVerstring "6.0.24.50\0" #ifdef CKernel diff --git a/WebMail.c b/WebMail.c index 569796f..edcc107 100644 --- a/WebMail.c +++ b/WebMail.c @@ -1246,63 +1246,25 @@ int ViewWebMailMessage(struct HTTPConnectionInfo * Session, char * Reply, int Nu User->Total.MsgsSent[Index] ++; // User->Total.BytesForwardedOut[Index] += Length; - // if body not UTF-8, convert it if (WebIsUTF8(MsgBytes, msgLen) == FALSE) { - // With Windows it is simple - convert using current codepage - // I think the only reliable way is to convert to unicode and back - - size_t origlen = msgLen + 1; - - UCHAR * BufferB = malloc(2 * origlen); -#ifdef WIN32 - WCHAR * BufferW = malloc(2 * origlen); - int wlen; - int len = (int)origlen; - - wlen = MultiByteToWideChar(CP_ACP, 0, MsgBytes, len, BufferW, (int)(origlen * 2)); - len = WideCharToMultiByte(CP_UTF8, 0, BufferW, wlen, BufferB, (int)(origlen * 2), NULL, NULL); + int code = TrytoGuessCode(MsgBytes, msgLen); - free(Save); - Save = MsgBytes = BufferB; - free(BufferW); - msgLen = len - 1; // exclude NULL -#else - size_t left = 2 * msgLen; - size_t outbuflen = left; - size_t len = msgLen + 1; // include null - int ret; - UCHAR * BufferBP = BufferB; - char * orig = MsgBytes; - MsgBytes[msgLen] = 0; + UCHAR * UTF = malloc(msgLen * 3); - iconv_t * icu = Session->WebMail->iconv_toUTF8; - - if (icu == NULL) - icu = Session->WebMail->iconv_toUTF8 = iconv_open("UTF-8//IGNORE", "CP1252"); - - if (icu == (iconv_t) -1) - { - Session->WebMail->iconv_toUTF8 = NULL; - strcpy(BufferB, MsgBytes); - } + if (code == 437) + msgLen = Convert437toUTF8(MsgBytes, msgLen, UTF); + else if (code == 1251) + msgLen = Convert1251toUTF8(MsgBytes, msgLen, UTF); else - { - iconv(icu, NULL, NULL, NULL, NULL); // Reset State Machine - ret = iconv(icu, &MsgBytes, &len, (char ** __restrict__)&BufferBP, &left); - } - - // left is next location to write, so length written is outbuflen - left - // add a null in case iconv didn't complete comversion - - BufferB[outbuflen - left] = 0; - - free(Save); - Save = MsgBytes = BufferB; - msgLen = strlen(MsgBytes); -#endif + msgLen = Convert1252toUTF8(MsgBytes, msgLen, UTF); + + free(MsgBytes); + Save = MsgBytes = UTF; + + MsgBytes[msgLen] = 0; } // ptr += sprintf(ptr, "%s", MsgBytes); diff --git a/utf8Routines.c b/utf8Routines.c index 6e0d17e..c0f9ca3 100644 --- a/utf8Routines.c +++ b/utf8Routines.c @@ -548,8 +548,8 @@ int TrytoGuessCode(unsigned char * Char, int Len) if (Above127 == 0) // DOesn't really matter! return 1252; - if (Above127 == LineDraw) - return 437; // If only Line Draw chars, assume line draw + if (LineDraw > ((Above127 * 9) / 10)) + return 437; // If mainly Line Draw chars, assume line draw // If mainly below 128, it is probably Latin if mainly above, probably Cyrillic