/[smeserver]/rpms/qmail/sme9/netqmail-1.06-tls-20160918-remote.patch
ViewVC logotype

Annotation of /rpms/qmail/sme9/netqmail-1.06-tls-20160918-remote.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Sat Mar 2 03:43:52 2019 UTC (5 years, 8 months ago) by jpp
Branch: MAIN
CVS Tags: qmail-1_03-23_el6_sme, qmail-1_03-24_el6_sme, HEAD
* Fri Mar 01 2019 Jean-Philipe Pialasse <tests@pialasse.com> 1.03-23.sme
- update using last patch for netqmail, only qmail-remote part [SME: 9349]
- add DEBUG flag for the moment to help configuring -DDEBUG=1

1 jpp 1.1 Frederik Vermeulen <qmail-tls akrul inoa.net> 20160918
2     http://inoa.net/qmail-tls/
3    
4     This patch implements RFC 3207 (was RFC 2487) in qmail.
5     This means you can get SSL or TLS encrypted and
6     authenticated SMTP between the MTAs and from MUA to MTA.
7     The code is considered experimental (but has worked for
8     many since its first release on 1999-03-21).
9    
10     Usage: - install OpenSSL-1.0.2 http://www.openssl.org/ or later
11     (any version since 0.9.6 is presumed to work)
12     - apply patch to netqmail-1.06 http://qmail.org/netqmail
13     The patches to qmail-remote.c and qmail-smtpd.c can be applied
14     separately.
15     - provide a server certificate in /var/qmail/control/servercert.pem.
16     "make cert" makes a self-signed certificate.
17     "make cert-req" makes a certificate request.
18     Note: you can add the CA certificate and intermediate
19     certs to the end of servercert.pem.
20     - replace qmail-smtpd and/or qmail-remote binary
21     - verify operation (header information should show
22     something like
23     "Received [..] with (DHE-RSA-AES256-SHA encrypted) SMTP;")
24    
25     Optional: - when DEBUG is defined, some extra TLS info will be logged
26     - qmail-remote will authenticate with the certificate in
27     /var/qmail/control/clientcert.pem. By preference this is
28     the same as servercert.pem, where nsCertType should be
29     == server,client or be a generic certificate (no usage specified).
30     - when a 2048 bit RSA key is provided in /var/qmail/control/rsa2048.pem,
31     this key will be used instead of (slow) on-the-fly generation by
32     qmail-smtpd. Idem for 2048 DH param in control/dh2048.pem.
33     `make tmprsadh` does this.
34     Periodical replacement can be done by crontab:
35     01 01 * * * /var/qmail/bin/update_tmprsadh > /dev/null 2>&1
36     - server authentication:
37     qmail-remote requires authentication from servers for which
38     /var/qmail/control/tlshosts/host.dom.ain.pem exists.
39     The .pem file contains the validating CA certificates.
40     One of the dNSName or the CommonName attributes have to match.
41     WARNING: this option may cause mail to be delayed, bounced,
42     doublebounced, and lost.
43     If /var/qmail/control/tlshosts/exhaustivelist is present,
44     the lists of hosts in /var/qmail/control/tlshosts is
45     an exhaustive list of hosts TLS is tried on.
46     If /var/qmail/control/notlshosts/host.dom.ain is present,
47     no TLS is tried on this host.
48     - client authentication:
49     when relay rules would reject an incoming mail,
50     qmail-smtpd can allow the mail based on a presented cert.
51     Certs are verified against a CA list in
52     /var/qmail/control/clientca.pem (eg. from
53     http://curl.haxx.se/ca/cacert.pem)
54     and the cert email-address has to match a line in
55     /var/qmail/control/tlsclients. This email-address is logged
56     in the headers. CRLs can be provided through
57     /var/qmail/control/clientcrl.pem.
58     - cipher selection:
59     qmail-remote:
60     openssl cipher string (`man ciphers`) read from
61     /var/qmail/control/tlsclientciphers
62     qmail-smtpd:
63     openssl cipher string read from TLSCIPHERS environment variable
64     (can vary based on client IP address e.g.)
65     or if that is not available /var/qmail/control/tlsserverciphers
66     - smtps (deprecated SMTP over TLS via port 465):
67     qmail-remote: when connecting to port 465
68     qmail-smtpd: when SMTPS environment variable is not empty
69    
70     Caveats: - do a `make clean` after patching
71     - binaries dynamically linked with current openssl versions need
72     recompilation when the shared openssl libs are upgraded.
73     - this patch could conflict with other patches (notably those
74     replacing \n with \r\n, which is a bad idea on encrypted links).
75     - some broken servers have a problem with TLSv1 compatibility.
76     Uncomment the line where we set the SSL_OP_NO_TLSv1 option.
77     - needs working /dev/urandom (or EGD for openssl versions >0.9.7)
78     for seeding random number generator.
79     - packagers should make sure that installing without a valid
80     servercert is impossible
81     - when applied in combination with AUTH patch, AUTH patch
82     should be applied first and first part of this patch
83     will fail. This error can be ignored. Packagers should
84     cut the first 12 lines of this patch to make a happy
85     patch
86     - `make tmprsadh` is recommended (or should I say required),
87     otherwise DH generation can be unpredictably slow
88     - some need "-I/usr/kerberos/include" to be added in conf-cc
89    
90     Copyright: GPL
91     Links with OpenSSL
92     Inspiration and code from examples in SSLeay (E. Young
93     <eay@cryptsoft.com> and T. Hudson <tjh@cryptsoft.com>),
94     stunnel (M. Trojnara <mtrojnar@ddc.daewoo.com.pl>),
95     Postfix/TLS (L. Jaenicke <Lutz.Jaenicke@aet.tu-cottbus.de>),
96     modssl (R. Engelschall <rse@engelschall.com>),
97     openssl examples of E. Rescorla <ekr@rtfm.com>.
98    
99     Bug reports: mailto:<qmail-tls akrul inoa.net>
100    
101    
102     >----< Cut the next 12 lines if applying over AUTH server patch >---<
103     --- qmail-1.03/qmail-smtpd.c Mon Jun 15 03:53:16 1998
104     +++ qmail-1.03-tls/qmail-smtpd.c Tue Jun 18 09:49:38 2002
105     @@ -229,7 +229,8 @@
106     }
107     void smtp_ehlo(arg) char *arg;
108     {
109     - smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
110     + smtp_greet("250-");
111     + out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
112     seenmail = 0; dohelo(arg);
113     }
114     void smtp_rset()
115     >----< Cut previous 12 lines if applying over AUTH server patch >---<
116    
117    
118    
119     >----< The next 89 lines are the qmail-remote EHLO patch >---<
120     --- qmail-1.03/qmail-remote.c Mon Jun 15 03:53:16 1998
121     +++ qmail-1.03-tls/qmail-remote.c Sun Nov 24 13:05:20 2002
122     @@ -163,6 +163,59 @@ unsigned long smtpcode()
123     return code;
124     }
125    
126     +#ifdef EHLO
127     +saa ehlokw = {0}; /* list of EHLO keywords and parameters */
128     +int maxehlokwlen = 0;
129     +
130     +unsigned long ehlo()
131     +{
132     + stralloc *sa;
133     + char *s, *e, *p;
134     + unsigned long code;
135     +
136     + if (ehlokw.len > maxehlokwlen) maxehlokwlen = ehlokw.len;
137     + ehlokw.len = 0;
138     +
139     +# ifdef MXPS
140     + if (type == 's') return 0;
141     +# endif
142     +
143     + substdio_puts(&smtpto, "EHLO ");
144     + substdio_put(&smtpto, helohost.s, helohost.len);
145     + substdio_puts(&smtpto, "\r\n");
146     + substdio_flush(&smtpto);
147     +
148     + code = smtpcode();
149     + if (code != 250) return code;
150     +
151     + s = smtptext.s;
152     + while (*s++ != '\n') ; /* skip the first line: contains the domain */
153     +
154     + e = smtptext.s + smtptext.len - 6; /* 250-?\n */
155     + while (s <= e)
156     + {
157     + if (!saa_readyplus(&ehlokw, 1)) temp_nomem();
158     + sa = ehlokw.sa + ehlokw.len++;
159     + if (ehlokw.len > maxehlokwlen) *sa = sauninit; else sa->len = 0;
160     +
161     + /* smtptext is known to end in a '\n' */
162     + for (p = (s += 4); ; ++p)
163     + if (*p == '\n' || *p == ' ' || *p == '\t') {
164     + if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem();
165     + if (*p++ == '\n') break;
166     + while (*p == ' ' || *p == '\t') ;
167     + s = p;
168     + }
169     + s = p;
170     + /* keyword should consist of alpha-num and '-'
171     + * broken AUTH might use '=' instead of space */
172     + for (p = sa->s; *p; ++p) if (*p == '=') { *p = 0; break; }
173     + }
174     +
175     + return 250;
176     +}
177     +#endif
178     +
179     void outsmtptext()
180     {
181     int i;
182     @@ -224,12 +277,26 @@ void smtp()
183    
184     if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
185    
186     +#ifdef EHLO
187     + code = ehlo();
188     +
189     + if (code == 250) {
190     + /* add EHLO response checks here */
191     +
192     + /* and if EHLO failed, use HELO */
193     + } else {
194     +#endif
195     +
196     substdio_puts(&smtpto,"HELO ");
197     substdio_put(&smtpto,helohost.s,helohost.len);
198     substdio_puts(&smtpto,"\r\n");
199     substdio_flush(&smtpto);
200     if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
201    
202     +#ifdef EHLO
203     + }
204     +#endif
205     +
206     substdio_puts(&smtpto,"MAIL FROM:<");
207     substdio_put(&smtpto,sender.s,sender.len);
208     substdio_puts(&smtpto,">\r\n");
209     >----< Previous 89 lines are the qmail-remote EHLO patch >---<
210    
211    
212    
213     --- netqmail-1.06-orig/qmail-remote.c 2016-09-18 10:04:24.690101666 +0000
214     +++ netqmail-1.06/qmail-remote.c 2016-09-18 09:49:43.206842686 +0000
215     @@ -48,6 +48,17 @@ saa reciplist = {0};
216    
217     struct ip_address partner;
218    
219     +#ifdef TLS
220     +# include <sys/stat.h>
221     +# include "tls.h"
222     +# include "ssl_timeoutio.h"
223     +# include <openssl/x509v3.h>
224     +# define EHLO 1
225     +
226     +int tls_init();
227     +const char *ssl_err_str = 0;
228     +#endif
229     +
230     void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); }
231     void zero() { if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); }
232     void zerodie() { zero(); substdio_flush(subfdoutsmall); _exit(0); }
233     @@ -99,6 +110,9 @@ void dropped() {
234     outhost();
235     out(" but connection died. ");
236     if (flagcritical) out("Possible duplicate! ");
237     +#ifdef TLS
238     + if (ssl_err_str) { out(ssl_err_str); out(" "); }
239     +#endif
240     out("(#4.4.2)\n");
241     zerodie();
242     }
243     @@ -110,6 +124,12 @@ int timeout = 1200;
244     int saferead(fd,buf,len) int fd; char *buf; int len;
245     {
246     int r;
247     +#ifdef TLS
248     + if (ssl) {
249     + r = ssl_timeoutread(timeout, smtpfd, smtpfd, ssl, buf, len);
250     + if (r < 0) ssl_err_str = ssl_error_str();
251     + } else
252     +#endif
253     r = timeoutread(timeout,smtpfd,buf,len);
254     if (r <= 0) dropped();
255     return r;
256     @@ -117,6 +137,12 @@ int saferead(fd,buf,len) int fd; char *b
257     int safewrite(fd,buf,len) int fd; char *buf; int len;
258     {
259     int r;
260     +#ifdef TLS
261     + if (ssl) {
262     + r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len);
263     + if (r < 0) ssl_err_str = ssl_error_str();
264     + } else
265     +#endif
266     r = timeoutwrite(timeout,smtpfd,buf,len);
267     if (r <= 0) dropped();
268     return r;
269     @@ -194,19 +220,25 @@ unsigned long ehlo()
270     e = smtptext.s + smtptext.len - 6; /* 250-?\n */
271     while (s <= e)
272     {
273     + int wasspace = 0;
274     +
275     if (!saa_readyplus(&ehlokw, 1)) temp_nomem();
276     sa = ehlokw.sa + ehlokw.len++;
277     if (ehlokw.len > maxehlokwlen) *sa = sauninit; else sa->len = 0;
278    
279     - /* smtptext is known to end in a '\n' */
280     - for (p = (s += 4); ; ++p)
281     - if (*p == '\n' || *p == ' ' || *p == '\t') {
282     - if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem();
283     - if (*p++ == '\n') break;
284     - while (*p == ' ' || *p == '\t') ;
285     - s = p;
286     - }
287     - s = p;
288     + /* smtptext is known to end in a '\n' */
289     + for (p = (s += 4); ; ++p)
290     + if (*p == '\n' || *p == ' ' || *p == '\t') {
291     + if (!wasspace)
292     + if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem();
293     + if (*p == '\n') break;
294     + wasspace = 1;
295     + } else if (wasspace == 1) {
296     + wasspace = 0;
297     + s = p;
298     + }
299     + s = ++p;
300     +
301     /* keyword should consist of alpha-num and '-'
302     * broken AUTH might use '=' instead of space */
303     for (p = sa->s; *p; ++p) if (*p == '=') { *p = 0; break; }
304     @@ -232,6 +264,11 @@ void quit(prepend,append)
305     char *prepend;
306     char *append;
307     {
308     +#ifdef TLS
309     + /* shouldn't talk to the client unless in an appropriate state */
310     + int state = ssl ? ssl->state : SSL_ST_BEFORE;
311     + if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE))
312     +#endif
313     substdio_putsflush(&smtpto,"QUIT\r\n");
314     /* waiting for remote side is just too ridiculous */
315     out(prepend);
316     @@ -239,6 +276,30 @@ char *append;
317     out(append);
318     out(".\n");
319     outsmtptext();
320     +
321     +#if defined(TLS) && defined(DEBUG)
322     + if (ssl) {
323     + X509 *peercert;
324     +
325     + out("STARTTLS proto="); out(SSL_get_version(ssl));
326     + out("; cipher="); out(SSL_get_cipher(ssl));
327     +
328     + /* we want certificate details */
329     + if (peercert = SSL_get_peer_certificate(ssl)) {
330     + char *str;
331     +
332     + str = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0);
333     + out("; subject="); out(str); OPENSSL_free(str);
334     +
335     + str = X509_NAME_oneline(X509_get_issuer_name(peercert), NULL, 0);
336     + out("; issuer="); out(str); OPENSSL_free(str);
337     +
338     + X509_free(peercert);
339     + }
340     + out(";\n");
341     + }
342     +#endif
343     +
344     zerodie();
345     }
346    
347     @@ -267,6 +328,206 @@ void blast()
348     substdio_flush(&smtpto);
349     }
350    
351     +#ifdef TLS
352     +char *partner_fqdn = 0;
353     +
354     +# define TLS_QUIT quit(ssl ? "; connected to " : "; connecting to ", "")
355     +void tls_quit(const char *s1, const char *s2)
356     +{
357     + out(s1); if (s2) { out(": "); out(s2); } TLS_QUIT;
358     +}
359     +# define tls_quit_error(s) tls_quit(s, ssl_error())
360     +
361     +int match_partner(const char *s, int len)
362     +{
363     + if (!case_diffb(partner_fqdn, len, s) && !partner_fqdn[len]) return 1;
364     + /* we also match if the name is *.domainname */
365     + if (*s == '*') {
366     + const char *domain = partner_fqdn + str_chr(partner_fqdn, '.');
367     + if (!case_diffb(domain, --len, ++s) && !domain[len]) return 1;
368     + }
369     + return 0;
370     +}
371     +
372     +/* don't want to fail handshake if certificate can't be verified */
373     +int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
374     +
375     +int tls_init()
376     +{
377     + int i;
378     + SSL *myssl;
379     + SSL_CTX *ctx;
380     + stralloc saciphers = {0};
381     + const char *ciphers, *servercert = 0;
382     +
383     + if (partner_fqdn) {
384     + struct stat st;
385     + stralloc tmp = {0};
386     + if (!stralloc_copys(&tmp, "control/tlshosts/")
387     + || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn))
388     + || !stralloc_catb(&tmp, ".pem", 5)) temp_nomem();
389     + if (stat(tmp.s, &st) == 0)
390     + servercert = tmp.s;
391     + else {
392     + if (!stralloc_copys(&tmp, "control/notlshosts/")
393     + || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)+1))
394     + temp_nomem();
395     + if ((stat("control/tlshosts/exhaustivelist", &st) == 0) ||
396     + (stat(tmp.s, &st) == 0)) {
397     + alloc_free(tmp.s);
398     + return 0;
399     + }
400     + alloc_free(tmp.s);
401     + }
402     + }
403     +
404     + if (!smtps) {
405     + stralloc *sa = ehlokw.sa;
406     + unsigned int len = ehlokw.len;
407     + /* look for STARTTLS among EHLO keywords */
408     + for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ;
409     + if (!len) {
410     + if (!servercert) return 0;
411     + out("ZNo TLS achieved while "); out(servercert);
412     + out(" exists"); smtptext.len = 0; TLS_QUIT;
413     + }
414     + }
415     +
416     + SSL_library_init();
417     + ctx = SSL_CTX_new(SSLv23_client_method());
418     + if (!ctx) {
419     + if (!smtps && !servercert) return 0;
420     + smtptext.len = 0;
421     + tls_quit_error("ZTLS error initializing ctx");
422     + }
423     +
424     + /* POODLE vulnerability */
425     + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
426     +
427     + if (servercert) {
428     + if (!SSL_CTX_load_verify_locations(ctx, servercert, NULL)) {
429     + SSL_CTX_free(ctx);
430     + smtptext.len = 0;
431     + out("ZTLS unable to load "); tls_quit_error(servercert);
432     + }
433     + /* set the callback here; SSL_set_verify didn't work before 0.9.6c */
434     + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
435     + }
436     +
437     + /* let the other side complain if it needs a cert and we don't have one */
438     +# define CLIENTCERT "control/clientcert.pem"
439     + if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT))
440     + SSL_CTX_use_RSAPrivateKey_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM);
441     +# undef CLIENTCERT
442     +
443     + myssl = SSL_new(ctx);
444     + SSL_CTX_free(ctx);
445     + if (!myssl) {
446     + if (!smtps && !servercert) return 0;
447     + smtptext.len = 0;
448     + tls_quit_error("ZTLS error initializing ssl");
449     + }
450     +
451     + if (!smtps) substdio_putsflush(&smtpto, "STARTTLS\r\n");
452     +
453     + /* while the server is preparing a response, do something else */
454     + if (control_readfile(&saciphers, "control/tlsclientciphers", 0) == -1)
455     + { SSL_free(myssl); temp_control(); }
456     + if (saciphers.len) {
457     + for (i = 0; i < saciphers.len - 1; ++i)
458     + if (!saciphers.s[i]) saciphers.s[i] = ':';
459     + ciphers = saciphers.s;
460     + }
461     + else ciphers = "DEFAULT";
462     + SSL_set_cipher_list(myssl, ciphers);
463     + alloc_free(saciphers.s);
464     +
465     + SSL_set_fd(myssl, smtpfd);
466     +
467     + /* read the response to STARTTLS */
468     + if (!smtps) {
469     + if (smtpcode() != 220) {
470     + SSL_free(myssl);
471     + if (!servercert) return 0;
472     + out("ZSTARTTLS rejected while ");
473     + out(servercert); out(" exists"); TLS_QUIT;
474     + }
475     + smtptext.len = 0;
476     + }
477     +
478     + ssl = myssl;
479     + if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0)
480     + tls_quit("ZTLS connect failed", ssl_error_str());
481     +
482     + if (servercert) {
483     + X509 *peercert;
484     + STACK_OF(GENERAL_NAME) *gens;
485     + int found_gen_dns = 0;
486     + int matched_gen_dns = 0;
487     +
488     + int r = SSL_get_verify_result(ssl);
489     + if (r != X509_V_OK) {
490     + out("ZTLS unable to verify server with ");
491     + tls_quit(servercert, X509_verify_cert_error_string(r));
492     + }
493     + alloc_free(servercert);
494     +
495     + peercert = SSL_get_peer_certificate(ssl);
496     + if (!peercert) {
497     + out("ZTLS unable to verify server ");
498     + tls_quit(partner_fqdn, "no certificate provided");
499     + }
500     +
501     + /* RFC 2595 section 2.4: find a matching name
502     + * first find a match among alternative names */
503     + gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0);
504     + if (gens) {
505     + for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i)
506     + {
507     + const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
508     + if (gn->type == GEN_DNS){
509     + found_gen_dns = 1;
510     + if (match_partner(gn->d.ia5->data, gn->d.ia5->length)){
511     + matched_gen_dns = 1;
512     + break;
513     + }
514     + }
515     + }
516     + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
517     + }
518     +
519     + /* no SubjectAltName of type DNS found, look up commonName */
520     + if (!found_gen_dns) {
521     + stralloc peer = {0};
522     + X509_NAME *subj = X509_get_subject_name(peercert);
523     + i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
524     + if (i >= 0) {
525     + const ASN1_STRING *s = X509_NAME_get_entry(subj, i)->value;
526     + if (s) { peer.len = s->length; peer.s = s->data; }
527     + }
528     + if (peer.len <= 0) {
529     + out("ZTLS unable to verify server ");
530     + tls_quit(partner_fqdn, "certificate contains no valid commonName");
531     + }
532     + if (!match_partner(peer.s, peer.len)) {
533     + out("ZTLS unable to verify server "); out(partner_fqdn);
534     + out(": received certificate for "); outsafe(&peer); TLS_QUIT;
535     + }
536     + } else if (!matched_gen_dns) {
537     + out("ZTLS unable to verify server ");
538     + tls_quit(partner_fqdn, "certificate contains no matching dNSNnames");
539     + }
540     +
541     + X509_free(peercert);
542     + }
543     +
544     + if (smtps) if (smtpcode() != 220)
545     + quit("ZTLS Connected to "," but greeting failed");
546     +
547     + return 1;
548     +}
549     +#endif
550     +
551     stralloc recip = {0};
552    
553     void smtp()
554     @@ -274,12 +535,37 @@ void smtp()
555     unsigned long code;
556     int flagbother;
557     int i;
558     +
559     +#ifndef PORT_SMTP
560     + /* the qmtpc patch uses smtp_port and undefines PORT_SMTP */
561     +# define port smtp_port
562     +#endif
563     +
564     +#ifdef TLS
565     +# ifdef MXPS
566     + if (type == 'S') smtps = 1;
567     + else if (type != 's')
568     +# endif
569     + if (port == 465) smtps = 1;
570     + if (!smtps)
571     +#endif
572    
573     if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
574    
575     #ifdef EHLO
576     +# ifdef TLS
577     + if (!smtps)
578     +# endif
579     code = ehlo();
580    
581     +# ifdef TLS
582     + if (tls_init())
583     + /* RFC2487 says we should issue EHLO (even if we might not need
584     + * extensions); at the same time, it does not prohibit a server
585     + * to reject the EHLO and make us fallback to HELO */
586     + code = ehlo();
587     +# endif
588     +
589     if (code == 250) {
590     /* add EHLO response checks here */
591    
592     @@ -484,6 +770,9 @@ char **argv;
593     if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) {
594     tcpto_err(&ip.ix[i].ip,0);
595     partner = ip.ix[i].ip;
596     +#ifdef TLS
597     + partner_fqdn = ip.ix[i].fqdn;
598     +#endif
599     smtp(); /* does not return */
600     }
601     tcpto_err(&ip.ix[i].ip,errno == error_timeout);
602     --- netqmail-1.06-orig/qmail-remote.8 1998-06-15 10:53:16.000000000 +0000
603     +++ netqmail-1.06/qmail-remote.8 2015-12-01 15:54:59.029940779 +0000
604     @@ -114,6 +114,10 @@ arguments.
605     always exits zero.
606     .SH "CONTROL FILES"
607     .TP 5
608     +.I clientcert.pem
609     +SSL certificate that is used to authenticate with the remote server
610     +during a TLS session.
611     +.TP 5
612     .I helohost
613     Current host name,
614     for use solely in saying hello to the remote SMTP server.
615     @@ -123,6 +127,16 @@ if that is supplied;
616     otherwise
617     .B qmail-remote
618     refuses to run.
619     +
620     +.TP 5
621     +.I notlshosts/<FQDN>
622     +.B qmail-remote
623     +will not try TLS on servers for which this file exists
624     +.RB ( <FQDN>
625     +is the fully-qualified domain name of the server).
626     +.IR (tlshosts/<FQDN>.pem
627     +takes precedence over this file however).
628     +
629     .TP 5
630     .I smtproutes
631     Artificial SMTP routes.
632     @@ -156,6 +170,8 @@ may be empty;
633     this tells
634     .B qmail-remote
635     to look up MX records as usual.
636     +.I port
637     +value of 465 (deprecated smtps port) causes TLS session to be started.
638     .I smtproutes
639     may include wildcards:
640    
641     @@ -195,6 +211,33 @@ Number of seconds
642     .B qmail-remote
643     will wait for each response from the remote SMTP server.
644     Default: 1200.
645     +
646     +.TP 5
647     +.I tlsclientciphers
648     +A set of OpenSSL client cipher strings. Multiple ciphers
649     +contained in a string should be separated by a colon.
650     +
651     +.TP 5
652     +.I tlshosts/<FQDN>.pem
653     +.B qmail-remote
654     +requires TLS authentication from servers for which this file exists
655     +.RB ( <FQDN>
656     +is the fully-qualified domain name of the server). One of the
657     +.I dNSName
658     +or the
659     +.I CommonName
660     +attributes have to match. The file contains the trusted CA certificates.
661     +
662     +.B WARNING:
663     +this option may cause mail to be delayed, bounced, doublebounced, or lost.
664     +
665     +.TP 5
666     +.I tlshosts/exhaustivelist
667     +if this file exists
668     +no TLS will be tried on hosts other than those for which a file
669     +.B tlshosts/<FQDN>.pem
670     +exists.
671     +
672     .SH "SEE ALSO"
673     addresses(5),
674     envelopes(5),
675     --- netqmail-1.06-orig/qmail-control.9 1998-06-15 10:53:16.000000000 +0000
676     +++ netqmail-1.06/qmail-control.9 2015-12-08 00:33:06.248714330 +0000
677     @@ -43,11 +43,14 @@ control default used by
678     .I badmailfrom \fR(none) \fRqmail-smtpd
679     .I bouncefrom \fRMAILER-DAEMON \fRqmail-send
680     .I bouncehost \fIme \fRqmail-send
681     +.I clientca.pem \fR(none) \fRqmail-smtpd
682     +.I clientcert.pem \fR(none) \fRqmail-remote
683     .I concurrencylocal \fR10 \fRqmail-send
684     .I concurrencyremote \fR20 \fRqmail-send
685     .I defaultdomain \fIme \fRqmail-inject
686     .I defaulthost \fIme \fRqmail-inject
687     .I databytes \fR0 \fRqmail-smtpd
688     +.I dh2048.pem \fR(none) \fRqmail-smtpd
689     .I doublebouncehost \fIme \fRqmail-send
690     .I doublebounceto \fRpostmaster \fRqmail-send
691     .I envnoathost \fIme \fRqmail-send
692     @@ -61,11 +64,17 @@ control default used by
693     .I qmqpservers \fR(none) \fRqmail-qmqpc
694     .I queuelifetime \fR604800 \fRqmail-send
695     .I rcpthosts \fR(none) \fRqmail-smtpd
696     +.I rsa2048.pem \fR(none) \fRqmail-smtpd
697     +.I servercert.pem \fR(none) \fRqmail-smtpd
698     .I smtpgreeting \fIme \fRqmail-smtpd
699     .I smtproutes \fR(none) \fRqmail-remote
700     .I timeoutconnect \fR60 \fRqmail-remote
701     .I timeoutremote \fR1200 \fRqmail-remote
702     .I timeoutsmtpd \fR1200 \fRqmail-smtpd
703     +.I tlsclients \fR(none) \fRqmail-smtpd
704     +.I tlsclientciphers \fR(none) \fRqmail-remote
705     +.I tlshosts/FQDN.pem \fR(none) \fRqmail-remote
706     +.I tlsserverciphers \fR(none) \fRqmail-smtpd
707     .I virtualdomains \fR(none) \fRqmail-send
708     .fi
709     .RE
710     --- netqmail-1.06-orig/dns.c 2007-11-30 20:22:54.000000000 +0000
711     +++ netqmail-1.06/dns.c 2015-12-01 15:54:59.033940812 +0000
712     @@ -267,12 +267,11 @@ stralloc *sa;
713     int pref;
714     {
715     int r;
716     - struct ip_mx ix;
717     + struct ip_mx ix = {0};
718    
719     if (!stralloc_copy(&glue,sa)) return DNS_MEM;
720     if (!stralloc_0(&glue)) return DNS_MEM;
721     if (glue.s[0]) {
722     - ix.pref = 0;
723     if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)])
724     {
725     if (!ipalloc_append(ia,&ix)) return DNS_MEM;
726     @@ -291,9 +290,16 @@ int pref;
727     ix.ip = ip;
728     ix.pref = pref;
729     if (r == DNS_SOFT) return DNS_SOFT;
730     - if (r == 1)
731     + if (r == 1) {
732     +#ifdef IX_FQDN
733     + ix.fqdn = glue.s;
734     +#endif
735     if (!ipalloc_append(ia,&ix)) return DNS_MEM;
736     }
737     + }
738     +#ifdef IX_FQDN
739     + glue.s = 0;
740     +#endif
741     return 0;
742     }
743    
744     @@ -313,7 +319,7 @@ unsigned long random;
745     {
746     int r;
747     struct mx { stralloc sa; unsigned short p; } *mx;
748     - struct ip_mx ix;
749     + struct ip_mx ix = {0};
750     int nummx;
751     int i;
752     int j;
753     @@ -325,7 +331,6 @@ unsigned long random;
754     if (!stralloc_copy(&glue,sa)) return DNS_MEM;
755     if (!stralloc_0(&glue)) return DNS_MEM;
756     if (glue.s[0]) {
757     - ix.pref = 0;
758     if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)])
759     {
760     if (!ipalloc_append(ia,&ix)) return DNS_MEM;
761     --- netqmail-1.06-orig/hier.c 1998-06-15 10:53:16.000000000 +0000
762     +++ netqmail-1.06/hier.c 2015-12-01 15:54:59.033940812 +0000
763     @@ -143,6 +143,9 @@ void hier()
764     c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755);
765     c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755);
766     c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755);
767     +#ifdef TLS
768     + c(auto_qmail,"bin","update_tmprsadh",auto_uido,auto_gidq,0755);
769     +#endif
770    
771     c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644);
772     c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644);
773     --- netqmail-1.06-orig/ipalloc.h 1998-06-15 10:53:16.000000000 +0000
774     +++ netqmail-1.06/ipalloc.h 2015-12-01 15:54:59.033940812 +0000
775     @@ -3,7 +3,15 @@
776    
777     #include "ip.h"
778    
779     +#ifdef TLS
780     +# define IX_FQDN 1
781     +#endif
782     +
783     +#ifdef IX_FQDN
784     +struct ip_mx { struct ip_address ip; int pref; char *fqdn; } ;
785     +#else
786     struct ip_mx { struct ip_address ip; int pref; } ;
787     +#endif
788    
789     #include "gen_alloc.h"
790    
791     --- netqmail-1.06-orig/tls.c 2016-09-18 10:04:24.698101731 +0000
792     +++ netqmail-1.06/tls.c 2015-12-01 15:54:59.033940812 +0000
793     @@ -0,0 +1,25 @@
794     +#include "exit.h"
795     +#include "error.h"
796     +#include <openssl/ssl.h>
797     +#include <openssl/err.h>
798     +
799     +int smtps = 0;
800     +SSL *ssl = NULL;
801     +
802     +void ssl_free(SSL *myssl) { SSL_shutdown(myssl); SSL_free(myssl); }
803     +void ssl_exit(int status) { if (ssl) ssl_free(ssl); _exit(status); }
804     +
805     +const char *ssl_error()
806     +{
807     + int r = ERR_get_error();
808     + if (!r) return NULL;
809     + SSL_load_error_strings();
810     + return ERR_error_string(r, NULL);
811     +}
812     +const char *ssl_error_str()
813     +{
814     + const char *err = ssl_error();
815     + if (err) return err;
816     + if (!errno) return 0;
817     + return (errno == error_timeout) ? "timed out" : error_str(errno);
818     +}
819     --- netqmail-1.06-orig/tls.h 2016-09-18 10:04:24.698101731 +0000
820     +++ netqmail-1.06/tls.h 2015-12-01 15:54:59.033940812 +0000
821     @@ -0,0 +1,16 @@
822     +#ifndef TLS_H
823     +#define TLS_H
824     +
825     +#include <openssl/ssl.h>
826     +
827     +extern int smtps;
828     +extern SSL *ssl;
829     +
830     +void ssl_free(SSL *myssl);
831     +void ssl_exit(int status);
832     +# define _exit ssl_exit
833     +
834     +const char *ssl_error();
835     +const char *ssl_error_str();
836     +
837     +#endif
838     --- netqmail-1.06-orig/ssl_timeoutio.c 2016-09-18 10:04:24.698101731 +0000
839     +++ netqmail-1.06/ssl_timeoutio.c 2015-12-01 15:54:59.033940812 +0000
840     @@ -0,0 +1,95 @@
841     +#include "select.h"
842     +#include "error.h"
843     +#include "ndelay.h"
844     +#include "now.h"
845     +#include "ssl_timeoutio.h"
846     +
847     +int ssl_timeoutio(int (*fun)(),
848     + int t, int rfd, int wfd, SSL *ssl, char *buf, int len)
849     +{
850     + int n;
851     + const datetime_sec end = (datetime_sec)t + now();
852     +
853     + do {
854     + fd_set fds;
855     + struct timeval tv;
856     +
857     + const int r = buf ? fun(ssl, buf, len) : fun(ssl);
858     + if (r > 0) return r;
859     +
860     + t = end - now();
861     + if (t < 0) break;
862     + tv.tv_sec = (time_t)t; tv.tv_usec = 0;
863     +
864     + FD_ZERO(&fds);
865     + switch (SSL_get_error(ssl, r))
866     + {
867     + default: return r; /* some other error */
868     + case SSL_ERROR_WANT_READ:
869     + FD_SET(rfd, &fds); n = select(rfd + 1, &fds, NULL, NULL, &tv);
870     + break;
871     + case SSL_ERROR_WANT_WRITE:
872     + FD_SET(wfd, &fds); n = select(wfd + 1, NULL, &fds, NULL, &tv);
873     + break;
874     + }
875     +
876     + /* n is the number of descriptors that changed status */
877     + } while (n > 0);
878     +
879     + if (n != -1) errno = error_timeout;
880     + return -1;
881     +}
882     +
883     +int ssl_timeoutaccept(int t, int rfd, int wfd, SSL *ssl)
884     +{
885     + int r;
886     +
887     + /* if connection is established, keep NDELAY */
888     + if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1;
889     + r = ssl_timeoutio(SSL_accept, t, rfd, wfd, ssl, NULL, 0);
890     +
891     + if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); }
892     + else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
893     +
894     + return r;
895     +}
896     +
897     +int ssl_timeoutconn(int t, int rfd, int wfd, SSL *ssl)
898     +{
899     + int r;
900     +
901     + /* if connection is established, keep NDELAY */
902     + if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1;
903     + r = ssl_timeoutio(SSL_connect, t, rfd, wfd, ssl, NULL, 0);
904     +
905     + if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); }
906     + else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
907     +
908     + return r;
909     +}
910     +
911     +int ssl_timeoutrehandshake(int t, int rfd, int wfd, SSL *ssl)
912     +{
913     + int r;
914     +
915     + SSL_renegotiate(ssl);
916     + r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
917     + if (r <= 0 || ssl->type == SSL_ST_CONNECT) return r;
918     +
919     + /* this is for the server only */
920     + ssl->state = SSL_ST_ACCEPT;
921     + return ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
922     +}
923     +
924     +int ssl_timeoutread(int t, int rfd, int wfd, SSL *ssl, char *buf, int len)
925     +{
926     + if (!buf) return 0;
927     + if (SSL_pending(ssl)) return SSL_read(ssl, buf, len);
928     + return ssl_timeoutio(SSL_read, t, rfd, wfd, ssl, buf, len);
929     +}
930     +
931     +int ssl_timeoutwrite(int t, int rfd, int wfd, SSL *ssl, char *buf, int len)
932     +{
933     + if (!buf) return 0;
934     + return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len);
935     +}
936     --- netqmail-1.06-orig/ssl_timeoutio.h 2016-09-18 10:04:24.698101731 +0000
937     +++ netqmail-1.06/ssl_timeoutio.h 2015-12-01 15:54:59.033940812 +0000
938     @@ -0,0 +1,21 @@
939     +#ifndef SSL_TIMEOUTIO_H
940     +#define SSL_TIMEOUTIO_H
941     +
942     +#include <openssl/ssl.h>
943     +
944     +/* the version is like this: 0xMNNFFPPS: major minor fix patch status */
945     +#if OPENSSL_VERSION_NUMBER < 0x00906000L
946     +# error "Need OpenSSL version at least 0.9.6"
947     +#endif
948     +
949     +int ssl_timeoutconn(int t, int rfd, int wfd, SSL *ssl);
950     +int ssl_timeoutaccept(int t, int rfd, int wfd, SSL *ssl);
951     +int ssl_timeoutrehandshake(int t, int rfd, int wfd, SSL *ssl);
952     +
953     +int ssl_timeoutread(int t, int rfd, int wfd, SSL *ssl, char *buf, int len);
954     +int ssl_timeoutwrite(int t, int rfd, int wfd, SSL *ssl, char *buf, int len);
955     +
956     +int ssl_timeoutio(
957     + int (*fun)(), int t, int rfd, int wfd, SSL *ssl, char *buf, int len);
958     +
959     +#endif
960     --- netqmail-1.06-orig/TARGETS 1998-06-15 10:53:16.000000000 +0000
961     +++ netqmail-1.06/TARGETS 2015-12-01 15:54:59.033940812 +0000
962     @@ -168,6 +168,8 @@ control.o
963     constmap.o
964     timeoutread.o
965     timeoutwrite.o
966     +tls.o
967     +ssl_timeoutio.o
968     timeoutconn.o
969     tcpto.o
970     dns.o
971     @@ -320,6 +322,7 @@ binm2
972     binm2+df
973     binm3
974     binm3+df
975     +Makefile-cert
976     it
977     qmail-local.0
978     qmail-lspawn.0
979     @@ -385,3 +388,4 @@ forgeries.0
980     man
981     setup
982     check
983     +update_tmprsadh
984     --- netqmail-1.06-orig/Makefile-cert.mk 2016-09-18 10:04:24.698101731 +0000
985     +++ netqmail-1.06/Makefile-cert.mk 2015-12-01 15:54:59.033940812 +0000
986     @@ -0,0 +1,21 @@
987     +cert-req: req.pem
988     +cert cert-req: QMAIL/control/clientcert.pem
989     + @:
990     +
991     +QMAIL/control/clientcert.pem: QMAIL/control/servercert.pem
992     + ln -s $< $@
993     +
994     +QMAIL/control/servercert.pem:
995     + PATH=$$PATH:/usr/local/ssl/bin \
996     + openssl req -new -x509 -nodes -days 366 -out $@ -keyout $@
997     + chmod 640 $@
998     + chown `head -2 conf-users | tail -1`:`head -1 conf-groups` $@
999     +
1000     +req.pem:
1001     + PATH=$$PATH:/usr/local/ssl/bin openssl req \
1002     + -new -nodes -out $@ -keyout QMAIL/control/servercert.pem
1003     + chmod 640 QMAIL/control/servercert.pem
1004     + chown `head -2 conf-users | tail -1`:`head -1 conf-groups` QMAIL/control/servercert.pem
1005     + @echo
1006     + @echo "Send req.pem to your CA to obtain signed_req.pem, and do:"
1007     + @echo "cat signed_req.pem >> QMAIL/control/servercert.pem"
1008     --- netqmail-1.06-orig/conf-cc 1998-06-15 10:53:16.000000000 +0000
1009     +++ netqmail-1.06/conf-cc 2015-12-08 00:59:12.688312582 +0000
1010     @@ -1,3 +1,3 @@
1011     -cc -O2
1012     +cc -O2 -DTLS=20160918 -I/usr/local/ssl/include
1013    
1014     This will be used to compile .c files.
1015     --- netqmail-1.06-orig/Makefile 2007-11-30 20:22:54.000000000 +0000
1016     +++ netqmail-1.06/Makefile 2015-12-01 15:54:59.033940812 +0000
1017     @@ -808,7 +808,7 @@ dnsptr dnsip dnsmxip dnsfq hostname ipme
1018     forward preline condredirect bouncesaying except maildirmake \
1019     maildir2mbox maildirwatch qail elq pinq idedit install-big install \
1020     instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
1021     -binm3 binm3+df
1022     +binm3 binm3+df update_tmprsadh
1023    
1024     load: \
1025     make-load warn-auto.sh systype
1026     @@ -1444,6 +1444,7 @@ ndelay.a case.a sig.a open.a lock.a seek
1027     substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib
1028     ./load qmail-remote control.o constmap.o timeoutread.o \
1029     timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
1030     + tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \
1031     ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
1032     lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
1033     str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib`
1034     @@ -1539,6 +1540,7 @@ open.a sig.a case.a env.a stralloc.a all
1035     fs.a auto_qmail.o socket.lib
1036     ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
1037     timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
1038     + tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
1039     received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
1040     datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
1041     alloc.a substdio.a error.a str.a fs.a auto_qmail.o `cat \
1042     @@ -1827,7 +1829,8 @@ date822fmt.h date822fmt.c dns.h dns.c tr
1043     ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \
1044     ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \
1045     prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \
1046     -maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c
1047     +maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \
1048     +update_tmprsadh
1049     shar -m `cat FILES` > shar
1050     chmod 400 shar
1051    
1052     @@ -2108,6 +2111,19 @@ timeoutwrite.o: \
1053     compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h
1054     ./compile timeoutwrite.c
1055    
1056     +qmail-smtpd: tls.o ssl_timeoutio.o ndelay.a
1057     +qmail-remote: tls.o ssl_timeoutio.o
1058     +qmail-smtpd.o: tls.h ssl_timeoutio.h
1059     +qmail-remote.o: tls.h ssl_timeoutio.h
1060     +
1061     +tls.o: \
1062     +compile tls.c exit.h error.h
1063     + ./compile tls.c
1064     +
1065     +ssl_timeoutio.o: \
1066     +compile ssl_timeoutio.c ssl_timeoutio.h select.h error.h ndelay.h
1067     + ./compile ssl_timeoutio.c
1068     +
1069     token822.o: \
1070     compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \
1071     gen_alloc.h gen_allocdefs.h
1072     @@ -2139,3 +2155,26 @@ compile wait_nohang.c haswaitp.h
1073     wait_pid.o: \
1074     compile wait_pid.c error.h haswaitp.h
1075     ./compile wait_pid.c
1076     +
1077     +cert cert-req: \
1078     +Makefile-cert
1079     + @$(MAKE) -sf $< $@
1080     +
1081     +Makefile-cert: \
1082     +conf-qmail conf-users conf-groups Makefile-cert.mk
1083     + @cat Makefile-cert.mk \
1084     + | sed s}QMAIL}"`head -1 conf-qmail`"}g \
1085     + > $@
1086     +
1087     +update_tmprsadh: \
1088     +conf-qmail conf-users conf-groups update_tmprsadh.sh
1089     + @cat update_tmprsadh.sh\
1090     + | sed s}UGQMAILD}"`head -2 conf-users|tail -1`:`head -1 conf-groups`"}g \
1091     + | sed s}QMAIL}"`head -1 conf-qmail`"}g \
1092     + > $@
1093     + chmod 755 update_tmprsadh
1094     +
1095     +tmprsadh: \
1096     +update_tmprsadh
1097     + echo "Creating new temporary RSA and DH parameters"
1098     + ./update_tmprsadh
1099     --- netqmail-1.06-orig/update_tmprsadh.sh 2016-09-18 10:04:24.698101731 +0000
1100     +++ netqmail-1.06/update_tmprsadh.sh 2015-12-08 00:32:33.936474103 +0000
1101     @@ -0,0 +1,19 @@
1102     +#!/bin/sh
1103     +
1104     +# Update temporary RSA and DH keys
1105     +# Frederik Vermeulen 2004-05-31 GPL
1106     +
1107     +umask 0077 || exit 0
1108     +
1109     +export PATH="$PATH:/usr/local/bin/ssl:/usr/sbin"
1110     +
1111     +openssl genrsa -out QMAIL/control/rsa2048.new 2048 &&
1112     +chmod 600 QMAIL/control/rsa2048.new &&
1113     +chown UGQMAILD QMAIL/control/rsa2048.new &&
1114     +mv -f QMAIL/control/rsa2048.new QMAIL/control/rsa2048.pem
1115     +echo
1116     +
1117     +openssl dhparam -2 -out QMAIL/control/dh2048.new 2048 &&
1118     +chmod 600 QMAIL/control/dh2048.new &&
1119     +chown UGQMAILD QMAIL/control/dh2048.new &&
1120     +mv -f QMAIL/control/dh2048.new QMAIL/control/dh2048.pem

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed