52extern void server(
int argcs,
char * 
const *argvs);
 
   74static stralloc tcpremoteinfo = {0};
 
   78char localip[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
 
   80static stralloc localhostsa;
 
   89static stralloc remotehostsa;
 
   95static char strnum[FMT_ULONG];
 
   96static char strnum2[FMT_ULONG];
 
  100static stralloc addresses;
 
  101static stralloc certname;
 
  142  logmsg(
who,111,FATAL,
"out of memory");
 
 
  146  logmsg(
who,111,FATAL,
"out of timestamps");
 
 
  161  for (i = 0;i < 100;++i) {
 
  164    if (ch < 33) ch = 
'?';
 
  165    if (ch > 126) ch = 
'?';
 
  166    if (ch == 
'%') ch = 
'?'; 
 
 
  171void env(
const char *s,
const char *t) 
 
 
  182static void env_def() {
 
  189  if (!stralloc_cats(&
envplus,
"")) 
return;
 
  192  for (i = 0; environ[i]; ++i)
 
  194  for (i = 0; i < 
envplus.len; ++i)
 
  198  e = (
char **) alloc((elen + 1) * 
sizeof(
char *));
 
  202  for (i = 0; environ[i]; ++i)
 
  203    e[elen++] = environ[i];
 
  206  for (i = 0; i < 
envplus.len; ++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] == 
'=') {
 
  229      alloc_free((
char *)
e);
 
  230      logmsg(
who,111,FATAL,
"environ changed");
 
 
  245  logmsg(
who,111,FATAL,B(
"unable to read: ",fnbase));
 
 
  248void found(
char *data,
unsigned int datalen) 
 
  255  while ((next0 = byte_chr(data,datalen,0)) < datalen) {
 
  262              split = str_chr(data + 1,
'=');
 
  263              if (data[1 + split] == 
'=') {
 
  265                env(data + 1,data + 1 + split + 1);
 
  270    data += next0; datalen -= next0;
 
 
  289    strnum[fmt_ulong(strnum,getpid())] = 0;
 
  294    logmsg(
who,111,FATAL,
"unable to get local address");
 
  299    if (dns_name(&localhostsa,
localip) >= 0)
 
  300      if (localhostsa.len) {
 
  324    if (dns_name(&remotehostsa,
remoteip) >= 0)
 
  325      if (remotehostsa.len) {
 
  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)) {
 
  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)) {
 
  349    if (!stralloc_0(&tcpremoteinfo)) 
drop_nomem();
 
  385    if (!ip6_isv4mapped(
localip)) {
 
  394        env(
"TCP6INTERFACE",socket_getifname(
netif));
 
  402    strnum[fmt_ulong(strnum,getpid())] = 0;
 
  415    buffer_putflush(buffer_2,tmp.s,tmp.len);
 
  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");
 
  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");
 
  431    strnum[fmt_ulong(strnum,getpid())] = 0;
 
  432    logmsg(
who,110,DROP,B(
"unable to TLS accept for pid:",strnum));
 
  437    strnum[fmt_ulong(strnum,getpid())] = 0;
 
  438    log_who(
who,B(
"tls ",strnum,
" accept "));
 
  444        logmsg(
who,110,ERROR,
"no client certificate");
 
  446        logmsg(
who,110,ERROR,
"missing credentials (CA) or unable to validate client certificate");
 
  449        logmsg(
who,110,ERROR,B(
"client hostname name does not match certificate: ",
remotehost,
" <=> ",certname.s));
 
  457      logmsg(
who,111,FATAL,
"unable to fork ");
 
  459      close(
pi[0]); close(
po[1]);
 
  460      sig_uncatch(sig_child);
 
  461      sig_unblock(sig_child);
 
  463        strnum[fmt_ulong(strnum,getpid())] = 0;
 
  464        logmsg(
who,-99,WARN,B(
"unable to speak TLS for pid: ",strnum));
 
  470  close(
pi[1]); close(
po[0]);
 
  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");
 
  481    socket_ipoptionskill(t);
 
  484    socket_tcpnodelay(t);
 
  488    if (buffer_putsflush(&
b,
banner) == -1)
 
  489      logmsg(
who,111,FATAL,
"unable to print banner");
 
 
  499    strnum[fmt_ulong(strnum,getpid())] = 0;
 
  503    buffer_putflush(buffer_2,tmp.s,tmp.len);
 
 
  512  logmsg(
who,100,USAGE,B(
who,
"\ 
  513[ -1346UXpPhHrRoOdDqQviIeEsS ] \ 
 
  542  strnum2[fmt_ulong(strnum2,
limit)] = 0;
 
  543  log_who(
who,B(
"status: ",strnum,
"/",strnum2));
 
 
  557  if (pid < 0) logmsg(
who,111,FATAL,
"cannot get pid");
 
 
  567  while ((pid = wait_nohang(&wstat)) > 0) {
 
  569      strnum[fmt_ulong(strnum,pid)] = 0;
 
  570      strnum2[fmt_ulong(strnum2,wstat)] = 0;
 
  571      log_who(
who,B(
"end ",strnum,
" status ",strnum2));
 
 
  584      logmsg(
who,111,ERROR,
"unable to read password");
 
 
  590int passwd_cb(
char *buff,
int size,
int rwflag,
void *userdata) 
 
  593    logmsg(
who,111,ERROR,
"password too long");
 
 
  599void spawn(
int s,
int argc,
char * 
const *argv) 
 
  609        sig_uncatch(sig_child);
 
  610        sig_unblock(sig_child);
 
  611        sig_uncatch(sig_term);
 
  612        sig_uncatch(sig_pipe);
 
  615            if (lock_ex(
fdlock) == -1)
 
  616              logmsg(
who,111,FATAL,B(
"unable to lock: ",(
char *)
lockfile));
 
  629          if (t == -1) 
continue;
 
  630          if (!
doit(t)) 
continue;
 
  638        logmsg(
who,111,FATAL,
"unable to fork");
 
 
  644int main(
int argc,
char * 
const *argv) 
 
  654  struct taia deadline;
 
  659  while ((opt = getoptb(argc,argv,
"dDvqQhHrRUXx:y:t:T:u:g:l:b:B:c:pPoO1346I:EeSsaAf:w:zZ")) != opteof)
 
  661      case 'b': scan_ulong(optarg,&
backlog); 
break;
 
  662      case 'c': scan_ulong(optarg,&
limit); 
break;
 
  664      case 'x': 
fnrules = optarg; 
break;
 
  666      case 'B': 
banner = optarg; 
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;
 
  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;
 
  712  else if (str_equal((
char *)
hostname,
":0")) {
 
  719  if (!x[scan_ulong(x,&u)])
 
  722    se = getservbyname(x,
"tcp");
 
  724      logmsg(
who,111,FATAL,B(
"unable to figure out port number for: ",x));
 
  725    uint16_unpack_big((
char*)&se->s_port,&
localport);
 
  728  if ((x = env_get(
"VERIFYDEPTH"))) {
 
  733  if ((x = env_get(
"CAFILE"))) 
cafile = x;
 
  736  if ((x = env_get(
"CCAFILE"))) 
ccafile = x;
 
  740  if ((x = env_get(
"CADIR"))) 
cadir = x;
 
  746  if ((x = env_get(
"CERTFILE"))) 
certfile = x;
 
  749  if ((x = env_get(
"KEYFILE"))) 
keyfile = x;
 
  752  if ((x = env_get(
"DHFILE"))) 
dhfile = x;
 
  755  if ((x = env_get(
"CIPHERS"))) 
ciphers = x;
 
  759    if (getpgrp() != getpid())
 
  760      logmsg(
who,111,FATAL,
"unable to create process group");
 
  765      logmsg(
who,111,FATAL,B(
"unable to open: ",(
char *)
lockfile));
 
  769    logmsg(
who,111,FATAL,
"unable to create pipe");
 
  776  sig_block(sig_child);
 
  779  sig_ignore(sig_pipe);
 
  784    if (!stralloc_copyb(&addresses,(
char *)V4mappedprefix,12)) 
drop_nomem();
 
  786    byte_copy(
localip,16,addresses.s);
 
  789      byte_copy(
localip,16,addresses.s);
 
  794  if (!addresses.len) {
 
  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));
 
  799    byte_copy(
localip,16,addresses.s);
 
  801    for (j = 0; j < addresses.len; j += 16) {  
 
  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);
 
  808  if (addresses.len < 16)
 
  809    logmsg(
who,111,FATAL,B(
"no IP address for: ",(
char *)
hostname));
 
  816    logmsg(
who,111,FATAL,
"unable to create socket");
 
  821    logmsg(
who,111,FATAL,
"unable to bind");
 
  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");
 
  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");
 
  845    buffer_puts(&
b,
" : ");
 
  847    buffer_puts(&
b,
"\n");
 
  855  if (!
ctx) logmsg(
who,111,FATAL,
"unable to create TLS context");
 
  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");
 
  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");
 
  875      logmsg(
who,111,ERROR,
"unable to load CA list");
 
  877      logmsg(
who,111,ERROR,
"unable to load client CA list");
 
  880    logmsg(
who,111,ERROR,
"unable to set RSA parameters");
 
  882    logmsg(
who,111,ERROR,
"unable to set DH parameters");
 
  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");
 
  892    logmsg(
who,111,ERROR,
"unable to set cipher list");
 
  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));
 
  902    log_who(
who,B(
"cert ",strnum,
" ",(
char *)
certfile));
 
  903    log_who(
who,B(
"key ",strnum,
" ",(
char *)
keyfile));
 
  905    log_who(
who,B(
"dhparam ",strnum,
" ",(
char *)
dhfile,
" ",strnum2));
 
  913    int pause_ret, read_ret;
 
  916    sig_unblock(sig_child);
 
  918    io[0].events = IOPAUSE_READ;
 
  920    taia_uint(&deadline,3600);
 
  921    taia_add(&deadline,&stamp,&deadline);
 
  922    pause_ret = iopause(io,1,&deadline,&stamp);
 
  923    sig_block(sig_child);
 
  926    while ((read_ret = buffer_unixread(
selfpipe[0],&ch,1)) == 1)
 
  928    if ((pause_ret > 0) && (read_ret == 0)) {
 
 
char bspace[BUFFER_SMALL]
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)
int passwd_cb(char *buf, int size, int rwflag, void *userdata)
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 drop_rules(const char *fnbase)
void append(const char *ch)
void safecats(const char *s)
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)