Added practical example to README.ENVELOPE_SCAN file patch
[qmail-ldap-patches] / qmail-ldap-envelope-scan / qmail-ldap-1.03-20060201-envelope-scan.patch
1 diff -Naur qmail-ldap-1.03-20060201/FILES qmail-ldap-envelope-scan-1.0rc3/FILES
2 --- qmail-ldap-1.03-20060201/FILES      2009-06-26 17:03:56.000000000 +0100
3 +++ qmail-ldap-envelope-scan-1.0rc3/FILES       2009-06-26 19:01:15.000000000 +0100
4 @@ -3,6 +3,7 @@
5  BLURB3
6  BLURB4
7  README
8 +README.ENVELOPE_SCAN
9  FAQ
10  INSTALL
11  INSTALL.alias
12 diff -Naur qmail-ldap-1.03-20060201/Makefile qmail-ldap-envelope-scan-1.0rc3/Makefile
13 --- qmail-ldap-1.03-20060201/Makefile   2009-06-26 17:03:56.000000000 +0100
14 +++ qmail-ldap-envelope-scan-1.0rc3/Makefile    2009-06-26 19:25:47.000000000 +0100
15 @@ -19,6 +19,8 @@
16  # -DQMQP_COMPRESS to use the QMQP on the fly compression (for clusters)
17  # -DQUOTATRASH to include the Trash in the quota calculation (normaly it is not)
18  # -DSMTPEXECCHECK to enable smtp DOS/Windows executable detection
19 +# -DENVELOPE_SCAN to enable generic envelope scanning. Postfix SMTPD Access
20 +#  Policy Server or custom authorization.
21  #LDAPFLAGS=-DQLDAP_CLUSTER -DEXTERNAL_TODO -DDASH_EXT -DDATA_COMPRESS -DQMQP_COMPRESS -DSMTPEXECCHECK
22  
23  # Perhaps you have different ldap libraries, change them here
24 @@ -272,6 +274,10 @@
25  compile auto_split.c
26         ./compile auto_split.c
27  
28 +session.o: \
29 +compile session.c uint64.h
30 +       ./compile session.c
31 +
32  auto_uids.c: \
33  auto-uid auto-gid conf-users conf-groups
34         ( ./auto-uid auto_uida `head -1 conf-users` \
35 @@ -814,6 +820,10 @@
36  compile fmt_ulong.c fmt.h
37         ./compile fmt_ulong.c
38  
39 +fmt_uint64.o: \
40 +compile fmt_uint64.c fmt.h uint64.h
41 +       ./compile fmt_uint64.c
42 +
43  fmtqfn.o: \
44  compile fmtqfn.c fmtqfn.h fmt.h auto_split.h
45         ./compile fmtqfn.c
46 @@ -2061,14 +2071,14 @@
47  timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
48  date822fmt.o now.o qmail.o execcheck.o cdb.a smtpcall.o coe.o fd.a \
49  seek.a wait.a datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
50 -alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_break.o \
51 -dns.lib socket.lib
52 +alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o auto_break.o \
53 +session.o fmt_uint64.o dns.lib socket.lib
54         ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o rbl.o \
55         timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
56         received.o date822fmt.o now.o qmail.o execcheck.o cdb.a \
57         smtpcall.o coe.o fd.a seek.a wait.a datetime.a getln.a \
58         open.a sig.a case.a env.a stralloc.a alloc.a substdio.a \
59 -       error.a fs.a auto_qmail.o dns.o str.a auto_break.o \
60 +       error.a fs.a auto_qmail.o dns.o str.a auto_break.o session.o fmt_uint64.o \
61         `cat dns.lib` `cat socket.lib` $(TLSLIBS) $(ZLIB)
62  
63  qmail-smtpd.0: \
64 @@ -2274,7 +2284,7 @@
65  received.o: \
66  compile received.c fmt.h qmail.h substdio.h now.h datetime.h \
67  datetime.h date822fmt.h received.h
68 -       ./compile received.c
69 +       ./compile $(LDAPFLAGS) received.c
70  
71  remoteinfo.o: \
72  compile remoteinfo.c byte.h substdio.h ip.h fmt.h timeoutconn.h \
73 @@ -2340,7 +2350,7 @@
74  FILES BLURB BLURB2 BLURB3 BLURB4 README FAQ INSTALL INSTALL.alias \
75  INSTALL.ctl INSTALL.ids INSTALL.maildir INSTALL.mbox INSTALL.vsm \
76  REMOVE.sendmail REMOVE.binmail TEST.deliver TEST.receive UPGRADE \
77 -THOUGHTS TODO THANKS CHANGES SECURITY INTERNALS SENDMAIL \
78 +THOUGHTS TODO THANKS CHANGES SECURITY INTERNALS SENDMAIL README.ENVELOPE_SCAN \
79  PIC.local2alias PIC.local2ext PIC.local2local PIC.local2rem \
80  PIC.local2virt PIC.nullclient PIC.relaybad PIC.relaygood \
81  PIC.rem2local FILES VERSION SYSDEPS TARGETS Makefile BIN.README \
82 @@ -2394,6 +2404,7 @@
83  exit.h timeoutconn.h timeoutconn.c timeoutread.h timeoutread.c \
84  timeoutwrite.h timeoutwrite.c remoteinfo.h remoteinfo.c uint32.h1 \
85  uint32.h2 tryulong32.c wait.3 wait.h wait_pid.c wait_nohang.c \
86 +uint64.h1 uint64.h2 \
87  trywaitp.c sig.h sig_alarm.c sig_block.c sig_catch.c sig_pause.c \
88  sig_pipe.c sig_child.c sig_term.c sig_hup.c sig_misc.c sig_bug.c \
89  trysgact.c trysgprm.c env.3 env.h env.c envread.c byte.h byte_chr.c \
90 @@ -2717,6 +2728,13 @@
91         && cat uint32.h2 || cat uint32.h1 ) > uint32.h
92         rm -f tryulong32.o tryulong32
93  
94 +uint64.h: \
95 +tryulong64.c compile load uint64.h1 uint64.h2
96 +       ( ( ./compile tryulong64.c && ./load tryulong64 && \
97 +       ./tryulong64 ) >/dev/null 2>&1 \
98 +       && cat uint64.h2 || cat uint64.h1 ) > uint64.h
99 +       rm -f tryulong64.o tryulong64
100 +
101  wait.a: \
102  makelib wait_pid.o wait_nohang.o
103         ./makelib wait.a wait_pid.o wait_nohang.o
104 diff -Naur qmail-ldap-1.03-20060201/README.ENVELOPE_SCAN qmail-ldap-envelope-scan-1.0rc3/README.ENVELOPE_SCAN
105 --- qmail-ldap-1.03-20060201/README.ENVELOPE_SCAN       1970-01-01 01:00:00.000000000 +0100
106 +++ qmail-ldap-envelope-scan-1.0rc3/README.ENVELOPE_SCAN        2009-06-26 20:24:02.000000000 +0100
107 @@ -0,0 +1,73 @@
108 +This started as a port of Anton Lundin's (http://www.acc.umu.se/~glance/) qmail envelope scanner
109 +patch with some minor adjustments to provide HELO/EHLO checking.
110 +
111 +Since it has been through quite some changes, not all published since i believe i'm actually the
112 +only one using this, but hey, it works for me. =)
113 +
114 +
115 +What does this patch do?
116 +------------------------
117 +This patch allows qmail-smtpd to call an external program, in two separate occasions to perform
118 +various verifications, and decide weather it should accept, defer or reject the incoming message.
119 +
120 +
121 +How does it do that?
122 +--------------------
123 +The basic principle is to export important information into well defined environment variables.
124 +Then qmail-smtpd just calls a defined program to perform a certain number of checks. The program
125 +should then inform qmail-smtpd of its decision, through the use of exit codes.
126 +Depending on the program exit code, qmail-smtp will then either accept, defer or reject the message.
127 +
128 +
129 +So what information does this patch export?
130 +-------------------------------------------
131 +The exported information includes the following information, in the respective extra variables:
132 +
133 +HELO           Remote server announcement
134 +SENDER         Message sender
135 +RECIPIENT      Recipient
136 +TCPREMOTEHOST  Remote server reverse DNS name
137 +RCPTCOUNT      Number of message recipients
138 +SESSIONID      Unique session ID
139 +SMTPSTATE      Protocol state. Can either be RCPT or END-OF-MESSAGE
140 +TCPREMOTEIP    Remote server IP address
141 +SIZE=5142      Message size. Either the announced ESMTP size or the actual message size, depending
142 +               on the protocol state (RCPT or END-OF-MESSAGE)
143 +AUTH_USER      SMTP-AUTH username of local sender
144 +
145 +
146 +... and how can i used it?
147 +--------------------------
148 +You can use a small program that i made, called qenvscan-policyd. It allows your qmail-smtpd to
149 +talk to an SMTP ACL Policy Daemon, such as policyd, and others. This an extremely powerful way
150 +to manage your Mail infrastructure. Besides Greylisting, you can take advantage of sender/recipient
151 +throttling, with quotas or accounting, message size restritions per user, domain, destination, etc.
152 +Just add something like this to your tcprules file.
153 +
154 +e.g.
155 +       :allow,ENVELOPE_SCANNER="/var/qmail/bin/qenvscan-policyd",POLICYD_SERVER="10.10.10.10",POLICYD_PORT="10031",PSTATE_RCPT="",PSTATE_EOM=""
156 +
157 +The PSTATE_RCPT will make qenvscan-policyd check for sender, authenticated user (if SMTPAUTH was used), recipients, number of recipients, helo, remoteip, ESMTP size and client name at RCPT.
158 +
159 +The PSTATE_EOM will make qenvscan-policyd check for the real message size, just after the completion of the DATA command. This check will share the same instance ID, which will allow this check to be associated with the earlier PSTATE_RCPT check for the same message.
160 +
161 +
162 +No thanks, i don't like that SMTP Policy stuff
163 +----------------------------------------------
164 +Fair enough. You can always write your own program or script to make the checks you want. Just make it grab the
165 +respective env vars, do your magic and make it spit out the following exit codes:
166 +
167 +0              on success, meaning that mail will be accepted
168 +100            on a permanent reject of mail
169 +101            on a temporary fail, which can be used for greylisting
170 +anything else  if there was something wrong in the process.
171 +
172 +In the case of a return value different from 0, 100 or 101, envelope_scanning will be in failsafe mode. This means
173 +qmail-ldap will continue as if there was no external envelope scanning and mail is delivered normally.
174 +
175 +
176 +As always, comments are welcomed.
177 +
178 +Hugo Monteiro <hugo.monteiro@fct.unl.pt>
179 +http://hmonteiro.net
180 +
181 diff -Naur qmail-ldap-1.03-20060201/TARGETS qmail-ldap-envelope-scan-1.0rc3/TARGETS
182 --- qmail-ldap-1.03-20060201/TARGETS    2009-06-26 17:03:56.000000000 +0100
183 +++ qmail-ldap-envelope-scan-1.0rc3/TARGETS     2009-06-26 16:30:29.000000000 +0100
184 @@ -460,3 +460,6 @@
185  readwrite.o
186  smtpcall.o
187  xtext.o
188 +session.o
189 +fmt_uint64.o
190 +uint64.h
191 diff -Naur qmail-ldap-1.03-20060201/fmt_uint64.c qmail-ldap-envelope-scan-1.0rc3/fmt_uint64.c
192 --- qmail-ldap-1.03-20060201/fmt_uint64.c       1970-01-01 01:00:00.000000000 +0100
193 +++ qmail-ldap-envelope-scan-1.0rc3/fmt_uint64.c        2009-06-26 16:30:29.000000000 +0100
194 @@ -0,0 +1,14 @@
195 +#include "fmt.h"
196 +#include "uint64.h"
197 +
198 +unsigned int fmt_uint64(s,u) register char *s; register uint64 u;
199 +{
200 +       register unsigned int len; register uint64 q;
201 +       len = 1; q = u;
202 +       while (q > 9) { ++len; q /= 10; }
203 +       if (s) {
204 +               s += len;
205 +               do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
206 +       }
207 +       return len;
208 +}
209 diff -Naur qmail-ldap-1.03-20060201/hier.c qmail-ldap-envelope-scan-1.0rc3/hier.c
210 --- qmail-ldap-1.03-20060201/hier.c     2009-06-26 17:03:56.000000000 +0100
211 +++ qmail-ldap-envelope-scan-1.0rc3/hier.c      2009-06-26 19:23:06.000000000 +0100
212 @@ -182,6 +182,9 @@
213    c(auto_qmail,"doc","QLDAPPICTURE",auto_uido,auto_gidq,0644);
214    c(auto_qmail,"doc","EXTTODO",auto_uido,auto_gidq,0644);
215    c(auto_qmail,"doc","POPBEFORESMTP",auto_uido,auto_gidq,0644);
216 +#ifdef ENVELOPE_SCAN
217 +  c(auto_qmail,"doc","README.ENVELOPE_SCAN",auto_uido,auto_gidq,0644);
218 +#endif
219  
220    c(auto_qmail,"bin","qmail-queue",auto_uidq,auto_gidq,04711);
221    c(auto_qmail,"bin","qmail-lspawn",auto_uido,auto_gidq,0700);
222 diff -Naur qmail-ldap-1.03-20060201/install-big.c qmail-ldap-envelope-scan-1.0rc3/install-big.c
223 --- qmail-ldap-1.03-20060201/install-big.c      2009-06-26 17:03:56.000000000 +0100
224 +++ qmail-ldap-envelope-scan-1.0rc3/install-big.c       2009-06-26 19:23:40.000000000 +0100
225 @@ -182,6 +182,9 @@
226    c(auto_qmail,"doc","QLDAPPICTURE",auto_uido,auto_gidq,0644);
227    c(auto_qmail,"doc","EXTTODO",auto_uido,auto_gidq,0644);
228    c(auto_qmail,"doc","POPBEFORESMTP",auto_uido,auto_gidq,0644);
229 +#ifdef ENVELOPE_SCAN
230 +  c(auto_qmail,"doc","README.ENVELOPE_SCAN",auto_uido,auto_gidq,0644);
231 +#endif
232  
233    c(auto_qmail,"bin","qmail-queue",auto_uidq,auto_gidq,04711);
234    c(auto_qmail,"bin","qmail-lspawn",auto_uido,auto_gidq,0700);
235 diff -Naur qmail-ldap-1.03-20060201/qmail-smtpd.c qmail-ldap-envelope-scan-1.0rc3/qmail-smtpd.c
236 --- qmail-ldap-1.03-20060201/qmail-smtpd.c      2009-06-26 17:03:56.000000000 +0100
237 +++ qmail-ldap-envelope-scan-1.0rc3/qmail-smtpd.c       2009-06-26 18:54:42.000000000 +0100
238 @@ -22,6 +22,10 @@
239  #include "env.h"
240  #include "now.h"
241  #include "exit.h"
242 +#ifdef ENVELOPE_SCAN
243 +  #include "fork.h"
244 +  #include "wait.h"
245 +#endif
246  #include "rcpthosts.h"
247  #include "rbl.h"
248  #include "timeoutread.h"
249 @@ -45,6 +49,10 @@
250  
251  #define MAXHOPS 100
252  #define MAXLINELEN 10000
253 +#ifdef ENVELOPE_SCAN
254 +#define RCPTSTATE "RCPT"
255 +#define EOMSTATE "END-OF-MESSAGE"
256 +#endif
257  unsigned long databytes = 0;
258  int timeout = 1200;
259  
260 @@ -165,6 +173,10 @@
261  void err_qqt(void) { out("451 qqt failure (#4.3.0)\r\n"); }
262  void err_dns(void) { out("421 DNS temporary failure at return MX check, try again later (#4.3.0)\r\n"); }
263  void err_soft(char *s) { out("451 "); out(s); out("\r\n"); logline2(1,"temporary verify error: ", s); }
264 +#ifdef ENVELOPE_SCAN
265 +void err_tempfail() { out("421 temporary envelope failure (#4.3.0)\r\n"); }
266 +void err_permfail() { out("553 sorry, permanent envelope failure (#5.7.1)\r\n"); }
267 +#endif
268  void err_bmf(void) { out("553 sorry, your mail was administratively denied. (#5.7.1)\r\n"); }
269  void err_bmfunknown(void) { out("553 sorry, your mail from a host ["); out(remoteip); out("] without valid reverse DNS was administratively denied (#5.7.1)\r\n"); }
270  void err_maxrcpt(void) { out("553 sorry, too many recipients (#5.7.1)\r\n"); }
271 @@ -304,6 +316,12 @@
272  #endif
273    char *x, *l;
274    unsigned long u;
275 +#ifdef ENVELOPE_SCAN
276 +  char *remoteport;
277 +  char sessionid[FMT_ULONG];
278 +  unsigned long nremoteport;
279 +  unsigned long long nsessionid;
280 +#endif
281  
282    l = env_get("LOGLEVEL");
283    if (l) { scan_ulong(l,&u); loglevel = u > 4 ? 4 : u; }
284 @@ -419,6 +437,14 @@
285    if (!remotehost) remotehost = "unknown";
286    remoteinfo = env_get("TCPREMOTEINFO");
287  
288 +#ifdef ENVELOPE_SCAN
289 +  remoteport = env_get("TCPREMOTEPORT");
290 +  scan_ulong(remoteport,&nremoteport);
291 +  nsessionid = hash64(remoteip,nremoteport);
292 +  sessionid[fmt_uint64(sessionid, nsessionid)] = 0;
293 +  if (!env_put2("SESSIONID",sessionid)) die_nomem();
294 +#endif
295 +
296    local = env_get("TCPLOCALHOST");
297    if (!local) local = env_get("TCPLOCALIP");
298    if (!local) local = "unknown";
299 @@ -831,7 +857,41 @@
300    return 0;
301  }
302  
303 +#ifdef ENVELOPE_SCAN
304 +int envelope_scanner()
305 +{
306 +  int child;
307 +  int wstat;
308 +  
309 +  if (!env_put2("HELO",helohost.s)) die_nomem();
310 +  char *envelope_scannerarg[] = { env_get("ENVELOPE_SCANNER") , 0};
311 +
312 +  switch(child = vfork()) {
313 +    case -1:
314 +      return 1;
315 +    case 0:
316 +      execv(*envelope_scannerarg,envelope_scannerarg);
317 +      _exit(111);
318 +  }
319 +
320 +  wait_pid(&wstat,child);
321 +  if (wait_crashed(wstat)) {
322 +    return 1;
323 +  }
324  
325 +  switch(wait_exitcode(wstat)) {
326 +    case 100: /* rejected */
327 +      err_permfail();
328 +      return 0;
329 +    case 101: /* greylisted */
330 +      err_tempfail();
331 +      return 0;
332 +    default: /* something wrong happened */
333 +      return 1;
334 +  }
335 +}
336 +#endif
337 +                                                       
338  void smtp_helo(char *arg)
339  {
340    smtp_line("250 ");
341 @@ -882,6 +942,9 @@
342    unsigned int i,j;
343    char *rblname;
344    int bounceflag = 0;
345 +#ifdef ENVELOPE_SCAN
346 +  char *messagesize;
347 +#endif
348  
349    /* address syntax check */
350    if (!addrparse(arg))
351 @@ -915,6 +978,12 @@
352      return;
353    }
354  
355 +#ifdef ENVELOPE_SCAN
356 +  if (!env_put2("SMTPSTATE",RCPTSTATE)) die_nomem();
357 +  messagesize = getparameter(arg, "SIZE");
358 +  if (!env_put2("SIZE",messagesize ? messagesize : "0")) die_nomem();
359 +#endif
360 +
361    /* bad mailfrom check */
362    if (bmfcheck())
363    {
364 @@ -1079,6 +1148,9 @@
365    if (!stralloc_copys(&rcptto,"")) die_nomem();
366    if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
367    if (!stralloc_0(&mailfrom)) die_nomem();
368 +#ifdef ENVELOPE_SCAN
369 +  if (!env_put2("SENDER",mailfrom.s)) die_nomem();
370 +#endif
371    rcptcount = 0;
372    if (loglevel < 4)
373      logline2(2,"mail from: ",mailfrom.s);
374 @@ -1137,6 +1209,18 @@
375    }
376    ++rcptcount;
377  
378 +#ifdef ENVELOPE_SCAN
379 +char recipientcount[FMT_ULONG];
380 +recipientcount[fmt_ulong(recipientcount,rcptcount)] = 0;
381 +
382 +  if (env_get("PSTATE_RCPT")) {
383 +    if (!env_put2("RCPTCOUNT",recipientcount)) die_nomem();
384 +    if (!env_put2("RECIPIENT",addr.s)) die_nomem();
385 +    if (!env_put2("SMTPSTATE",RCPTSTATE)) die_nomem();
386 +    if (env_get("ENVELOPE_SCANNER") && !envelope_scanner()) return;
387 +  }
388 +#endif
389 +
390    /* maximum recipient limit reached */
391    if (maxrcptcount && rcptcount > maxrcptcount) {
392      err_maxrcpt();
393 @@ -1405,6 +1489,10 @@
394  stralloc protocolinfo = {0};
395  #endif
396  
397 +#ifdef ENVELOPE_SCAN
398 +char messagesize[FMT_ULONG];
399 +#endif
400 +
401  void smtp_data(char *arg) {
402    unsigned int hops;
403    unsigned long qp;
404 @@ -1479,6 +1567,15 @@
405    qmail_from(&qqt,mailfrom.s);
406    qmail_put(&qqt,rcptto.s,rcptto.len);
407   
408 +#ifdef ENVELOPE_SCAN
409 +  if (env_get("PSTATE_EOM")) {
410 +    if (!env_put2("SMTPSTATE",EOMSTATE)) die_nomem();
411 +    messagesize[fmt_ulong(messagesize, bytesreceived)] = 0;
412 +    if (!env_put2("SIZE",messagesize));
413 +    if (env_get("ENVELOPE_SCANNER") && !envelope_scanner()) return;
414 +  }
415 +#endif
416 +
417    qqx = qmail_close(&qqt);
418    if (!*qqx) { acceptmessage(qp); return; }
419    if (hops) {
420 @@ -1594,6 +1691,9 @@
421    case '2':
422      flagauthok = 1;
423      remoteinfo = line.s;
424 +#ifdef ENVELOPE_SCAN
425 +    if (!env_put2("AUTH_USER",remoteinfo)) die_nomem();
426 +#endif
427      out(status);
428      logline2(2,"authentication success, user ", remoteinfo);
429      break;
430 diff -Naur qmail-ldap-1.03-20060201/received.c qmail-ldap-envelope-scan-1.0rc3/received.c
431 --- qmail-ldap-1.03-20060201/received.c 2009-06-26 17:03:56.000000000 +0100
432 +++ qmail-ldap-envelope-scan-1.0rc3/received.c  2009-06-26 16:30:29.000000000 +0100
433 @@ -4,6 +4,9 @@
434  #include "datetime.h"
435  #include "date822fmt.h"
436  #include "received.h"
437 +#ifdef ENVELOPE_SCAN
438 +#include "env.h"
439 +#endif
440  
441  static int issafe(ch) char ch;
442  {
443 @@ -54,6 +57,9 @@
444  const char *rcptto;
445  {
446    struct datetime dt;
447 +#ifdef ENVELOPE_SCAN
448 +  char *smtpauthuser;
449 +#endif
450  
451    qmail_puts(qqt,"Received: from ");
452    safeput(qqt,remotehost);
453 @@ -71,6 +77,14 @@
454    safeput(qqt,remoteip);
455    qmail_puts(qqt,"])");
456  
457 +#ifdef ENVELOPE_SCAN
458 +  smtpauthuser = env_get("AUTH_USER");
459 +  if (smtpauthuser) {
460 +    qmail_puts(qqt,"\n           (SMTPAUTH User ");
461 +    safeput(qqt,smtpauthuser);
462 +    qmail_puts(qqt,")");
463 +  }
464 +#endif
465    if (mailfrom) {
466      qmail_puts(qqt,"\n          (envelope-sender <");
467      safeput(qqt,mailfrom);
468 diff -Naur qmail-ldap-1.03-20060201/session.c qmail-ldap-envelope-scan-1.0rc3/session.c
469 --- qmail-ldap-1.03-20060201/session.c  1970-01-01 01:00:00.000000000 +0100
470 +++ qmail-ldap-envelope-scan-1.0rc3/session.c   2009-06-26 16:30:29.000000000 +0100
471 @@ -0,0 +1,20 @@
472 +#include <unistd.h>
473 +#include "session.h"
474 +#include "uint64.h"
475 +
476 +unsigned long long hash64(char *remoteip, unsigned long remoteport)
477 +{
478 +unsigned long long hv = 5381;
479 +int i = 0;
480 +
481 +       /* unique enough */
482 +       hv = ((hv << 5) + hv) ^ (unsigned int)getpid();
483 +       hv = ((hv << 5) + hv) ^ (unsigned int)time(NULL);
484 +       hv = ((hv << 5) + hv) ^ remoteport;
485 +
486 +       while (remoteip[i++]) {
487 +               hv = ((hv << 5) + hv) ^ (unsigned int)*remoteip;
488 +       }
489 +
490 +       return hv;
491 +}
492 diff -Naur qmail-ldap-1.03-20060201/session.h qmail-ldap-envelope-scan-1.0rc3/session.h
493 --- qmail-ldap-1.03-20060201/session.h  1970-01-01 01:00:00.000000000 +0100
494 +++ qmail-ldap-envelope-scan-1.0rc3/session.h   2009-06-26 16:30:29.000000000 +0100
495 @@ -0,0 +1,6 @@
496 +#ifndef SESSION_H
497 +#define SESSION_H
498 +
499 +unsigned long long hash64(char *remoteip, unsigned long remoteport);
500 +
501 +#endif
502 diff -Naur qmail-ldap-1.03-20060201/tryulong64.c qmail-ldap-envelope-scan-1.0rc3/tryulong64.c
503 --- qmail-ldap-1.03-20060201/tryulong64.c       1970-01-01 01:00:00.000000000 +0100
504 +++ qmail-ldap-envelope-scan-1.0rc3/tryulong64.c        2009-06-26 16:30:29.000000000 +0100
505 @@ -0,0 +1,11 @@
506 +int main()
507 +{
508 +  unsigned long u;
509 +  u = 1;
510 +  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
511 +  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
512 +  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
513 +  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
514 +  if (!u) _exit(1);
515 +  _exit(0);
516 +}
517 diff -Naur qmail-ldap-1.03-20060201/uint64.h1 qmail-ldap-envelope-scan-1.0rc3/uint64.h1
518 --- qmail-ldap-1.03-20060201/uint64.h1  1970-01-01 01:00:00.000000000 +0100
519 +++ qmail-ldap-envelope-scan-1.0rc3/uint64.h1   2009-06-26 16:30:29.000000000 +0100
520 @@ -0,0 +1,8 @@
521 +#ifndef UINT64_H
522 +#define UINT64_H
523 +
524 +/* sysdep: -ulong64 */
525 +
526 +typedef unsigned long long uint64;
527 +
528 +#endif
529 diff -Naur qmail-ldap-1.03-20060201/uint64.h2 qmail-ldap-envelope-scan-1.0rc3/uint64.h2
530 --- qmail-ldap-1.03-20060201/uint64.h2  1970-01-01 01:00:00.000000000 +0100
531 +++ qmail-ldap-envelope-scan-1.0rc3/uint64.h2   2009-06-26 16:30:29.000000000 +0100
532 @@ -0,0 +1,8 @@
533 +#ifndef UINT64_H
534 +#define UINT64_H
535 +
536 +/* sysdep: +ulong64 */
537 +
538 +typedef unsigned long uint64;
539 +
540 +#endif