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