ucspi-ssl  0.12.7
ucspi-ssl
sslhandle.c
Go to the documentation of this file.
1 
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <sys/param.h>
10 #include <netdb.h>
11 #include <signal.h>
12 #include <arpa/inet.h>
13 #include "ucspissl.h"
14 #include "uint_t.h"
15 #include "str.h"
16 #include "byte.h"
17 #include "fmt.h"
18 #include "scan.h"
19 #include "ip.h"
20 #include "fd.h"
21 #include "exit.h"
22 #include "env.h"
23 #include "prot.h"
24 #include "open.h"
25 #include "wait.h"
26 #include "stralloc.h"
27 #include "alloc.h"
28 #include "buffer.h"
29 #include "getln.h"
30 #include "logmsg.h"
31 #include "getoptb.h"
32 #include "socket_if.h"
33 #include "ndelay.h"
34 #include "remoteinfo.h"
35 #include "rules.h"
36 #include "sig.h"
37 #include "iopause.h"
38 #include "dnsresolv.h"
39 #include "auto_cafile.h"
40 #include "auto_cadir.h"
41 #include "auto_ccafile.h"
42 #include "auto_dhfile.h"
43 #include "auto_certchainfile.h"
44 #include "auto_certfile.h"
45 #include "auto_keyfile.h"
46 #include "auto_ciphers.h"
47 #include "iopause.h"
48 #include "coe.h"
49 #include "lock.h"
50 
51 
52 extern void server(int argcs,char * const *argvs);
53 char *who;
54 
55 int verbosity = 1;
56 int flagkillopts = 1;
57 int flagafter = 0;
58 int flagdelay = 0;
59 const char *banner = "";
62 int flagparanoid = 0;
64 int flagsslenv = 0;
65 int flagtcpenv = 0;
66 unsigned long timeout = 26;
67 unsigned long ssltimeout = 26;
68 unsigned int progtimeout = 3600;
69 uint32 netif = 0;
70 int selfpipe[2];
71 int flagexit = 0;
72 int flagdualstack = 0;
73 
74 static stralloc tcpremoteinfo = {0};
75 
76 uint16 localport;
77 char localportstr[FMT_ULONG];
78 char localip[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
79 char localipstr[IP6_FMT];
80 static stralloc localhostsa;
81 const char *localhost = 0;
82 const char *lockfile = 0;
83 int fdlock;
84 
85 uint16 remoteport;
86 char remoteportstr[FMT_ULONG];
87 char remoteip[16];
88 char remoteipstr[IP6_FMT];
89 static stralloc remotehostsa;
90 char *remotehost = 0;
91 
92 const char *hostname;
93 const char *loopback = "127.0.0.1";
94 
95 static char strnum[FMT_ULONG];
96 static char strnum2[FMT_ULONG];
97 
98 static stralloc tmp;
99 static stralloc fqdn;
100 static stralloc addresses;
101 static stralloc certname;
102 stralloc envplus = {0};
103 stralloc envtmp = {0};
104 
105 char bspace[16];
106 buffer b;
107 
108 SSL_CTX *ctx;
110 const char *certfile = auto_certfile;
111 const char *keyfile = auto_keyfile;
112 stralloc password = {0};
113 int match = 0;
114 const char *cafile = auto_cafile;
115 const char *ccafile = auto_ccafile;
116 const char *cadir = auto_cadir;
117 const char *ciphers = auto_ciphers;
118 int verifydepth = 1;
119 const char *dhfile = auto_dhfile;
121 
122 int pi[2];
123 int po[2];
124 
125 X509 *cert;
127 
128 char **e;
129 char **e1;
130 
131 /* ---------------------------- child */
132 
133 
134 int flagdeny = 0;
136 const char *fnrules = 0;
137 
138 void drop_nomem(void) {
139  logmsg(who,111,FATAL,"out of memory");
140 }
141 void drop_notemp(void) {
142  logmsg(who,111,FATAL,"out of timestamps");
143 }
144 void cats(const char *s) {
145  if (!stralloc_cats(&tmp,s)) drop_nomem();
146 }
147 void append(const char *ch) {
148  if (!stralloc_append(&tmp,ch)) drop_nomem();
149 }
150 void safecats(const char *s) {
151  char ch;
152  int i;
153 
154  for (i = 0;i < 100;++i) {
155  ch = s[i];
156  if (!ch) return;
157  if (ch < 33) ch = '?';
158  if (ch > 126) ch = '?';
159  if (ch == '%') ch = '?'; /* logger stupidity */
160  append(&ch);
161  }
162  cats("...");
163 }
164 void env(const char *s,const char *t) {
165  if (!s) return;
166  if (!stralloc_copys(&envtmp,s)) drop_nomem();
167  if (t) {
168  if (!stralloc_cats(&envtmp,"=")) drop_nomem();
169  if (!stralloc_cats(&envtmp,t)) drop_nomem();
170  }
171  if (!stralloc_0(&envtmp)) drop_nomem();
172  if (!stralloc_cat(&envplus,&envtmp)) drop_nomem();
173 }
174 static void env_def() {
175  unsigned int elen;
176  unsigned int i;
177  unsigned int j;
178  unsigned int split;
179  unsigned int t;
180 
181  if (!stralloc_cats(&envplus,"")) return;
182 
183  elen = 0;
184  for (i = 0; environ[i]; ++i)
185  ++elen;
186  for (i = 0; i < envplus.len; ++i)
187  if (!envplus.s[i])
188  ++elen;
189 
190  e = (char **) alloc((elen + 1) * sizeof(char *));
191  if (!e) return;
192 
193  elen = 0;
194  for (i = 0; environ[i]; ++i)
195  e[elen++] = environ[i];
196 
197  j = 0;
198  for (i = 0; i < envplus.len; ++i)
199  if (!envplus.s[i]) {
200  split = str_chr(envplus.s + j,'=');
201  for (t = 0;t < elen;++t)
202  if (byte_equal(envplus.s + j,split,e[t]))
203  if (e[t][split] == '=') {
204  --elen;
205  e[t] = e[elen];
206  break;
207  }
208  if (envplus.s[j + split])
209  e[elen++] = envplus.s + j;
210  j = i + 1;
211  }
212  e[elen] = 0;
213 
214  e1 = environ;
215  environ = e;
216 }
217 void env_reset(void) {
218  if (e) {
219  if (e != environ)
220  alloc_free((char *)e);
221  logmsg(who,111,FATAL,"environ changed");
222  }
223 
224  environ = e1;
225  envplus.len = 0;
226 }
227 int error_warn(const char *x) {
228  if (!x) return 0;
229  log_who(who,"x");
230  return 0;
231 }
232 void drop_rules(void) {
233  logmsg(who,111,FATAL,B("unable to read: ",(char *)fnrules));
234 }
235 
236 void found(char *data,unsigned int datalen) {
237  unsigned int next0;
238  unsigned int split;
239 
240  while ((next0 = byte_chr(data,datalen,0)) < datalen) {
241  switch(data[0]) {
242  case 'D':
243  flagdeny = 1;
244  break;
245  case '+':
246  split = str_chr(data + 1,'=');
247  if (data[1 + split] == '=') {
248  data[1 + split] = 0;
249  env(data + 1,data + 1 + split + 1);
250  }
251  break;
252  }
253  ++next0;
254  data += next0; datalen -= next0;
255  }
256 }
257 
258 int doit(int t) {
259  int j;
260  SSL *ssl;
261  uint32 netif;
262 
263  if (ip6_isv4mapped(remoteip)) {
264  remoteipstr[ip4_fmt(remoteipstr,remoteip+12)] = 0;
265  localipstr[ip4_fmt(localipstr,localip + 12)] = 0;
266  } else {
267  remoteipstr[ip6_fmt(remoteipstr,remoteip)] = 0;
268  localipstr[ip6_fmt(localipstr,localip)] = 0;
269  }
270 
271  if (verbosity >= 2) {
272  strnum[fmt_ulong(strnum,getpid())] = 0;
273  log_who(who,B("pid ",strnum," from ",remoteipstr));
274  }
275 
276  if (socket_local(t,localip,&localport,&netif) == -1)
277  logmsg(who,111,FATAL,"unable to get local address");
278 
279  remoteportstr[fmt_ulong(remoteportstr,remoteport)] = 0;
280 
281  if (!localhost)
282  if (dns_name(&localhostsa,localip) >= 0)
283  if (localhostsa.len) {
284  if (!stralloc_0(&localhostsa)) drop_nomem();
285  localhost = localhostsa.s;
286  }
287 
288  env("PROTO","TLS");
289  env("SSLLOCALIP",localipstr);
290  env("SSLLOCALPORT",localportstr);
291  env("SSLLOCALHOST",localhost);
292  env("SSLREMOTEIP",remoteipstr);
293  env("SSLREMOTEPORT",remoteportstr);
294  env("SSLREMOTEHOST",remotehost);
295 
296  if (flagtcpenv) {
297  env("TCPLOCALIP",localipstr);
298  env("TCPLOCALPORT",localportstr);
299  env("TCPLOCALHOST",localhost);
300  env("TCPREMOTEIP",remoteipstr);
301  env("TCPREMOTEPORT",remoteportstr);
302  env("TCPREMOTEHOST",remotehost);
303  if (!ip6_isv4mapped(localip)) {
304  env("PROTO","TCP6");
305  env("TCP6LOCALIP",localipstr);
306  env("TCP6LOCALHOST",localhost);
307  env("TCP6LOCALPORT",localportstr);
308  env("TCP6REMOTEIP",remoteipstr);
309  env("TCP6REMOTEPORT",remoteportstr);
310  env("TCP6REMOTEHOST",remotehost);
311  if (netif)
312  env("TCP6INTERFACE",socket_getifname(netif));
313  } else
314  env("PROTO","TCP");
315  }
316 
317  if (flagremotehost)
318  if (dns_name(&remotehostsa,remoteip) >= 0)
319  if (remotehostsa.len) {
320  if (flagparanoid)
321  if (dns_ip6(&tmp,&remotehostsa) >= 0)
322  for (j = 0; j + 16 <= tmp.len; j += 16)
323  if (byte_equal(remoteip,16,tmp.s + j)) {
324  flagparanoid = 0;
325  break;
326  }
327  if (dns_ip4(&tmp,&remotehostsa) >= 0)
328  for (j = 0; j + 4 <= tmp.len; j += 4)
329  if (byte_equal(remoteip,4,tmp.s + j)) {
330  flagparanoid = 0;
331  break;
332  }
333  if (!flagparanoid) {
334  if (!stralloc_0(&remotehostsa)) drop_nomem();
335  remotehost = remotehostsa.s;
336  }
337  }
338 
339  if (flagremoteinfo) {
340  if (remoteinfo(&tcpremoteinfo,remoteip,remoteport,localip,localport,timeout,netif) == -1)
341  flagremoteinfo = 0;
342  if (!stralloc_0(&tcpremoteinfo)) drop_nomem();
343  }
344  env("SSLREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
345  if (flagtcpenv)
346  env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
347 
348  if (fnrules) {
349  int fdrules;
350  flagdeny = 0;
351  fdrules = open_read(fnrules);
352  if (fdrules == -1) {
353  if (errno != ENOENT) drop_rules();
355  } else {
356  if (rules(found,fdrules,remoteipstr,remotehost,flagremoteinfo ? tcpremoteinfo.s : 0) == -1)
357  drop_rules();
358  close(fdrules);
359  }
360  }
361 
362  if (verbosity >= 2) {
363  strnum[fmt_ulong(strnum,getpid())] = 0;
364  if (!stralloc_copys(&tmp,who)) drop_nomem();
365  if (!stralloc_cats(&tmp,": ")) drop_nomem();
366  safecats(flagdeny ? "deny" : "ok");
367  cats(" "); safecats(strnum);
368  cats(" "); if (localhost) safecats(localhost);
369  cats(":"); safecats(localipstr);
370  cats(":"); safecats(localportstr);
371  cats(" "); if (remotehost) safecats(remotehost);
372  cats(":"); safecats(remoteipstr);
373  cats(":"); if (flagremoteinfo) safecats(tcpremoteinfo.s);
374  cats(":"); safecats(remoteportstr);
375  cats("\n");
376  buffer_putflush(buffer_2,tmp.s,tmp.len);
377  }
378 
379  if (flagdeny) {
380  close(t);
381  return(0);
382  }
383 
384  if (pipe(pi) == -1) logmsg(who,111,FATAL,"unable to create pipe");
385  if (pipe(po) == -1) logmsg(who,111,FATAL,"unable to create pipe");
386 
387  ssl = ssl_new(ctx,t);
388  if (!ssl) logmsg(who,111,FATAL,"unable to create SSL instance");
389  if (ndelay_on(t) == -1)
390  logmsg(who,111,FATAL,"unable to set socket options");
391  if (ssl_timeoutaccept(ssl,ssltimeout) == -1) {
392  strnum[fmt_ulong(strnum,getpid())] = 0;
393  logmsg(who,110,DROP,B("unable to TLS accept for pid:",strnum));
395  }
396 
397  if (verbosity >= 2) {
398  strnum[fmt_ulong(strnum,getpid())] = 0;
399  log_who(who,B("tls ",strnum," accept "));
400  }
401 
402  if (flagclientcert) {
403  switch(ssl_verify(ssl,remotehost,&certname)) {
404  case -1:
405  logmsg(who,110,ERROR,"no client certificate");
406  case -2:
407  logmsg(who,110,ERROR,"missing credentials (CA) or unable to validate client certificate");
408  case -3:
409  if (!stralloc_0(&certname)) drop_nomem();
410  logmsg(who,110,ERROR,B("client hostname name does not match certificate: ",remotehost," <=> ",certname.s));
411  default:
412  break;
413  }
414  }
415 
416  switch(fork()) {
417  case -1:
418  logmsg(who,111,FATAL,"unable to fork ");
419  case 0:
420  close(pi[0]); close(po[1]);
421  sig_uncatch(sig_child);
422  sig_unblock(sig_child);
423  if (ssl_io(ssl,pi[1],po[0],progtimeout) == -1) {
424  strnum[fmt_ulong(strnum,getpid())] = 0;
425  logmsg(who,-99,WARN,B("unable to speak TLS for pid: ",strnum));
427  _exit(111);
428  }
429  _exit(0);
430  }
431  close(pi[1]); close(po[0]);
432 
433  if (flagsslenv && !ssl_server_env(ssl,&envplus)) drop_nomem();
434  env_def();
435 
436  if (fd_move(0,pi[0]) == -1)
437  logmsg(who,111,FATAL,"unable to set up descriptor 0");
438  if (fd_move(1,po[1]) == -1)
439  logmsg(who,111,FATAL,"unable to set up descriptor 1");
440 
441  if (flagkillopts) {
442  socket_ipoptionskill(t);
443  }
444  if (!flagdelay)
445  socket_tcpnodelay(t);
446 
447  if (*banner) {
448  buffer_init(&b,buffer_unixwrite,1,bspace,sizeof(bspace));
449  if (buffer_putsflush(&b,banner) == -1)
450  logmsg(who,111,FATAL,"unable to print banner");
451  }
452 
453  ssl_free(ssl);
454  return 1;
455 }
456 
457 void done(void) {
458  if (verbosity >= 2) {
459  strnum[fmt_ulong(strnum,getpid())] = 0;
460  if (!stralloc_copys(&tmp,who)) drop_nomem();
461  if (!stralloc_cats(&tmp,": ")) drop_nomem();
462  cats("done "); safecats(strnum); cats("\n");
463  buffer_putflush(buffer_2,tmp.s,tmp.len);
464  }
465 }
466 
467 
468 /* ---------------------------- parent */
469 
470 void usage(void)
471 {
472  logmsg(who,100,USAGE,B(who,"\
473 [ -1346UXpPhHrRoOdDqQviIeEsS ] \
474 [ -c limit ] \
475 [ -x rules.cdb ] \
476 [ -B banner ] \
477 [ -g gid ] \
478 [ -u uid ] \
479 [ -b backlog ] \
480 [ -l localname ] \
481 [ -t timeout ] \
482 [ -T ssltimeout ] \
483 [ -w progtimeout ] \
484 [ -f lockfile ] \
485 [ -I interface ] \
486 host port program"));
487 }
488 
489 unsigned long limit = 40;
490 unsigned long numchildren = 0;
491 
492 int flag1 = 0;
493 int flag3 = 0;
494 unsigned long backlog = 20;
495 unsigned long uid = 0;
496 unsigned long gid = 0;
497 
498 void printstatus(void) {
499  if (verbosity < 2) return;
500  strnum[fmt_ulong(strnum,numchildren)] = 0;
501  strnum2[fmt_ulong(strnum2,limit)] = 0;
502  log_who(who,B("status: ",strnum,"/",strnum2));
503 }
504 
505 void trigger(void) {
506  buffer_unixwrite(selfpipe[1],"",1);
507 }
508 
509 void sigterm(void) {
510  int pid;
511 
512  flagexit = 1;
513  pid = getpid();
514  if (pid < 0) logmsg(who,111,FATAL,"cannot get pid");
515  kill(-pid,SIGTERM);
516  trigger();
517 }
518 
519 void sigchld(void) {
520  int wstat;
521  int pid;
522 
523  while ((pid = wait_nohang(&wstat)) > 0) {
524  if (verbosity >= 2) {
525  strnum[fmt_ulong(strnum,pid)] = 0;
526  strnum2[fmt_ulong(strnum2,wstat)] = 0;
527  log_who(who,B("end ",strnum," status ",strnum2));
528  }
530  if (flagexit && !numchildren) _exit(0);
531  }
532  trigger();
533 }
534 
535 void read_passwd(void) {
536  if (!password.len) {
537  buffer_init(&b,buffer_unixread,3,bspace,sizeof(bspace));
538  if (getln(&b,&password,&match,'\0') == -1)
539  logmsg(who,111,ERROR,"unable to read password");
540  close(3);
541  if (match) --password.len;
542  }
543 }
544 
545 int passwd_cb(char *buff,int size,int rwflag,void *userdata) {
546  if (size < password.len)
547  logmsg(who,111,ERROR,"password too long");
548 
549  byte_copy(buff,password.len,password.s);
550  return password.len;
551 }
552 
553 void spawn(int s,int argc,char * const *argv) {
554  int t;
555 
556  while (numchildren >= limit) sig_pause();
557  while (numchildren < limit) {
559 
560  switch(fork()) {
561  case 0:
562  sig_uncatch(sig_child);
563  sig_unblock(sig_child);
564  sig_uncatch(sig_term);
565  sig_uncatch(sig_pipe);
566  for (;;) {
567  if (lockfile) {
568  if (lock_ex(fdlock) == -1)
569  logmsg(who,111,FATAL,B("unable to lock: ",(char *)lockfile));
570  if (flagdualstack)
571  t = socket_accept6(s,remoteip,&remoteport,&netif);
572  else
573  t = socket_accept4(s,remoteip,&remoteport);
574  lock_un(fdlock);
575  } else {
576  if (flagdualstack)
577  t = socket_accept6(s,remoteip,&remoteport,&netif);
578  else
579  t = socket_accept4(s,remoteip,&remoteport);
580  }
581 
582  if (t == -1) continue;
583  if (!doit(t)) continue;
584  server(argc,argv);
585  close(0); close(1);
586  env_reset();
587  done();
588  }
589  break;
590  case -1:
591  logmsg(who,111,FATAL,"unable to fork");
593  }
594  }
595 }
596 
597 int main(int argc,char * const *argv) {
598  int opt;
599  struct servent *se;
600  char *x;
601  unsigned long u = 0;
602  int j;
603  int s;
604  int ipflag = 0;
605  iopause_fd io[2];
606  char ch;
607  struct taia deadline;
608  struct taia stamp;
609 
610  who = argv[0];
611  while ((opt = getopt(argc,argv,"dDvqQhHrRUXx:t:T:u:g:l:b:B:c:pPoO1346I:EeSsaAf:w:zZM:")) != opteof)
612  switch(opt) {
613  case 'b': scan_ulong(optarg,&backlog); break;
614  case 'c': scan_ulong(optarg,&limit); break;
615  case 'X': flagallownorules = 1; break;
616  case 'x': fnrules = optarg; break;
617  case 'B': banner = optarg; break;
618  case 'd': flagdelay = 1; break;
619  case 'D': flagdelay = 0; break;
620  case 'v': verbosity = 2; break;
621  case 'q': verbosity = 0; break;
622  case 'Q': verbosity = 1; break;
623  case 'P': flagparanoid = 0; break;
624  case 'p': flagparanoid = 1; break;
625  case 'O': flagkillopts = 1; break;
626  case 'o': flagkillopts = 0; break;
627  case 'H': flagremotehost = 0; break;
628  case 'h': flagremotehost = 1; break;
629  case 'R': flagremoteinfo = 0; break;
630  case 'r': flagremoteinfo = 1; break;
631  case 't': scan_ulong(optarg,&timeout); break;
632  case 'T': scan_ulong(optarg,&ssltimeout); break;
633  case 'U': x = env_get("UID"); if (x) scan_ulong(x,&uid);
634  x = env_get("GID"); if (x) scan_ulong(x,&gid); break;
635  case 'u': scan_ulong(optarg,&uid); break;
636  case 'g': scan_ulong(optarg,&gid); break;
637  case 'l': localhost = optarg; break;
638  case 'I': netif = socket_getifidx(optarg); break;
639  case '1': flag1 = 1; break;
640  case '3': flag3 = 1; break;
641  case '4': ipflag = 1; break;
642  case '6': ipflag = 2; break;
643  case 'Z': flagclientcert = 0; break;
644  case 'z': flagclientcert = 1; break;
645  case 'S': flagsslenv = 0; break;
646  case 's': flagsslenv = 1; break;
647  case 'E': flagtcpenv = 0; break;
648  case 'e': flagtcpenv = 1; break;
649  case 'A': flagafter = 0; break;
650  case 'a': flagafter = 1; break;
651  case 'f': lockfile = optarg; break;
652  case 'w': scan_uint(optarg,&progtimeout); break;
653  case 'M': scan_ulong(optarg,&u); break;
654  default: usage();
655  }
656  argc -= optind;
657  argv += optind;
658 
659  if (!verbosity) buffer_2->fd = -1;
660 
661  hostname = *argv++;
662  if (!hostname || str_equal((char *)hostname,"")) usage();
663  if (str_equal((char *)hostname,"0")) hostname = loopback;
664  else if (str_equal((char *)hostname,":0")) {
665  flagdualstack = 1;
666  hostname = "::";
667  }
668 
669  x = *argv++; --argc;
670  if (!x) usage();
671  if (!x[scan_ulong(x,&u)])
672  localport = u;
673  else {
674  se = getservbyname(x,"tcp");
675  if (!se)
676  logmsg(who,111,FATAL,B("unable to figure out port number for: ",x));
677  uint16_unpack_big((char*)&se->s_port,&localport);
678  }
679 
680  if ((x = env_get("VERIFYDEPTH"))) {
681  scan_ulong(x,&u);
682  verifydepth = u;
683  }
684 
685  if ((x = env_get("CAFILE"))) cafile = x;
686  if (cafile && str_equal((char *)cafile,"")) cafile = 0;
687 
688  if ((x = env_get("CCAFILE"))) ccafile = x;
689  if (ccafile && str_equal((char *)ccafile,"")) ccafile = 0;
690  if (!flagclientcert) ccafile = 0;
691 
692  if ((x = env_get("CADIR"))) cadir = x;
693  if (cadir && str_equal((char *)cadir,"")) cadir= 0;
694 
695  if ((x = env_get("CERTCHAINFILE"))) certchainfile = x;
696  if (certchainfile && str_equal((char *)certchainfile,"")) certchainfile = 0;
697 
698  if ((x = env_get("CERTFILE"))) certfile = x;
699  if (certfile && str_equal((char *)certfile,"")) certfile = 0;
700 
701  if ((x = env_get("KEYFILE"))) keyfile = x;
702  if (keyfile && str_equal((char *)keyfile,"")) keyfile = 0;
703 
704  if ((x = env_get("DHFILE"))) dhfile = x;
705  if (dhfile && str_equal((char *)dhfile,"")) dhfile = 0;
706 
707  if ((x = env_get("CIPHERS"))) ciphers = x;
708  if (ciphers && str_equal((char *)ciphers,"")) ciphers = 0;
709 
710  if (setsid() == -1)
711  if (getpgrp() != getpid())
712  logmsg(who,111,FATAL,"unable to create process group");
713 
714  if (lockfile) {
715  fdlock = open_append(lockfile);
716  if (fdlock == -1)
717  logmsg(who,111,FATAL,B("unable to open: ",(char *)lockfile));
718  }
719 
720  if (pipe(selfpipe) == -1)
721  logmsg(who,111,FATAL,"unable to create pipe");
722 
723  coe(selfpipe[0]);
724  coe(selfpipe[1]);
725  ndelay_on(selfpipe[0]);
726  ndelay_on(selfpipe[1]);
727 
728  sig_block(sig_child);
729  sig_catch(sig_child,sigchld);
730  sig_catch(sig_term,sigterm);
731  sig_ignore(sig_pipe);
732 
733  /* IP address only */
734 
735  if (ip4_scan(hostname,localip)) {
736  if (!stralloc_copyb(&addresses,(char *)V4mappedprefix,12)) drop_nomem();
737  if (!stralloc_catb(&addresses,localip,4)) drop_nomem();
738  byte_copy(localip,16,addresses.s);
739  } else if (ip6_scan(hostname,localip)) {
740  if (!stralloc_copyb(&addresses,localip,16)) drop_nomem();
741  byte_copy(localip,16,addresses.s);
742  }
743 
744  /* Asynchronous DNS IPv4/IPv6 Name qualification */
745 
746  if (!addresses.len) {
747  if (!stralloc_copys(&tmp,hostname)) drop_nomem();
748  if (dns_ip_qualify(&addresses,&fqdn,&tmp) < 0)
749  logmsg(who,111,FATAL,B("temporarily unable to figure out IP address for: ",(char *)hostname));
750 
751  byte_copy(localip,16,addresses.s);
752 
753  for (j = 0; j < addresses.len; j += 16) { // Select best matching IP address
754  if (ipflag == 1 && !ip6_isv4mapped(addresses.s + j)) continue;
755  if (ipflag == 2 && !ip6_isv4mapped(addresses.s + j)) continue;
756  byte_copy(localip,16,addresses.s + j);
757  }
758 
759  }
760  if (addresses.len < 16)
761  logmsg(who,111,FATAL,B("no IP address for: ",(char *)hostname));
762 
763  if (ip6_isv4mapped(localip))
764  s = socket_tcp4();
765  else
766  s = socket_tcp6();
767  if (s == -1)
768  logmsg(who,111,FATAL,"unable to create socket");
769 
770  if (flagdualstack)
771  socket_dualstack(s);
772  if (socket_bind_reuse(s,localip,localport,netif) == -1)
773  logmsg(who,111,FATAL,"unable to bind");
774  if (socket_local(s,localip,&localport,&netif) == -1)
775  logmsg(who,111,FATAL,"unable to get local address");
776  if (socket_listen(s,backlog) == -1)
777  logmsg(who,111,FATAL,"unable to listen");
778  ndelay_off(s);
779 
780  if (!flagafter) {
781  if (gid) if (prot_gid(gid) == -1)
782  logmsg(who,111,FATAL,"unable to set gid");
783  if (uid) if (prot_uid(uid) == -1)
784  logmsg(who,111,FATAL,"unable to set uid");
785  }
786 
787  if (ip6_isv4mapped(localip))
788  localipstr[ip4_fmt(localipstr,localip + 12)] = 0;
789  else
790  localipstr[ip6_fmt(localipstr,localip)] = 0;
791 
792  localportstr[fmt_ulong(localportstr,localport)] = 0;
793 
794  if (flag1) {
795  buffer_init(&b,buffer_unixwrite,1,bspace,sizeof(bspace));
796  buffer_puts(&b,localipstr);
797  buffer_puts(&b," : ");
798  buffer_puts(&b,localportstr);
799  buffer_puts(&b,"\n");
800  buffer_flush(&b);
801  }
802 
803  if (flag3) read_passwd();
804 
805  ctx = ssl_server();
806  ssl_errstr();
807  if (!ctx) logmsg(who,111,FATAL,"unable to create TLS context");
808 
809  if (certchainfile) {
811  case -1: logmsg(who,111,ERROR,"unable to load certificate chain file");
812  case -2: logmsg(who,111,ERROR,"unable to load key");
813  case -3: logmsg(who,111,ERROR,"key does not match certificate");
814  default: break;
815  }
816  } else {
818  case -1: logmsg(who,111,ERROR,"unable to load certificate");
819  case -2: logmsg(who,111,ERROR,"unable to load key");
820  case -3: logmsg(who,111,ERROR,"key does not match certificate");
821  default: break;
822  }
823  }
824 
826  logmsg(who,111,ERROR,"unable to load CA list");
827 
828  if (!ssl_cca(ctx,ccafile))
829  logmsg(who,111,ERROR,"unable to load client CA list");
830 
831  if (!ssl_params_rsa(ctx,rsalen))
832  logmsg(who,111,ERROR,"unable to set RSA parameters");
833  if (!ssl_params_dh(ctx,dhfile))
834  logmsg(who,111,ERROR,"unable to set DH parameters");
835 
836  if (flagafter) {
837  if (gid) if (prot_gid(gid) == -1)
838  logmsg(who,111,FATAL,"unable to set gid");
839  if (uid) if (prot_uid(uid) == -1)
840  logmsg(who,111,FATAL,"unable to set uid");
841  }
842 
843  if (!ssl_ciphers(ctx,ciphers))
844  logmsg(who,111,ERROR,"unable to set cipher list");
845 
846  if (verbosity >= 2) {
847  strnum[fmt_ulong(strnum,getpid())] = 0;
848  strnum2[fmt_ulong(strnum2,rsalen)] = 0;
849  log_who(who,B("ciphers ",strnum," ",(char *)ciphers));
850  log_who(who,B("cafile ",strnum," ",(char *)cafile));
851  log_who(who,B("ccafile ",strnum," ",(char *)ccafile));
852  log_who(who,B("cadir ",strnum," ",(char *)cadir));
853  log_who(who,B("certchainfile ",strnum," ",(char *)certchainfile));
854  log_who(who,B("cert ",strnum," ",(char *)certfile));
855  log_who(who,B("key ",strnum," ",(char *)keyfile));
856  /* XXX */
857  log_who(who,B("dhparam ",strnum," ",(char *)dhfile," ",strnum2));
858  }
859 
860  close(0);
861  close(1);
862  printstatus();
863 
864  for (;;) {
865  int pause_ret, read_ret;
866  if (!flagexit) spawn(s,argc,argv);
867 
868  sig_unblock(sig_child);
869  io[0].fd = selfpipe[0];
870  io[0].events = IOPAUSE_READ;
871  taia_now(&stamp);
872  taia_uint(&deadline,3600);
873  taia_add(&deadline,&stamp,&deadline);
874  pause_ret = iopause(io,1,&deadline,&stamp);
875  sig_block(sig_child);
876 
877  if (flagexit && !numchildren) _exit(0);
878  while ((read_ret = buffer_unixread(selfpipe[0],&ch,1)) == 1)
879  ;
880  if ((pause_ret > 0) && (read_ret == 0)) {
881  flagexit = 1;
882  --numchildren;
883  }
884  if (flagexit && !numchildren) _exit(0);
885  }
886 }
const char auto_cadir[]
Definition: auto_cadir.c:1
const char auto_cafile[]
Definition: auto_cafile.c:1
const char auto_ccafile[]
Definition: auto_ccafile.c:1
const char auto_certchainfile[]
const char auto_certfile[]
Definition: auto_certfile.c:1
const char auto_ciphers[]
Definition: auto_ciphers.c:1
const char auto_dhfile[]
Definition: auto_dhfile.c:1
const char auto_keyfile[]
Definition: auto_keyfile.c:1
int coe(int fd)
Definition: coe.c:6
void _exit()
int remoteinfo(stralloc *out, char ipremote[16], uint16 portremote, char iplocal[16], uint16 portlocal, unsigned int timeout, uint32 netif)
Definition: remoteinfo.c:86
int rules(void(*callback)(char *, unsigned int), int fd, char *ip, char *host, char *info)
Definition: rules.c:135
int ssl_ca(SSL_CTX *ctx, const char *certfile, const char *certdir, int d)
Definition: ssl_ca.c:3
int ssl_cca(SSL_CTX *ctx, const char *certfile)
Definition: ssl_cca.c:3
int ssl_certkey(SSL_CTX *ctx, const char *certfile, const char *keyfile, pem_password_cb *passwd_cb)
Definition: ssl_certkey.c:3
int ssl_chainfile(SSL_CTX *ctx, const char *certchainfile, const char *keyfile, pem_password_cb *passwd_cb)
Definition: ssl_chainfile.c:8
int ssl_ciphers(SSL_CTX *ctx, const char *ciphers)
Definition: ssl_ciphers.c:3
int ssl_server_env(SSL *ssl, stralloc *sa)
Definition: ssl_env.c:423
int ssl_error(int(*op)(const char *))
Definition: ssl_error.c:3
int ssl_io(SSL *ssl, int fdleft, int fdright, unsigned int timeout)
Definition: ssl_io.c:20
SSL * ssl_new(SSL_CTX *ctx, int s)
Definition: ssl_new.c:4
int ssl_params_dh(SSL_CTX *ctx, const char *dhfile)
Definition: ssl_params.c:37
int ssl_params_rsa(SSL_CTX *ctx, int len)
Definition: ssl_params.c:8
int ssl_timeoutaccept(SSL *ssl, unsigned int timeout)
Definition: ssl_timeout.c:7
int ssl_verify(SSL *ssl, const char *hostname, stralloc *dnsout)
Definition: ssl_verify.c:10
void drop_nomem(void)
Definition: sslhandle.c:138
void sigchld(void)
Definition: sslhandle.c:519
stralloc password
Definition: sslhandle.c:112
const char * certfile
Definition: sslhandle.c:110
int selfpipe[2]
Definition: sslhandle.c:70
int verbosity
Definition: sslhandle.c:55
const char * dhfile
Definition: sslhandle.c:119
unsigned long ssltimeout
Definition: sslhandle.c:67
const char * ciphers
Definition: sslhandle.c:117
void cats(const char *s)
Definition: sslhandle.c:144
int flagallownorules
Definition: sslhandle.c:135
int flagexit
Definition: sslhandle.c:71
X509 * cert
Definition: sslhandle.c:125
char ** e
Definition: sslhandle.c:128
char localipstr[IP6_FMT]
Definition: sslhandle.c:79
int flag3
Definition: sslhandle.c:493
void server(int argcs, char *const *argvs)
void found(char *data, unsigned int datalen)
Definition: sslhandle.c:236
uint16 localport
Definition: sslhandle.c:76
char remoteportstr[FMT_ULONG]
Definition: sslhandle.c:86
char localportstr[FMT_ULONG]
Definition: sslhandle.c:77
stralloc envplus
Definition: sslhandle.c:102
const char * fnrules
Definition: sslhandle.c:136
int flagclientcert
Definition: sslhandle.c:63
unsigned long uid
Definition: sslhandle.c:495
char localip[16]
Definition: sslhandle.c:78
unsigned long gid
Definition: sslhandle.c:496
const char * cadir
Definition: sslhandle.c:116
int flagremotehost
Definition: sslhandle.c:61
unsigned int progtimeout
Definition: sslhandle.c:68
int flagremoteinfo
Definition: sslhandle.c:60
int flagkillopts
Definition: sslhandle.c:56
unsigned long timeout
Definition: sslhandle.c:66
void printstatus(void)
Definition: sslhandle.c:498
buffer b
Definition: sslhandle.c:106
char remoteipstr[IP6_FMT]
Definition: sslhandle.c:88
const char * cafile
Definition: sslhandle.c:114
const char * banner
Definition: sslhandle.c:59
const char * certchainfile
Definition: sslhandle.c:109
int doit(int t)
Definition: sslhandle.c:258
int flagafter
Definition: sslhandle.c:57
void env_reset(void)
Definition: sslhandle.c:217
void env(const char *s, const char *t)
Definition: sslhandle.c:164
unsigned long numchildren
Definition: sslhandle.c:490
char buf[SSL_NAME_LEN]
Definition: sslhandle.c:126
const char * keyfile
Definition: sslhandle.c:111
unsigned long backlog
Definition: sslhandle.c:494
int rsalen
Definition: sslhandle.c:120
int flagdeny
Definition: sslhandle.c:134
uint16 remoteport
Definition: sslhandle.c:85
void done(void)
Definition: sslhandle.c:457
char * who
Definition: sslhandle.c:53
void read_passwd(void)
Definition: sslhandle.c:535
const char * hostname
Definition: sslhandle.c:92
void sigterm(void)
Definition: sslhandle.c:509
const char * lockfile
Definition: sslhandle.c:82
const char * loopback
Definition: sslhandle.c:93
void drop_rules(void)
Definition: sslhandle.c:232
char remoteip[16]
Definition: sslhandle.c:87
void append(const char *ch)
Definition: sslhandle.c:147
int flagdelay
Definition: sslhandle.c:58
void safecats(const char *s)
Definition: sslhandle.c:150
unsigned long limit
Definition: sslhandle.c:489
uint32 netif
Definition: sslhandle.c:69
char * remotehost
Definition: sslhandle.c:90
int match
Definition: sslhandle.c:113
const char * localhost
Definition: sslhandle.c:81
stralloc envtmp
Definition: sslhandle.c:103
int main(int argc, char *const *argv)
Definition: sslhandle.c:597
int pi[2]
Definition: sslhandle.c:122
SSL_CTX * ctx
Definition: sslhandle.c:108
int flagtcpenv
Definition: sslhandle.c:65
int passwd_cb(char *buff, int size, int rwflag, void *userdata)
Definition: sslhandle.c:545
void drop_notemp(void)
Definition: sslhandle.c:141
char bspace[16]
Definition: sslhandle.c:105
void spawn(int s, int argc, char *const *argv)
Definition: sslhandle.c:553
void usage(void)
Definition: sslhandle.c:470
const char * ccafile
Definition: sslhandle.c:115
int flagdualstack
Definition: sslhandle.c:72
int verifydepth
Definition: sslhandle.c:118
int flagparanoid
Definition: sslhandle.c:62
int fdlock
Definition: sslhandle.c:83
int flagsslenv
Definition: sslhandle.c:64
int error_warn(const char *x)
Definition: sslhandle.c:227
char ** e1
Definition: sslhandle.c:129
void trigger(void)
Definition: sslhandle.c:505
int po[2]
Definition: sslhandle.c:123
int flag1
Definition: sslhandle.c:492
Header file to be used with sqmail; previously called ssl.h. (name clash)
#define SSL_NAME_LEN
Definition: ucspissl.h:31
#define SSL_RSA_LEN
Definition: ucspissl.h:32
#define ssl_errstr()
Definition: ucspissl.h:61
#define ssl_free(ssl)
Definition: ucspissl.h:62
#define ssl_server()
Definition: ucspissl.h:36