#include "common.h"
#include "smtpd.h"
#include "smtp.h"
#include <ctype.h>
#include <ip.h>
#include <ndb.h>

typedef struct {
	int	existed;	/* these two are distinct to cope with errors */
	int	created;
	int	noperm;
	long	mtime;		/* mod time, iff it already existed */
} Greysts;

/*
 * There's a bit of a problem with yahoo; they apparently have a vast
 * pool of machines that all run the same queue(s), so a 451 retry can
 * come from a different IP address for many, many retries, and it can
 * take ~5 hours for the same IP to call us back.  Various other goofballs,
 * notably the IEEE, try to send mail just before 9 AM, then refuse to try
 * again until after 5 PM.  Doh!
 */
enum {
	Nonspammax = 14*60*60,  /* must call back within this time if real */
};
static char whitelist[] = "/mail/lib/whitelist";

/*
 * matches ip addresses or subnets in whitelist against nci->rsys.
 * ignores comments and blank lines in /mail/lib/whitelist.
 */
static int
onwhitelist(void)
{
	int lnlen;
	char *line, *parse;
	char input[128];
	uchar ip[IPaddrlen], ipmasked[IPaddrlen];
	uchar mask4[IPaddrlen], addr4[IPaddrlen];
	uchar mask[IPaddrlen], addr[IPaddrlen], addrmasked[IPaddrlen];
	Biobuf *wl;
	static int beenhere;
	static allzero[IPaddrlen];

	if (!beenhere) {
		beenhere = 1;
		fmtinstall('I', eipfmt);
	}

	parseip(ip, nci->rsys);
	wl = Bopen(whitelist, OREAD);
	if (wl == nil)
		return 1;
	while ((line = Brdline(wl, '\n')) != nil) {
		if (line[0] == '#' || line[0] == '\n')
			continue;
		lnlen = Blinelen(wl);
		line[lnlen-1] = '\0';		/* clobber newline */

		/* default mask is /32 (v4) or /128 (v6) for bare IP */
		parse = line;
		if (strchr(line, '/') == nil) {
			strncpy(input, line, sizeof input - 5);
			if (strchr(line, '.') != nil)
				strcat(input, "/32");
			else
				strcat(input, "/128");
			parse = input;
		}
		/* sorry, dave; where's parsecidr for v4 or v6? */
		v4parsecidr(addr4, mask4, parse);
		v4tov6(addr, addr4);
		v4tov6(mask, mask4);

		maskip(addr, mask, addrmasked);
		maskip(ip, mask, ipmasked);
		if (memcmp(ipmasked, addrmasked, IPaddrlen) == 0)
			break;
	}
	Bterm(wl);
	return line != nil;
}

static int mkdirs(char *);

/*
 * if any directories leading up to path don't exist, create them.
 * modifies but restores path.
 */
static int
mkpdirs(char *path)
{
	int rv = 0;
	char *sl = strrchr(path, '/');

	if (sl != nil) {
		*sl = '\0';
		rv = mkdirs(path);
		*sl = '/';
	}
	return rv;
}

/*
 * if path or any directories leading up to it don't exist, create them.
 * modifies but restores path.
 */
static int
mkdirs(char *path)
{
	int fd;

	if (access(path, AEXIST) >= 0)
		return 0;

	/* make presumed-missing intermediate directories */
	if (mkpdirs(path) < 0)
		return -1;

	/* make final directory */
	fd = create(path, OREAD, 0777|DMDIR);
	if (fd < 0)
		/*
		 * we may have lost a race; if the directory now exists,
		 * it's okay.
		 */
		return access(path, AEXIST) < 0? -1: 0;
	close(fd);
	return 0;
}

static long
getmtime(char *file)
{
	long mtime = -1;
	Dir *ds = dirstat(file);

	if (ds != nil) {
		mtime = ds->mtime;
		free(ds);
	}
	return mtime;
}

static void
tryaddgrey(char *file, Greysts *gsp)
{
	int fd = create(file, OWRITE|OEXCL, 0444|DMEXCL);

	gsp->created = (fd >= 0);
	if (fd >= 0) {
		close(fd);
		gsp->existed = 0;  /* just created; couldn't have existed */
	} else {
		/*
		 * why couldn't we create file? it must have existed
		 * (or we were denied perm on parent dir.).
		 * if it existed, fill in gsp->mtime; otherwise
		 * make presumed-missing intermediate directories.
		 */
		gsp->existed = access(file, AEXIST) >= 0;
		if (gsp->existed)
			gsp->mtime = getmtime(file);
		else if (mkpdirs(file) < 0)
			gsp->noperm = 1;
	}
}

static void
addgreylist(char *file, Greysts *gsp)
{
	tryaddgrey(file, gsp);
	if (!gsp->created && !gsp->existed && !gsp->noperm)
		/* retry the greylist entry with parent dirs created */
		tryaddgrey(file, gsp);
}

static int
recentcall(Greysts *gsp)
{
	long delay = time(0) - gsp->mtime;

	if (!gsp->existed)
		return 0;
	/* reject immediate call-back; spammers are doing that now */
	return delay >= 30 && delay <= Nonspammax;
}

/*
 * policy: if (caller-IP, my-IP, rcpt) is not on the greylist,
 * reject this message as "451 temporary failure".  if the caller is real,
 * he'll retry soon, otherwise he's a spammer.
 * at the first rejection, create a greylist entry for (my-ip, caller-ip,
 * rcpt, time), where time is the file's mtime.  if they call back and there's
 * already a greylist entry, and it's within the allowed interval,
 * add their IP to the append-only whitelist.
 *
 * greylist files can be removed at will; at worst they'll cause a few
 * extra retries.
 */

static int
isrcptrecent(char *rcpt)
{
	char *user;
	char file[256];
	Greysts gs;
	Greysts *gsp = &gs;

	if (rcpt[0] == '\0' || strchr(rcpt, '/') != nil ||
	    strcmp(rcpt, ".") == 0 || strcmp(rcpt, "..") == 0)
		return 0;

	/* shorten names to fit pre-fossil or pre-9p2000 file servers */
	user = strrchr(rcpt, '!');
	if (user == nil)
		user = rcpt;
	else
		user++;

	/* check & try to update the grey list entry */
	snprint(file, sizeof file, "/mail/grey/%s/%s/%s",
		nci->lsys, nci->rsys, user);
	memset(gsp, 0, sizeof *gsp);
	addgreylist(file, gsp);

	/* if on greylist already and prior call was recent, add to whitelist */
	if (gsp->existed && recentcall(gsp)) {
		syslog(0, "smtpd",
			"%s/%s was grey; adding IP to white", nci->rsys, rcpt);
		return 1;
	} else if (gsp->existed)
		syslog(0, "smtpd", "call for %s/%s was seconds ago or long ago",
			nci->rsys, rcpt);
	else
		syslog(0, "smtpd", "no call registered for %s/%s; registering",
			nci->rsys, rcpt);
	return 0;
}

void
vfysenderhostok(void)
{
	char *fqdn;
	int recent = 0;
	Link *l;

	if (onwhitelist())
		return;

	for (l = rcvers.first; l; l = l->next)
		if (isrcptrecent(s_to_c(l->p)))
			recent = 1;

	/* if on greylist already and prior call was recent, add to whitelist */
	if (recent) {
		int fd = create(whitelist, OWRITE, 0666|DMAPPEND);

		if (fd >= 0) {
			seek(fd, 0, 2);			/* paranoia */
			if ((fqdn = csgetvalue(nil, "ip", nci->rsys, "dom", nil)) != nil)
				fprint(fd, "# %s\n%s\n\n", fqdn, nci->rsys);
			else
				fprint(fd, "# unknown\n%s\n\n", nci->rsys);
			close(fd);
		}
	} else {
		syslog(0, "smtpd",
	"no recent call from %s for a rcpt; rejecting with temporary failure",
			nci->rsys);
		reply("451 please try again soon from the same IP.\r\n");
		exits("no recent call for a rcpt");
	}
}
