1This patch is Copyright (C) 2004 by James Craig Burley.  License
2below.
3
42004-01-19 0040 EST  James Craig Burley  <craig-qmail@jcb-sc.com>
5
6This patch improves ISO C conformance of qmail code -- specifically,
7of qmail-lspawn, qmail-newmrh, qmail-newu, qmail-pop3d, qmail-popup,
8qmail-rspawn, and qmail-smtpd.  This fixes two known bugs:
9
10  -  qmail-smtpd can be crashed by a client sending a sufficiently
11     long (e.g. 2GB) header line in an email.
12
13  -  qmail_lspawn, qmail-newmrh, qmail-newu, and qmail-rspawn might
14     crash or otherwise misbehave on hosts with a smaller "int" type
15     than "char *" type, e.g. 64-bit hosts with 32-bit "int"s.
16
17The other changes are unlikely to have any effect, except possibly on
18unusual architectures and/or in the presence of rare optimizations.
19
20This is Version 1 of this patch.  It adds the changes to
21cdbmake_add.c, spawn.c, and, correspondingly, Makefile, which pertain
22to the second bug listed above.
23
24See all my qmail patches at <http://www.jcb-sc.com/qmail/patches/>.
25
26License:
27
28Permission is hereby granted, free of charge, to any person obtaining a
29copy of this software and associated documentation files (the
30"Software"), to deal in the Software without restriction, including
31without limitation the rights to use, copy, modify, merge, publish,
32distribute, sublicense, and/or sell copies of the Software, and to
33permit persons to whom the Software is furnished to do so, subject to
34the following conditions:
35
36The above copyright notice and this permission notice shall be included
37in all copies or substantial portions of the Software.
38
39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
41MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
42IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
43CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
44TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
45SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
47
48*** qmail-1.03/cdbmake_add.c	Mon Jun 15 06:53:16 1998
49--- qmail-1.03.0/cdbmake_add.c	Mon Jan 19 00:35:38 2004
50***************
51*** 1,2 ****
52--- 1,3 ----
53+ #include "alloc.h"
54  #include "cdbmake.h"
55
56*** qmail-1.03/Makefile	Mon Jun 15 06:53:16 1998
57--- qmail-1.03.0/Makefile	Mon Jan 19 00:35:35 2004
58*************** makelib cdbmake_pack.o cdbmake_hash.o cd
59*** 264,268 ****
60
61  cdbmake_add.o: \
62! compile cdbmake_add.c cdbmake.h uint32.h
63  	./compile cdbmake_add.c
64
65--- 264,268 ----
66
67  cdbmake_add.o: \
68! compile cdbmake_add.c cdbmake.h alloc.h uint32.h
69  	./compile cdbmake_add.c
70
71*************** trylsock.c compile load
72*** 1893,1897 ****
73  spawn.o: \
74  compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \
75! stralloc.h gen_alloc.h select.h exit.h coe.h open.h error.h \
76  auto_qmail.h auto_uids.h auto_spawn.h
77  	./chkspawn
78--- 1893,1897 ----
79  spawn.o: \
80  compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \
81! stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \
82  auto_qmail.h auto_uids.h auto_spawn.h
83  	./chkspawn
84*** qmail-1.03/qmail-pop3d.c	Mon Jun 15 06:53:16 1998
85--- qmail-1.03.0/qmail-pop3d.c	Thu Jan 15 22:08:57 2004
86*************** void die_scan() { err("unable to scan $H
87*** 67,71 ****
88
89  void err_syntax() { err("syntax error"); }
90! void err_unimpl() { err("unimplemented"); }
91  void err_deleted() { err("already deleted"); }
92  void err_nozero() { err("messages are counted from 1"); }
93--- 67,71 ----
94
95  void err_syntax() { err("syntax error"); }
96! void err_unimpl(arg) char *arg; { err("unimplemented"); }
97  void err_deleted() { err("already deleted"); }
98  void err_nozero() { err("messages are counted from 1"); }
99*************** void err_nosuch() { err("unable to open
100*** 74,78 ****
101  void err_nounlink() { err("unable to unlink all deleted messages"); }
102
103! void okay() { puts("+OK \r\n"); flush(); }
104
105  void printfn(fn) char *fn;
106--- 74,78 ----
107  void err_nounlink() { err("unable to unlink all deleted messages"); }
108
109! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); }
110
111  void printfn(fn) char *fn;
112*************** void getlist()
113*** 147,151 ****
114  }
115
116! void pop3_stat()
117  {
118    int i;
119--- 147,151 ----
120  }
121
122! void pop3_stat(arg) char *arg;
123  {
124    int i;
125*************** void pop3_stat()
126*** 162,174 ****
127  }
128
129! void pop3_rset()
130  {
131    int i;
132    for (i = 0;i < numm;++i) m[i].flagdeleted = 0;
133    last = 0;
134!   okay();
135  }
136
137! void pop3_last()
138  {
139    puts("+OK ");
140--- 162,174 ----
141  }
142
143! void pop3_rset(arg) char *arg;
144  {
145    int i;
146    for (i = 0;i < numm;++i) m[i].flagdeleted = 0;
147    last = 0;
148!   okay(0);
149  }
150
151! void pop3_last(arg) char *arg;
152  {
153    puts("+OK ");
154*************** void pop3_last()
155*** 178,182 ****
156  }
157
158! void pop3_quit()
159  {
160    int i;
161--- 178,182 ----
162  }
163
164! void pop3_quit(arg) char *arg;
165  {
166    int i;
167*************** void pop3_quit()
168*** 193,197 ****
169  	rename(m[i].fn,line.s); /* if it fails, bummer */
170        }
171!   okay();
172    die();
173  }
174--- 193,197 ----
175  	rename(m[i].fn,line.s); /* if it fails, bummer */
176        }
177!   okay(0);
178    die();
179  }
180*************** void pop3_dele(arg) char *arg;
181*** 215,219 ****
182    m[i].flagdeleted = 1;
183    if (i + 1 > last) last = i + 1;
184!   okay();
185  }
186
187--- 215,219 ----
188    m[i].flagdeleted = 1;
189    if (i + 1 > last) last = i + 1;
190!   okay(0);
191  }
192
193*************** void dolisting(arg,flaguidl) char *arg;
194*** 239,243 ****
195    }
196    else {
197!     okay();
198      for (i = 0;i < numm;++i)
199        if (!m[i].flagdeleted)
200--- 239,243 ----
201    }
202    else {
203!     okay(0);
204      for (i = 0;i < numm;++i)
205        if (!m[i].flagdeleted)
206*************** void pop3_top(arg) char *arg;
207*** 268,272 ****
208    fd = open_read(m[i].fn);
209    if (fd == -1) { err_nosuch(); return; }
210!   okay();
211    substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf));
212    blast(&ssmsg,limit);
213--- 268,272 ----
214    fd = open_read(m[i].fn);
215    if (fd == -1) { err_nosuch(); return; }
216!   okay(0);
217    substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf));
218    blast(&ssmsg,limit);
219*************** char **argv;
220*** 300,304 ****
221    getlist();
222
223!   okay();
224    commands(&ssin,pop3commands);
225    die();
226--- 300,304 ----
227    getlist();
228
229!   okay(0);
230    commands(&ssin,pop3commands);
231    die();
232*** qmail-1.03/qmail-popup.c	Mon Jun 15 06:53:16 1998
233--- qmail-1.03.0/qmail-popup.c	Thu Jan 15 22:09:21 2004
234*************** void die_badauth() { err("authorization
235*** 65,72 ****
236  void err_syntax() { err("syntax error"); }
237  void err_wantuser() { err("USER first"); }
238! void err_authoriz() { err("authorization first"); }
239
240! void okay() { puts("+OK \r\n"); flush(); }
241! void pop3_quit() { okay(); die(); }
242
243
244--- 65,72 ----
245  void err_syntax() { err("syntax error"); }
246  void err_wantuser() { err("USER first"); }
247! void err_authoriz(arg) char *arg; { err("authorization first"); }
248
249! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); }
250! void pop3_quit(arg) char *arg; { okay(0); die(); }
251
252
253*************** void pop3_user(arg) char *arg;
254*** 137,141 ****
255  {
256    if (!*arg) { err_syntax(); return; }
257!   okay();
258    seenuser = 1;
259    if (!stralloc_copys(&username,arg)) die_nomem();
260--- 137,141 ----
261  {
262    if (!*arg) { err_syntax(); return; }
263!   okay(0);
264    seenuser = 1;
265    if (!stralloc_copys(&username,arg)) die_nomem();
266*** qmail-1.03/qmail-smtpd.c	Mon Jun 15 06:53:16 1998
267--- qmail-1.03.0/qmail-smtpd.c	Thu Jan 15 22:12:02 2004
268*************** void straynewline() { out("451 See http:
269*** 52,61 ****
270  void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
271  void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
272! void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
273  void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
274  void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); }
275  void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); }
276! void err_noop() { out("250 ok\r\n"); }
277! void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); }
278  void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
279
280--- 52,61 ----
281  void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
282  void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
283! void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); }
284  void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
285  void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); }
286  void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); }
287! void err_noop(arg) char *arg; { out("250 ok\r\n"); }
288! void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); }
289  void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
290
291*************** void smtp_greet(code) char *code;
292*** 68,76 ****
293    substdio_put(&ssout,greeting.s,greeting.len);
294  }
295! void smtp_help()
296  {
297    out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n");
298  }
299! void smtp_quit()
300  {
301    smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
302--- 68,76 ----
303    substdio_put(&ssout,greeting.s,greeting.len);
304  }
305! void smtp_help(arg) char *arg;
306  {
307    out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n");
308  }
309! void smtp_quit(arg) char *arg;
310  {
311    smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
312*************** void smtp_ehlo(arg) char *arg;
313*** 233,237 ****
314    seenmail = 0; dohelo(arg);
315  }
316! void smtp_rset()
317  {
318    seenmail = 0;
319--- 233,237 ----
320    seenmail = 0; dohelo(arg);
321  }
322! void smtp_rset(arg) char *arg;
323  {
324    seenmail = 0;
325*************** int *hops;
326*** 317,322 ****
327          if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
328          if (flagmaybey) if (pos == 1) flaginheader = 0;
329        }
330-       ++pos;
331        if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
332      }
333--- 317,322 ----
334          if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
335          if (flagmaybey) if (pos == 1) flaginheader = 0;
336+ 	++pos;
337        }
338        if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
339      }
340*************** void acceptmessage(qp) unsigned long qp;
341*** 366,370 ****
342  }
343
344! void smtp_data() {
345    int hops;
346    unsigned long qp;
347--- 366,370 ----
348  }
349
350! void smtp_data(arg) char *arg; {
351    int hops;
352    unsigned long qp;
353*** qmail-1.03/spawn.c	Mon Jun 15 06:53:16 1998
354--- qmail-1.03.0/spawn.c	Mon Jan 19 00:35:38 2004
355***************
356*** 6,9 ****
357--- 6,10 ----
358  #include "byte.h"
359  #include "str.h"
360+ #include "alloc.h"
361  #include "stralloc.h"
362  #include "select.h"
363