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