8 #include <sys/socket.h>
12 #include <arpa/inet.h>
32 #include "socket_if.h"
38 #include "dnsresolv.h"
52 extern void server(
int argcs,
char *
const *argvs);
74 static stralloc tcpremoteinfo = {0};
78 char localip[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
80 static stralloc localhostsa;
89 static stralloc remotehostsa;
95 static char strnum[FMT_ULONG];
96 static char strnum2[FMT_ULONG];
100 static stralloc addresses;
101 static stralloc certname;
139 logmsg(
who,111,FATAL,
"out of memory");
142 logmsg(
who,111,FATAL,
"out of timestamps");
154 for (i = 0;i < 100;++i) {
157 if (ch < 33) ch =
'?';
158 if (ch > 126) ch =
'?';
159 if (ch ==
'%') ch =
'?';
164 void env(
const char *s,
const char *t) {
174 static void env_def() {
181 if (!stralloc_cats(&
envplus,
""))
return;
184 for (i = 0; environ[i]; ++i)
186 for (i = 0; i <
envplus.len; ++i)
190 e = (
char **) alloc((elen + 1) *
sizeof(
char *));
194 for (i = 0; environ[i]; ++i)
195 e[elen++] = environ[i];
198 for (i = 0; i <
envplus.len; ++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] ==
'=') {
220 alloc_free((
char *)
e);
221 logmsg(
who,111,FATAL,
"environ changed");
233 logmsg(
who,111,FATAL,B(
"unable to read: ",(
char *)
fnrules));
236 void found(
char *data,
unsigned int datalen) {
240 while ((next0 = byte_chr(data,datalen,0)) < datalen) {
246 split = str_chr(data + 1,
'=');
247 if (data[1 + split] ==
'=') {
249 env(data + 1,data + 1 + split + 1);
254 data += next0; datalen -= next0;
272 strnum[fmt_ulong(strnum,getpid())] = 0;
277 logmsg(
who,111,FATAL,
"unable to get local address");
282 if (dns_name(&localhostsa,
localip) >= 0)
283 if (localhostsa.len) {
303 if (!ip6_isv4mapped(
localip)) {
312 env(
"TCP6INTERFACE",socket_getifname(
netif));
318 if (dns_name(&remotehostsa,
remoteip) >= 0)
319 if (remotehostsa.len) {
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)) {
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)) {
342 if (!stralloc_0(&tcpremoteinfo))
drop_nomem();
363 strnum[fmt_ulong(strnum,getpid())] = 0;
376 buffer_putflush(buffer_2,tmp.s,tmp.len);
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");
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");
392 strnum[fmt_ulong(strnum,getpid())] = 0;
393 logmsg(
who,110,DROP,B(
"unable to TLS accept for pid:",strnum));
398 strnum[fmt_ulong(strnum,getpid())] = 0;
399 log_who(
who,B(
"tls ",strnum,
" accept "));
405 logmsg(
who,110,ERROR,
"no client certificate");
407 logmsg(
who,110,ERROR,
"missing credentials (CA) or unable to validate client certificate");
410 logmsg(
who,110,ERROR,B(
"client hostname name does not match certificate: ",
remotehost,
" <=> ",certname.s));
418 logmsg(
who,111,FATAL,
"unable to fork ");
420 close(
pi[0]); close(
po[1]);
421 sig_uncatch(sig_child);
422 sig_unblock(sig_child);
424 strnum[fmt_ulong(strnum,getpid())] = 0;
425 logmsg(
who,-99,WARN,B(
"unable to speak TLS for pid: ",strnum));
431 close(
pi[1]); close(
po[0]);
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");
442 socket_ipoptionskill(t);
445 socket_tcpnodelay(t);
449 if (buffer_putsflush(&
b,
banner) == -1)
450 logmsg(
who,111,FATAL,
"unable to print banner");
459 strnum[fmt_ulong(strnum,getpid())] = 0;
463 buffer_putflush(buffer_2,tmp.s,tmp.len);
472 logmsg(
who,100,USAGE,B(
who,
"\
473 [ -1346UXpPhHrRoOdDqQviIeEsS ] \
486 host port program"));
501 strnum2[fmt_ulong(strnum2,
limit)] = 0;
502 log_who(
who,B(
"status: ",strnum,
"/",strnum2));
514 if (pid < 0) logmsg(
who,111,FATAL,
"cannot get pid");
523 while ((pid = wait_nohang(&wstat)) > 0) {
525 strnum[fmt_ulong(strnum,pid)] = 0;
526 strnum2[fmt_ulong(strnum2,wstat)] = 0;
527 log_who(
who,B(
"end ",strnum,
" status ",strnum2));
539 logmsg(
who,111,ERROR,
"unable to read password");
545 int passwd_cb(
char *buff,
int size,
int rwflag,
void *userdata) {
547 logmsg(
who,111,ERROR,
"password too long");
553 void spawn(
int s,
int argc,
char *
const *argv) {
562 sig_uncatch(sig_child);
563 sig_unblock(sig_child);
564 sig_uncatch(sig_term);
565 sig_uncatch(sig_pipe);
568 if (lock_ex(
fdlock) == -1)
569 logmsg(
who,111,FATAL,B(
"unable to lock: ",(
char *)
lockfile));
582 if (t == -1)
continue;
583 if (!
doit(t))
continue;
591 logmsg(
who,111,FATAL,
"unable to fork");
597 int main(
int argc,
char *
const *argv) {
607 struct taia deadline;
611 while ((opt = getopt(argc,argv,
"dDvqQhHrRUXx:t:T:u:g:l:b:B:c:pPoO1346I:EeSsaAf:w:zZM:")) != opteof)
613 case 'b': scan_ulong(optarg,&
backlog);
break;
614 case 'c': scan_ulong(optarg,&
limit);
break;
616 case 'x':
fnrules = optarg;
break;
617 case 'B':
banner = optarg;
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;
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;
653 case 'M': scan_ulong(optarg,&u);
break;
664 else if (str_equal((
char *)
hostname,
":0")) {
671 if (!x[scan_ulong(x,&u)])
674 se = getservbyname(x,
"tcp");
676 logmsg(
who,111,FATAL,B(
"unable to figure out port number for: ",x));
677 uint16_unpack_big((
char*)&se->s_port,&
localport);
680 if ((x = env_get(
"VERIFYDEPTH"))) {
685 if ((x = env_get(
"CAFILE")))
cafile = x;
688 if ((x = env_get(
"CCAFILE")))
ccafile = x;
692 if ((x = env_get(
"CADIR")))
cadir = x;
698 if ((x = env_get(
"CERTFILE")))
certfile = x;
701 if ((x = env_get(
"KEYFILE")))
keyfile = x;
704 if ((x = env_get(
"DHFILE")))
dhfile = x;
707 if ((x = env_get(
"CIPHERS")))
ciphers = x;
711 if (getpgrp() != getpid())
712 logmsg(
who,111,FATAL,
"unable to create process group");
717 logmsg(
who,111,FATAL,B(
"unable to open: ",(
char *)
lockfile));
721 logmsg(
who,111,FATAL,
"unable to create pipe");
728 sig_block(sig_child);
731 sig_ignore(sig_pipe);
736 if (!stralloc_copyb(&addresses,(
char *)V4mappedprefix,12))
drop_nomem();
738 byte_copy(
localip,16,addresses.s);
741 byte_copy(
localip,16,addresses.s);
746 if (!addresses.len) {
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));
751 byte_copy(
localip,16,addresses.s);
753 for (j = 0; j < addresses.len; j += 16) {
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);
760 if (addresses.len < 16)
761 logmsg(
who,111,FATAL,B(
"no IP address for: ",(
char *)
hostname));
768 logmsg(
who,111,FATAL,
"unable to create socket");
773 logmsg(
who,111,FATAL,
"unable to bind");
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");
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");
797 buffer_puts(&
b,
" : ");
799 buffer_puts(&
b,
"\n");
807 if (!
ctx) logmsg(
who,111,FATAL,
"unable to create TLS context");
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");
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");
826 logmsg(
who,111,ERROR,
"unable to load CA list");
829 logmsg(
who,111,ERROR,
"unable to load client CA list");
832 logmsg(
who,111,ERROR,
"unable to set RSA parameters");
834 logmsg(
who,111,ERROR,
"unable to set DH parameters");
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");
844 logmsg(
who,111,ERROR,
"unable to set cipher list");
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));
854 log_who(
who,B(
"cert ",strnum,
" ",(
char *)
certfile));
855 log_who(
who,B(
"key ",strnum,
" ",(
char *)
keyfile));
857 log_who(
who,B(
"dhparam ",strnum,
" ",(
char *)
dhfile,
" ",strnum2));
865 int pause_ret, read_ret;
868 sig_unblock(sig_child);
870 io[0].events = IOPAUSE_READ;
872 taia_uint(&deadline,3600);
873 taia_add(&deadline,&stamp,&deadline);
874 pause_ret = iopause(io,1,&deadline,&stamp);
875 sig_block(sig_child);
878 while ((read_ret = buffer_unixread(
selfpipe[0],&ch,1)) == 1)
880 if ((pause_ret > 0) && (read_ret == 0)) {
const char auto_ccafile[]
const char auto_certchainfile[]
const char auto_certfile[]
const char auto_ciphers[]
const char auto_keyfile[]
int remoteinfo(stralloc *out, char ipremote[16], uint16 portremote, char iplocal[16], uint16 portlocal, unsigned int timeout, uint32 netif)
int rules(void(*callback)(char *, unsigned int), int fd, char *ip, char *host, char *info)
int ssl_ca(SSL_CTX *ctx, const char *certfile, const char *certdir, int d)
int ssl_cca(SSL_CTX *ctx, const char *certfile)
int ssl_certkey(SSL_CTX *ctx, const char *certfile, const char *keyfile, pem_password_cb *passwd_cb)
int ssl_chainfile(SSL_CTX *ctx, const char *certchainfile, const char *keyfile, pem_password_cb *passwd_cb)
int ssl_ciphers(SSL_CTX *ctx, const char *ciphers)
int ssl_server_env(SSL *ssl, stralloc *sa)
int ssl_error(int(*op)(const char *))
int ssl_io(SSL *ssl, int fdleft, int fdright, unsigned int timeout)
SSL * ssl_new(SSL_CTX *ctx, int s)
int ssl_params_dh(SSL_CTX *ctx, const char *dhfile)
int ssl_params_rsa(SSL_CTX *ctx, int len)
int ssl_timeoutaccept(SSL *ssl, unsigned int timeout)
int ssl_verify(SSL *ssl, const char *hostname, stralloc *dnsout)
void server(int argcs, char *const *argvs)
void found(char *data, unsigned int datalen)
char remoteportstr[FMT_ULONG]
char localportstr[FMT_ULONG]
char remoteipstr[IP6_FMT]
const char * certchainfile
void env(const char *s, const char *t)
unsigned long numchildren
void append(const char *ch)
void safecats(const char *s)
int main(int argc, char *const *argv)
int passwd_cb(char *buff, int size, int rwflag, void *userdata)
void spawn(int s, int argc, char *const *argv)
int error_warn(const char *x)
Header file to be used with sqmail; previously called ssl.h. (name clash)