| @@ -1,31 +1,79 @@ | | | @@ -1,31 +1,79 @@ |
1 | $NetBSD: patch-aa,v 1.3 2010/04/17 21:11:18 tez Exp $ | | 1 | $NetBSD: patch-aa,v 1.4 2010/09/10 23:33:42 gdt Exp $ |
2 | Added CVE-2010-1132 patch from: | | 2 | |
3 | https://bugzilla.redhat.com/attachment.cgi?id=401011 | | 3 | This patch has hunks for three separate reasons: |
4 | | | 4 | |
5 | --- spamass-milter.cpp.orig 2010-04-17 16:04:59.724786300 -0500 | | 5 | 1) Ancient fix to avoid going beyond s2. |
6 | +++ spamass-milter.cpp 2010-04-17 16:05:04.755469800 -0500 | | 6 | |
7 | @@ -171,10 +171,6 @@ | | 7 | 2) Added CVE-2010-1132 patch from: |
| | | 8 | |
| | | 9 | https://bugzilla.redhat.com/attachment.cgi?id=401011 |
| | | 10 | |
| | | 11 | 3) (Most of, some in .h) patch to add option to not scan mail from |
| | | 12 | authenticated users, from: |
| | | 13 | |
| | | 14 | http://lists.freebsd.org/pipermail/freebsd-ports-bugs/2006-November/106024.html |
| | | 15 | |
| | | 16 | --- spamass-milter.cpp.orig 2010-09-10 15:50:58.000000000 +0000 |
| | | 17 | +++ spamass-milter.cpp |
| | | 18 | @@ -170,10 +170,7 @@ char *spambucket; |
| | | 19 | bool flag_full_email = false; /* pass full email address to spamc */ |
8 | bool flag_expand = false; /* alias/virtusertable expansion */ | | 20 | bool flag_expand = false; /* alias/virtusertable expansion */ |
9 | bool warnedmacro = false; /* have we logged that we couldn't fetch a macro? */ | | 21 | bool warnedmacro = false; /* have we logged that we couldn't fetch a macro? */ |
10 | | | 22 | - |
11 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ | | 23 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ |
12 | -static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER; | | 24 | -static pthread_mutex_t popen_mutex = PTHREAD_MUTEX_INITIALIZER; |
13 | -#endif | | 25 | -#endif |
14 | - | | 26 | +bool auth = false; /* don't scan authenticated users */ |
| | | 27 | |
15 | // {{{ main() | | 28 | // {{{ main() |
16 | | | 29 | |
17 | int | | 30 | @@ -181,7 +178,7 @@ int |
18 | @@ -461,59 +457,24 @@ | | 31 | main(int argc, char* argv[]) |
| | | 32 | { |
| | | 33 | int c, err = 0; |
| | | 34 | - const char *args = "fd:mMp:P:r:u:D:i:b:B:e:x"; |
| | | 35 | + const char *args = "fd:mMp:P:r:u:D:i:b:B:e:xa"; |
| | | 36 | char *sock = NULL; |
| | | 37 | bool dofork = false; |
| | | 38 | char *pidfilename = NULL; |
| | | 39 | @@ -196,6 +193,9 @@ main(int argc, char* argv[]) |
| | | 40 | /* Process command line options */ |
| | | 41 | while ((c = getopt(argc, argv, args)) != -1) { |
| | | 42 | switch (c) { |
| | | 43 | + case 'a': |
| | | 44 | + auth = true; |
| | | 45 | + break; |
| | | 46 | case 'f': |
| | | 47 | dofork = true; |
| | | 48 | break; |
| | | 49 | @@ -281,7 +281,7 @@ main(int argc, char* argv[]) |
| | | 50 | cout << "SpamAssassin Sendmail Milter Plugin" << endl; |
| | | 51 | cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d xx[,yy...]] [-D host]" << endl; |
| | | 52 | cout << " [-e defaultdomain] [-f] [-i networks] [-m] [-M]" << endl; |
| | | 53 | - cout << " [-P pidfile] [-r nn] [-u defaultuser] [-x]" << endl; |
| | | 54 | + cout << " [-P pidfile] [-r nn] [-u defaultuser] [-x] [-a]" << endl; |
| | | 55 | cout << " [-- spamc args ]" << endl; |
| | | 56 | cout << " -p socket: path to create socket" << endl; |
| | | 57 | cout << " -b bucket: redirect spam to this mail address. The orignal" << endl; |
| | | 58 | @@ -302,6 +302,7 @@ main(int argc, char* argv[]) |
| | | 59 | cout << " -u defaultuser: pass the recipient's username to spamc.\n" |
| | | 60 | " Uses 'defaultuser' if there are multiple recipients." << endl; |
| | | 61 | cout << " -x: pass email address through alias and virtusertable expansion." << endl; |
| | | 62 | + cout << " -a: don't scan messages over an authenticated connection." << endl; |
| | | 63 | cout << " -- spamc args: pass the remaining flags to spamc." << endl; |
| | | 64 | |
| | | 65 | exit(EX_USAGE); |
| | | 66 | @@ -461,59 +462,24 @@ assassinate(SMFICTX* ctx, SpamAssassin* |
19 | send another copy. The milter API will not let you send the | | 67 | send another copy. The milter API will not let you send the |
20 | message AND return a failure code to the sender, so this is | | 68 | message AND return a failure code to the sender, so this is |
21 | the only way to do it. */ | | 69 | the only way to do it. */ |
22 | -#if defined(__FreeBSD__) | | 70 | -#if defined(__FreeBSD__) |
23 | - int rv; | | 71 | - int rv; |
24 | -#endif | | 72 | -#endif |
25 | - | | 73 | - |
26 | -#if defined(HAVE_ASPRINTF) | | 74 | -#if defined(HAVE_ASPRINTF) |
27 | - char *buf; | | 75 | - char *buf; |
28 | -#else | | 76 | -#else |
29 | - char buf[1024]; | | 77 | - char buf[1024]; |
30 | -#endif | | 78 | -#endif |
31 | - char *fmt="%s \"%s\""; | | 79 | - char *fmt="%s \"%s\""; |
| @@ -74,94 +122,110 @@ Added CVE-2010-1132 patch from: | | | @@ -74,94 +122,110 @@ Added CVE-2010-1132 patch from: |
74 | - rv = pthread_mutex_unlock(&popen_mutex); | | 122 | - rv = pthread_mutex_unlock(&popen_mutex); |
75 | - if (rv) | | 123 | - if (rv) |
76 | - { | | 124 | - { |
77 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); | | 125 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); |
78 | - abort(); | | 126 | - abort(); |
79 | - } | | 127 | - } |
80 | -#endif | | 128 | -#endif |
81 | -#if defined(HAVE_ASPRINTF) | | 129 | -#if defined(HAVE_ASPRINTF) |
82 | - free(buf); | | 130 | - free(buf); |
83 | -#endif | | 131 | -#endif |
84 | } | | 132 | } |
85 | return SMFIS_REJECT; | | 133 | return SMFIS_REJECT; |
86 | } | | 134 | } |
87 | @@ -842,30 +803,19 @@ | | 135 | @@ -783,6 +749,15 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro |
| | | 136 | } |
| | | 137 | /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */ |
| | | 138 | |
| | | 139 | + if (auth) { |
| | | 140 | + const char *auth_type = smfi_getsymval(ctx, "{auth_type}"); |
| | | 141 | + |
| | | 142 | + if (auth_type) { |
| | | 143 | + debug(D_MISC, "auth_type=%s", auth_type); |
| | | 144 | + return SMFIS_ACCEPT; |
| | | 145 | + } |
| | | 146 | + } |
| | | 147 | + |
| | | 148 | debug(D_FUNC, "mlfi_envfrom: enter"); |
| | | 149 | try { |
| | | 150 | // launch new SpamAssassin |
| | | 151 | @@ -842,30 +817,19 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp |
88 | /* open a pipe to sendmail so we can do address expansion */ | | 152 | /* open a pipe to sendmail so we can do address expansion */ |
89 | | | 153 | |
90 | char buf[1024]; | | 154 | char buf[1024]; |
91 | - char *fmt="%s -bv \"%s\" 2>&1"; | | 155 | - char *fmt="%s -bv \"%s\" 2>&1"; |
92 | - | | 156 | - |
93 | -#if defined(HAVE_SNPRINTF) | | 157 | -#if defined(HAVE_SNPRINTF) |
94 | - snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, envrcpt[0]); | | 158 | - snprintf(buf, sizeof(buf)-1, fmt, SENDMAIL, envrcpt[0]); |
95 | -#else | | 159 | -#else |
96 | - /* XXX possible buffer overflow here */ | | 160 | - /* XXX possible buffer overflow here */ |
97 | - sprintf(buf, fmt, SENDMAIL, envrcpt[0]); | | 161 | - sprintf(buf, fmt, SENDMAIL, envrcpt[0]); |
98 | -#endif | | 162 | -#endif |
| | | 163 | - |
| | | 164 | - debug(D_RCPT, "calling %s", buf); |
99 | + char *popen_argv[4]; | | 165 | + char *popen_argv[4]; |
100 | + | | 166 | + |
101 | + popen_argv[0] = SENDMAIL; | | 167 | + popen_argv[0] = SENDMAIL; |
102 | + popen_argv[1] = "-bv"; | | 168 | + popen_argv[1] = "-bv"; |
103 | + popen_argv[2] = envrcpt[0]; | | 169 | + popen_argv[2] = envrcpt[0]; |
104 | + popen_argv[3] = NULL; | | 170 | + popen_argv[3] = NULL; |
105 | | | 171 | |
106 | - debug(D_RCPT, "calling %s", buf); | | | |
107 | + debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]); | | | |
108 | | | | |
109 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ | | 172 | -#if defined(__FreeBSD__) /* popen bug - see PR bin/50770 */ |
110 | - rv = pthread_mutex_lock(&popen_mutex); | | 173 | - rv = pthread_mutex_lock(&popen_mutex); |
111 | - if (rv) | | 174 | - if (rv) |
112 | - { | | 175 | - { |
113 | - debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv)); | | 176 | - debug(D_ALWAYS, "Could not lock popen mutex: %s", strerror(rv)); |
114 | - abort(); | | 177 | - abort(); |
115 | - } | | 178 | - } |
116 | -#endif | | 179 | -#endif |
117 | - | | 180 | + debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]); |
| | | 181 | |
118 | - p = popen(buf, "r"); | | 182 | - p = popen(buf, "r"); |
119 | + p = popenv(popen_argv, "r"); | | 183 | + p = popenv(popen_argv, "r"); |
120 | if (!p) | | 184 | if (!p) |
121 | { | | 185 | { |
122 | - debug(D_RCPT, "popen failed(%s). Will not expand aliases", strerror(errno)); | | 186 | - debug(D_RCPT, "popen failed(%s). Will not expand aliases", strerror(errno)); |
123 | + debug(D_RCPT, "popenv failed(%s). Will not expand aliases", strerror(errno)); | | 187 | + debug(D_RCPT, "popenv failed(%s). Will not expand aliases", strerror(errno)); |
124 | assassin->expandedrcpt.push_back(envrcpt[0]); | | 188 | assassin->expandedrcpt.push_back(envrcpt[0]); |
125 | } else | | 189 | } else |
126 | { | | 190 | { |
127 | @@ -890,16 +840,8 @@ | | 191 | @@ -890,16 +854,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp |
128 | assassin->expandedrcpt.push_back(p+7); | | 192 | assassin->expandedrcpt.push_back(p+7); |
129 | } | | 193 | } |
130 | } | | 194 | } |
131 | - pclose(p); p = NULL; | | 195 | - pclose(p); p = NULL; |
132 | + fclose(p); p = NULL; | | 196 | + fclose(p); p = NULL; |
133 | } | | 197 | } |
134 | -#if defined(__FreeBSD__) | | 198 | -#if defined(__FreeBSD__) |
135 | - rv = pthread_mutex_unlock(&popen_mutex); | | 199 | - rv = pthread_mutex_unlock(&popen_mutex); |
136 | - if (rv) | | 200 | - if (rv) |
137 | - { | | 201 | - { |
138 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); | | 202 | - debug(D_ALWAYS, "Could not unlock popen mutex: %s", strerror(rv)); |
139 | - abort(); | | 203 | - abort(); |
140 | - } | | 204 | - } |
141 | -#endif | | 205 | -#endif |
142 | } else | | 206 | } else |
143 | { | | 207 | { |
144 | assassin->expandedrcpt.push_back(envrcpt[0]); | | 208 | assassin->expandedrcpt.push_back(envrcpt[0]); |
145 | @@ -2033,7 +1975,7 @@ | | 209 | @@ -2033,7 +1989,7 @@ cmp_nocase_partial(const string& s, cons |
146 | string::const_iterator p=s.begin(); | | 210 | string::const_iterator p=s.begin(); |
147 | string::const_iterator p2=s2.begin(); | | 211 | string::const_iterator p2=s2.begin(); |
148 | | | 212 | |
149 | - while ( p != s.end() && p2 <= s2.end() ) { | | 213 | - while ( p != s.end() && p2 <= s2.end() ) { |
150 | + while ( p != s.end() ) { | | 214 | + while ( p != s.end() ) { |
151 | if (toupper(*p) != toupper(*p2)) | | 215 | if (toupper(*p) != toupper(*p2)) |
152 | { | | 216 | { |
153 | debug(D_STR, "c_nc_p: <%s><%s> : miss", s.c_str(), s2.c_str()); | | 217 | debug(D_STR, "c_nc_p: <%s><%s> : miss", s.c_str(), s2.c_str()); |
154 | @@ -2157,5 +2099,71 @@ | | 218 | @@ -2157,5 +2113,71 @@ void warnmacro(char *macro, char *scope) |
155 | warnedmacro = true; | | 219 | warnedmacro = true; |
156 | } | | 220 | } |
157 | | | 221 | |
158 | +/* | | 222 | +/* |
159 | + untrusted-argument-safe popen function - only supports "r" and "w" modes | | 223 | + untrusted-argument-safe popen function - only supports "r" and "w" modes |
160 | + for simplicity, and always reads stdout and stderr in "r" mode. Call | | 224 | + for simplicity, and always reads stdout and stderr in "r" mode. Call |
161 | + fclose to close the FILE. | | 225 | + fclose to close the FILE. |
162 | +*/ | | 226 | +*/ |
163 | +FILE *popenv(char *const argv[], const char *type) | | 227 | +FILE *popenv(char *const argv[], const char *type) |
164 | +{ | | 228 | +{ |
165 | + FILE *iop; | | 229 | + FILE *iop; |
166 | + int pdes[2]; | | 230 | + int pdes[2]; |
167 | + int save_errno; | | 231 | + int save_errno; |