Skip to content
Snippets Groups Projects
Commit ce90be9e authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Fix corrupted RFC822 msg headers when a header field was > 1024 chars

When sending an SMB message header via SMTP or POP3, some header fields (lines) could potentially be longer than 1024 and yet sockprintf() was limited to sending 1024 bytes (actually 1022 plus CRLF). This could result in some messages not being sent correctly: header field truncated, not CRLR-terminated, and notably resulting in MIME message contents not being decoded properly in a message viewer/reader. Example (Content-Type is part of the previous header field/line):
x-ms-exchange-antispam-messagedata-0:
 =?us-ascii?Q?cm9T1Q9G65VC/lKTTqhODKhy5lHT2y6WWMb/WyvJ+EeGEwYmY7ILhzE3yfNM?=
 =?us-ascii?Q?KeFWN9T/PqHBya1plKf/sHgaw0iRmI7Hq+u9Dp4bG8OqdniKQlK+Aa27oXMd?=
 =?us-ascii?Q?Hly6OEYaSu7jbhGGY89LF0gyRVqquqxkaMfpKvG+h4cQnnu4Tl8YAKeE39a2?=
 =?us-ascii?Q?lHW3372ulmb9jvvZU72J2RtZYkuoIr+Wsqhfyuj39wTZ/+C4qKCsYrmTxrki?=
 =?us-ascii?Q?fBZ4gMPzWkrcWAr7zPcXBg8bphJJB8VJFUjQyksA3EG4dtH8+TZeEcNNBmHf?=
 =?us-ascii?Q?oCGnV9wHr9HszzrSkkZ2GGyh3QZLHAVDNe7wDXSy7HJttZugf9kNqKGeaYQL?=
 =?us-ascii?Q?TpljH1aHPe7MiSP9Dmp/xHQ/DWQOZDx5guNS+iMciMt5p5ad+SkQye0hWRhd?=
 =?us-ascii?Q?usHvpllclzIee6lxJ0VSPAzHGlAOhtOolrHdDB2ODjvkEzU7L2Fj2f5x7p9q?=
 =?us-ascii?Q?9d6sUgSz7vZVx8yyR3KPq3jIX0QUnl0xr2Mix9xcmMNcg0yFLPcznqBdLVa8?=
 =?us-ascii?Q?IC7j0+8oy4BjYxr8Z3elxMC2JKq13gPYgR95cwm6hMDiZbMB4EW/J1uJhD/I?=
 =?us-ascii?Q?RIIqTZ+Ywt8nKOfXj6/a9Aauf0wN71QKKA+in7KY9oksIhkUGvWOrtJwkVDL?=
 =?us-ascii?Q?Q2UFrBBJyQHJgumj5Y+bG8FDk/55IfyV9XYEcsdLL4bCF+HX4QPHZCw4P+li?=
 =?us-ascii?Q?bRvN+UxOO8hgXVkgB1q8mNJ62yQuaj0AContent-Type: multipart/alternative;
	boundary="_000_SN6PR07MB454477F4C32C66D48BA0B02187A09SN6PR07MB4544namp_"

Solved by using asprintf() instead of snprintf() for dynamic string formatting and allocation in one go. Using realloc() to expand the buffer for the appended/required CRLF.
parent 83a4d6ae
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #3836 passed
......@@ -40,6 +40,7 @@
#include "ini_file.h"
#include "netwrap.h" /* getNameServerList() */
#include "xpendian.h"
#include "xpprintf.h"
#include "js_rtpool.h"
#include "js_request.h"
#include "multisock.h"
......@@ -359,21 +360,9 @@ int mail_close_socket(SOCKET *sock, int *sess)
int sockprintf(SOCKET sock, const char* prot, CRYPT_SESSION sess, char *fmt, ...)
{
int len;
int maxlen;
int result;
va_list argptr;
char sbuf[1024];
va_start(argptr,fmt);
len=vsnprintf(sbuf,maxlen=sizeof(sbuf)-2,fmt,argptr);
va_end(argptr);
if(len<0 || len > maxlen) /* format error or output truncated */
len=maxlen;
if(startup->options&MAIL_OPT_DEBUG_TX)
lprintf(LOG_DEBUG,"%04d %s TX: %.*s", sock, prot, len, sbuf);
memcpy(sbuf+len,"\r\n",2);
len+=2;
char* sbuf = NULL;
if(sock==INVALID_SOCKET) {
lprintf(LOG_WARNING,"%s !INVALID SOCKET in call to sockprintf", prot);
......@@ -387,6 +376,27 @@ int sockprintf(SOCKET sock, const char* prot, CRYPT_SESSION sess, char *fmt, ...
return(0);
}
va_start(argptr,fmt);
len = vasprintf(&sbuf, fmt, argptr);
va_end(argptr);
if(len < 0 || sbuf == NULL) { /* format error or allocation error */
lprintf(LOG_CRIT, "%04d %s %s error (%d) formatting string: '%s'", sock, prot, __FUNCTION__, len, fmt);
free(sbuf);
return 0;
}
if(startup->options&MAIL_OPT_DEBUG_TX)
lprintf(LOG_DEBUG,"%04d %s TX: %.*s", sock, prot, len, sbuf);
char* newp = realloc(sbuf, len + 2); // "\r\n"
if(newp == NULL) { /* format error or allocation error */
lprintf(LOG_CRIT, "%04d %s %s re-allocation failure of %d bytes", sock, prot, __FUNCTION__, len + 2);
free(sbuf);
return 0;
}
sbuf = newp;
memcpy(sbuf+len,"\r\n",2);
len+=2;
if (sess != -1) {
int tls_sent;
int sent = 0;
......@@ -396,11 +406,13 @@ int sockprintf(SOCKET sock, const char* prot, CRYPT_SESSION sess, char *fmt, ...
sent += tls_sent;
else {
GCES(result, prot, sock, sess, "pushing data");
free(sbuf);
return 0;
}
}
if ((result = cryptFlushData(sess)) != CRYPT_OK) {
GCES(result, prot, sock, sess, "flushing data");
free(sbuf);
return 0;
}
}
......@@ -418,11 +430,13 @@ int sockprintf(SOCKET sock, const char* prot, CRYPT_SESSION sess, char *fmt, ...
lprintf(LOG_NOTICE,"%04d %s Connection aborted by peer on send",sock, prot);
else
lprintf(LOG_NOTICE,"%04d %s !ERROR %d sending on socket",sock,prot,ERROR_VALUE);
free(sbuf);
return(0);
}
lprintf(LOG_WARNING,"%04d %s !ERROR: short send on socket: %d instead of %d",sock,prot,result,len);
}
}
free(sbuf);
return(len);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment