aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmail-smtpc/qmail-smtpc.c
blob: 0e0b11bf52c72e1b721de97f5e347a622b3bb607 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* ISC license. */

#include <string.h>
#include <stdint.h>
#include <unistd.h>

#include <skalibs/cdb.h>
#include <skalibs/stralloc.h>
#include <skalibs/sig.h>
#include <skalibs/tai.h>
#include <skalibs/ip46.h>

#include <smtpd-starttls-proxy/config.h>
#include "qmailr.h"
#include "qmail-smtpc.h"

#define dieusage() qmailr_perm("qmail-remote was invoked improperly")

int main (int argc, char const *const *argv)
{
  stralloc storage = STRALLOC_ZERO ;
  stralloc ipme4 = STRALLOC_ZERO ;
  stralloc ipme6 = STRALLOC_ZERO ;
  qmailr_tls qt = QMAILR_TLS_ZERO ;
  smtproutes routes = SMTPROUTES_ZERO ;
  unsigned int timeoutconnect = 60, timeoutremote = 1200 ;
  char const *host ;
  size_t mepos, helopos, hostpos = 0 ;
  uint16_t port = 25 ;
  int r ;

  if (argc-- < 4) dieusage() ;
  argv++ ;
  if (chdir(SMTPD_STARTTLS_PROXY_QMAIL_HOME) == -1) qmailr_temp("Unable to chdir to " SMTPD_STARTTLS_PROXY_QMAIL_HOME) ;
  if (sig_altignore(SIGPIPE) == -1) qmailr_tempsys("Unable to ignore SIGPIPE") ;
  host = *argv++ ; argc-- ;
  tain_now_set_stopwatch_g() ;


 /* init control */

  r = qmailr_control_read("control/me", &storage, &mepos) ;
  if (r == -1) qmailr_tempsys("Unable to read control/me") ;
  else if (!r) qmailr_temp("Invalid control/me") ;

  r = qmailr_control_read("control/helohost", &storage, &helopos) ;
  if (r == -1) qmailr_tempsys("Unable to read control/helohost") ;
  else if (!r) helopos = mepos ;

  r = qmailr_control_readint("control/timeoutconnect", &timeoutconnect, &storage) ;
  if (r == -1) qmailr_tempsys("Unable to read control/timeoutconnect") ;
  r = qmailr_control_readint("control/timeoutremote", &timeoutremote, &storage) ;
  if (r == -1) qmailr_tempsys("Unable to read control/timeoutremote") ;

  if (!qmailr_control_readiplist("control/ipme", &ipme4, &ipme6))
    qmailr_tempsys("Unable to read control/ipme") ;
  stralloc_shrink(&ipme4) ;
  stralloc_shrink(&ipme6) ;
  qsort(ipme4.s, ipme4.len >> 2, 4, &qmailr_memcmp4) ;
  qsort(ipme6.s, ipme6.len >> 4, 16, &qmailr_memcmp16) ;

  if (!qmailr_tls_init(&qt, &storage))
    qmailr_tempsys("Unable to read TLS control files") ;

  if (smtproutes_init(&routes))
  {
    if (!smtproutes_match(&routes, host, &storage, &hostpos, &port))
    {
      size_t hostlen = strlen(host) ;
      for (size_t i = 0 ; i < hostlen ; i++) if (host[i] == '.')
        if (smtproutes_match(&routes, argv[1], &storage, &hostpos, &port)) break ;
      if (!hostpos) smtproutes_match(&routes, "", &storage, &hostpos, &port) ;
    }
    smtproutes_free(&routes) ;
  }

  {
    genalloc mxipind = GENALLOC_ZERO ;
    size_t eaddrpos[argc] ;
    dns_stuff(hostpos ? storage.s + hostpos : host, argv, argc, eaddrpos, &mxipind, &storage, timeoutconnect, ipme4.s, ipme4.len >> 2, ipme6.s, ipme6.len >> 4, !hostpos) ;

  }


  _exit(0) ;
}