1
0
Fork 0
qmail/tcp-env.c
MAILER-DAEMON 69cea49034 Makes qmail-smtpd with AUTH support plus SPF and DKIM.
This is the qmail that we're currently running at antartida.xyz.  We
took the notqmail repository and essentially applied patches for AUTH,
SPF and DKIM.

The DKIM patch does not come from the notqmail repository.  We took it
from the excellent notes at

  https://www.memoryhole.net/qmail/

We also applied the any-to-cname patch.  But we did not take the
oversize-dns patch.  Any mistakes here are mine---I had to merge it as
best we could and resolve various conflicts.

This is it. -- MAILER DAEMON :)

(*) Commit message from the notqmail branch

Remove FILES.auth, add new files to FILES.

Realphabetize Makefile targets.  Remove trailing whitespace variously.

Remove duplication declaration of auth in qmail-smtpd.c

Modification to Erwin Hoffmann's SMTP authentication for qmail-smtpd,
qmail-remote.

Apply Jana Saout's qmail-spf-rc5.patch

From https://www.saout.de/misc/spf/

This is an SPF implementation for qmail.

SPF is something like a DNS based "reverse MX" system to designate
permitted senders for mails depending on the domain name. The goal
is to disallow sender address forgery.

The patch is entirely written using the qmail string and DNS
functions, and thus completely integrated into qmail without
external dependencies.

It can check incoming mails inside the SMTP daemon, add Received-SPF
lines and optionally block undesired transfers. The check is
performed at the envelope level.
2024-11-24 13:20:39 -03:00

133 lines
3.1 KiB
C

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/param.h>
#include <netinet/in.h>
#include "sig.h"
#include "stralloc.h"
#include "str.h"
#include "env.h"
#include "fmt.h"
#include "scan.h"
#include "subgetopt.h"
#include "ip.h"
#include "strsalloc.h"
#include "dns.h"
#include "byte.h"
#include "remoteinfo.h"
#include "exit.h"
#include "case.h"
void die() { _exit(111); }
struct sockaddr_in salocal;
unsigned long localport;
struct ip_address iplocal;
stralloc localname = {0};
struct sockaddr_in saremote;
unsigned long remoteport;
struct ip_address ipremote;
stralloc remotename = {0};
char temp[IPFMT + FMT_ULONG];
void main(argc,argv)
int argc;
char *argv[];
{
strsalloc ssa = {0};
int dummy;
char *proto;
int opt;
int flagremoteinfo;
unsigned long timeout;
sig_pipeignore();
flagremoteinfo = 1;
timeout = 30;
while ((opt = sgopt(argc,argv,"rRt:")) != sgoptdone)
switch(opt)
{
case 'r': flagremoteinfo = 1; break;
case 'R': flagremoteinfo = 0; break;
case 't': scan_ulong(sgoptarg,&timeout); break;
}
argv += sgoptind;
argc -= sgoptind;
if (argc < 1) die();
if (!env_init()) die();
proto = env_get("PROTO");
if (!proto || str_diff(proto,"TCP"))
{
if (!env_put("PROTO=TCP")) die();
dummy = sizeof(salocal);
if (getsockname(0,(struct sockaddr *) &salocal,&dummy) == -1) die();
localport = ntohs(salocal.sin_port);
temp[fmt_ulong(temp,localport)] = 0;
if (!env_put2("TCPLOCALPORT",temp)) die();
byte_copy(&iplocal,4,&salocal.sin_addr);
temp[ip_fmt(temp,&iplocal)] = 0;
if (!env_put2("TCPLOCALIP",temp)) die();
switch(dns_ptr(&ssa,&iplocal))
{
case DNS_MEM: die();
case DNS_SOFT:
if (!stralloc_copys(&localname,"softdnserror")) die();
case 0:
if (!stralloc_copy(&localname,&ssa.sa[0])) die();
if (!stralloc_0(&localname)) die();
case_lowers(localname.s);
if (!env_put2("TCPLOCALHOST",localname.s)) die();
break;
default:
if (!env_unset("TCPLOCALHOST")) die();
}
dummy = sizeof(saremote);
if (getpeername(0,(struct sockaddr *) &saremote,&dummy) == -1) die();
remoteport = ntohs(saremote.sin_port);
temp[fmt_ulong(temp,remoteport)] = 0;
if (!env_put2("TCPREMOTEPORT",temp)) die();
byte_copy(&ipremote,4,&saremote.sin_addr);
temp[ip_fmt(temp,&ipremote)] = 0;
if (!env_put2("TCPREMOTEIP",temp)) die();
switch(dns_ptr(&ssa,&ipremote))
{
case DNS_MEM: die();
case DNS_SOFT:
if (!stralloc_copys(&remotename,"softdnserror")) die();
case 0:
if (!stralloc_copy(&remotename,&ssa.sa[0])) die();
if (!stralloc_0(&remotename)) die();
case_lowers(remotename.s);
if (!env_put2("TCPREMOTEHOST",remotename.s)) die();
break;
default:
if (!env_unset("TCPREMOTEHOST")) die();
}
if (!env_unset("TCPREMOTEINFO")) die();
if (flagremoteinfo)
{
char *rinfo;
rinfo = remoteinfo_get(&ipremote,remoteport,&iplocal,localport,(int) timeout);
if (rinfo)
if (!env_put2("TCPREMOTEINFO",rinfo)) die();
}
}
sig_pipedefault();
execvp(*argv,argv);
die();
}