aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/exim/patch-exim-src_spam.c.diff
blob: 1109874b51dbf1e4b504c12b09aa6e52750468b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
--- src/spam.c.orig	2011-01-20 19:29:51.179597017 +0300
+++ src/spam.c	2011-02-21 21:17:15.051230555 +0300
@@ -21,6 +21,9 @@
 int spam_ok = 0;
 int spam_rc = 0;
 
+/* push formatted line into vector */
+static int push_line(struct iovec *iov, int i, const char *fmt, ...);
+
 int spam(uschar **listptr) {
   int sep = 0;
   uschar *list = *listptr;
@@ -211,14 +214,26 @@
   }
 
   /* now we are connected to spamd on spamd_sock */
-  (void)string_format(spamd_buffer,
-           sizeof(spamd_buffer),
-           "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
-           user_name,
-           mbox_size);
+  int r, request_p = 0;
+  const char *helo;
+  struct iovec request_v[64];
+  
+  r = 0;
+  r += push_line(request_v, request_p++, "REPORT SPAMC/1.2\r\n");
+  r += push_line(request_v, request_p++, "Content-length: %lu\r\n", mbox_size);
+  r += push_line(request_v, request_p++, "Queue-Id: %s\r\n", message_id);
+  r += push_line(request_v, request_p++, "From: <%s>\r\n", sender_address);
+  r += push_line(request_v, request_p++, "Recipient-Number: %d\r\n", recipients_count);
+  for (i = 0; i < recipients_count; i ++)
+    r += push_line(request_v, request_p++, "Rcpt: <%s>\r\n", recipients_list[i].address);
+  if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')
+    r += push_line(request_v, request_p++, "Helo: %s\r\n", helo);
+  if (sender_host_address != NULL)
+    r += push_line(request_v, request_p++, "IP: %s\r\n", sender_host_address);
+  r += push_line(request_v, request_p++, "\r\n");
 
   /* send our request */
-  if (send(spamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0) < 0) {
+  if (writev(spamd_sock, request_v, request_p) < 0) {
     (void)close(spamd_sock);
     log_write(0, LOG_MAIN|LOG_PANIC,
          "spam acl condition: spamd send failed: %s", strerror(errno));
@@ -329,7 +344,7 @@
   (void)close(spamd_sock);
 
   /* dig in the spamd output and put the report in a multiline header, if requested */
-  if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\nContent-length: %*u\r\n\r\n%lf/%lf\r\n%n",
+  if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\n\r\nSpam: %*s ; %lf / %lf\r\nContent-length: %*u\r\n\r\n%n",
              spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3 ) {
 
     /* try to fall back to pre-2.50 spamd output */
@@ -420,4 +435,31 @@
   };
 }
 
+static int
+push_line(struct iovec *iov, const int i, const char *fmt, ...)
+{
+  va_list ap;
+  size_t len;
+  char buf[512];
+
+  if (i >= 64) {
+    log_write(0, LOG_MAIN, "rspam: %s: index out of bounds", __FUNCTION__);
+    return (-1);
+  }
+
+  va_start(ap, fmt);
+  len = vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+
+  iov[i].iov_base = string_copy(US buf);
+  iov[i].iov_len = len;
+
+  if (len >= sizeof(buf)) {
+    log_write(0, LOG_MAIN, "rspam: %s: error, string was longer than %d", __FUNCTION__, sizeof(buf));
+    return (-1);
+  }
+
+  return 0;
+}
+
 #endif