97
97
#undef DO_CONNECT_DEBUG_SYSLOGS
98
98
/* or #define DO_CONNECT_DEBUG_SYSLOGS 1 */
100
static const int ESC_PASSTHROUGHRAW = EX__MAX + 666;
100
/* static const int ESC_PASSTHROUGHRAW = EX__MAX + 666; No longer seems to be used */
102
102
/* set EXPANSION_ALLOWANCE to something more than might be
103
103
added to a message in X-headers and the report template */
195
195
#ifdef DO_CONNECT_DEBUG_SYSLOGS
196
libspamc_log(flags, DEBUG_LEVEL, "dbg: create socket(%s)", typename);
196
libspamc_log(flags, LOG_DEBUG, "dbg: create socket(%s)", typename);
199
199
if ((*psock = socket(type, SOCK_STREAM, proto))
334
334
addrbuf.sun_path[sizeof addrbuf.sun_path - 1] = '\0';
336
336
#ifdef DO_CONNECT_DEBUG_SYSLOGS
337
libspamc_log(tp->flags, DEBUG_LEVEL, "dbg: connect(AF_UNIX) to spamd at %s",
337
libspamc_log(tp->flags, LOG_DEBUG, "dbg: connect(AF_UNIX) to spamd at %s",
338
338
addrbuf.sun_path);
341
status = connect(mysock, (struct sockaddr *) &addrbuf, sizeof(addrbuf));
341
status = timeout_connect(mysock, (struct sockaddr *) &addrbuf, sizeof(addrbuf));
345
345
if (status >= 0) {
346
346
#ifdef DO_CONNECT_DEBUG_SYSLOGS
347
libspamc_log(tp->flags, DEBUG_LEVEL, "dbg: connect(AF_UNIX) ok");
347
libspamc_log(tp->flags, LOG_DEBUG, "dbg: connect(AF_UNIX) ok");
350
350
*sockptr = mysock;
412
412
ipaddr = inet_ntoa(addrbuf.sin_addr);
414
414
#ifdef DO_CONNECT_DEBUG_SYSLOGS
415
libspamc_log(tp->flags, DEBUG_LEVEL,
415
libspamc_log(tp->flags, LOG_DEBUG,
416
416
"dbg: connect(AF_INET) to spamd at %s (try #%d of %d)",
417
417
ipaddr, numloops + 1, MAX_CONNECT_RETRIES);
421
connect(mysock, (struct sockaddr *) &addrbuf, sizeof(addrbuf));
421
timeout_connect(mysock, (struct sockaddr *) &addrbuf, sizeof(addrbuf));
423
423
if (status != 0) {
440
440
#ifdef DO_CONNECT_DEBUG_SYSLOGS
441
libspamc_log(tp->flags, DEBUG_LEVEL,
441
libspamc_log(tp->flags, LOG_DEBUG,
442
442
"dbg: connect(AF_INET) to spamd at %s done", ipaddr);
444
444
*sockptr = mysock;
502
502
m->type = MESSAGE_ERROR;
503
if (m->raw_len > m->max_len)
503
if (m->raw_len > (int) m->max_len)
505
505
libspamc_log(m->priv->flags, LOG_ERR,
506
506
"skipped message, greater than max message size (%d bytes)",
518
518
static int _message_read_bsmtp(int fd, struct message *m)
520
unsigned int i, j, p_len;
523
524
_clear_message(m);
524
525
if ((m->raw = malloc(m->max_len + 1)) == NULL)
535
536
m->type = MESSAGE_ERROR;
536
if (m->raw_len > m->max_len)
537
if (m->raw_len > (int) m->max_len)
537
538
return EX_TOOBIG;
539
for (i = 0; i < m->raw_len - 6; i++) {
540
if ((m->raw[i] == '\n') &&
541
(m->raw[i + 1] == 'D' || m->raw[i + 1] == 'd') &&
542
(m->raw[i + 2] == 'A' || m->raw[i + 2] == 'a') &&
543
(m->raw[i + 3] == 'T' || m->raw[i + 3] == 't') &&
544
(m->raw[i + 4] == 'A' || m->raw[i + 4] == 'a') &&
545
((m->raw[i + 5] == '\r' && m->raw[i + 6] == '\n')
546
|| m->raw[i + 5] == '\n')) {
549
if (m->raw[i - 1] == '\r')
553
m->msg_len = m->raw_len - i;
540
/* Search for \nDATA\n which marks start of actual message */
541
while ((p_len = (m->raw_len - (p - m->raw))) > 8) { /* leave room for at least \nDATA\n.\n */
542
char* q = memchr(p, '\n', p_len - 8); /* find next \n then see if start of \nDATA\n */
543
if (q == NULL) break;
545
if (((q[0]|0x20) == 'd') && /* case-insensitive ASCII comparison */
546
((q[1]|0x20) == 'a') &&
547
((q[2]|0x20) == 't') &&
548
((q[3]|0x20) == 'a')) {
550
if (q[0] == '\r') ++q;
551
if (*(q++) == '\n') { /* leave q at start of message if we found it */
553
m->pre_len = q - m->raw;
554
m->msg_len = m->raw_len - m->pre_len;
558
p = q; /* the above code ensures no other '\n' comes before q */
557
560
if (m->msg == NULL)
558
561
return EX_DATAERR;
563
/* ensure this is >= 0 */
564
if (m->msg_len < 0) {
560
568
/* Find the end-of-DATA line */
569
/* if bad format with no end ".\n" will truncate the last two characters of the buffer */
562
for (i = j = 0; i < m->msg_len; i++) {
571
for (i = j = 0; (i+2) < (unsigned int) m->msg_len; i++) { /* (i+2) prevents out of bound reference msg[i+2] */
563
572
if (prev == '\n' && m->msg[i] == '.') {
564
573
/* Dot at the beginning of a line */
565
574
if ((m->msg[i + 1] == '\r' && m->msg[i + 2] == '\n')
855
else if (sscanf(buf, "DidSet: %s", didset_ret) == 1) {
864
else if (sscanf(buf, "DidSet: %14s", didset_ret) == 1) {
856
865
if (strstr(didset_ret, "local")) {
857
866
*didtellflags |= SPAMC_SET_LOCAL;
860
869
*didtellflags |= SPAMC_SET_REMOTE;
863
else if (sscanf(buf, "DidRemove: %s", didremove_ret) == 1) {
872
else if (sscanf(buf, "DidRemove: %14s", didremove_ret) == 1) {
864
873
if (strstr(didremove_ret, "local")) {
865
874
*didtellflags |= SPAMC_REMOVE_LOCAL;
951
960
_use_msg_for_out(m);
954
len += sprintf(buf + len, "Content-length: %d\r\n\r\n", m->msg_len);
963
len += sprintf(buf + len, "Content-length: %d\r\n\r\n", (int) m->msg_len);
956
965
libspamc_timeout = m->timeout;
1120
1129
m.type = MESSAGE_NONE;
1122
m.max_len = max_size;
1131
/* enforce max_size being unsigned, therefore >= 0 */
1136
m.max_len = (unsigned int) max_size;
1123
1138
ret = message_read(in_fd, flags, &m);
1124
1139
if (ret != EX_OK)
1263
1278
_use_msg_for_out(m);
1264
1279
return EX_OSERR;
1266
len += sprintf(buf + len, "Content-length: %d\r\n\r\n", m->msg_len);
1281
len += sprintf(buf + len, "Content-length: %d\r\n\r\n", (int) m->msg_len);
1268
1283
libspamc_timeout = m->timeout;
1625
1640
va_start(ap, msg);
1627
1642
if ((flags & SPAMC_LOG_TO_STDERR) != 0) {
1628
// create a log-line buffer
1643
/* create a log-line buffer */
1629
1644
len = snprintf(buf, LOG_BUFSIZ, "spamc: ");
1630
1645
len += vsnprintf(buf+len, LOG_BUFSIZ-len, msg, ap);
1632
// avoid buffer overflow
1647
/* avoid buffer overflow */
1633
1648
if (len > (LOG_BUFSIZ-2)) { len = (LOG_BUFSIZ-3); }
1635
1650
len += snprintf(buf+len, LOG_BUFSIZ-len, "\n");