Пример #1
0
sfsistat mlfi_data(SMFICTX * ctx)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);
	char *msgid;

	/* In Postfix, the Sendmail macro 'i' is only available in the DATA,
	   EOH, and EOM milter protocol stages so we try get the msgid again */
	if (priv->msgid != NULL)
		goto check;

	msgid = smfi_getsymval(ctx, "{i}");
	if (msgid != NULL) {
		priv->msgid = strdup(msgid);
		if (priv->msgid == NULL) {
			mlog(LOG_ERR, "%s: %s: Memory allocation failed",
			     priv->connectfrom, "mlfi_data()");
			mlfi_cleanup(ctx);
			return SMFIS_TEMPFAIL;
		}
	}

check:
	if (priv->check != 0)
		return mlfi_dnslcheck(ctx);

	/* continue processing */
	return SMFIS_CONTINUE;
}
Пример #2
0
sfsistat mlfi_eom(SMFICTX * ctx)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);

	if (config.stamp == 0)
		return mlfi_cleanup(ctx);

	switch (priv->stamp) {
	case STAMP_PASSED:
		smfi_addheader(ctx, "X-DNSBL-MILTER", "Passed");
		break;
	case STAMP_WHITELISTED:
		smfi_addheader(ctx, "X-DNSBL-MILTER", "Whitelisted");
		break;
	case STAMP_SKIPPED:
		smfi_addheader(ctx, "X-DNSBL-MILTER", "Skipped");
		break;
	case STAMP_BLACKLISTED:
		smfi_addheader(ctx, "X-DNSBL-MILTER", "Blacklisted");
		break;
	default:
		smfi_addheader(ctx, "X-DNSBL-MILTER", "Unknown error");
		break;
	}

	return mlfi_cleanup(ctx);
}
Пример #3
0
sfsistat mlfi_envfrom(SMFICTX * ctx, char **argv)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);
	char *msgid;

	/* SMTP Authenticated. Skip DNS blacklist checks */
	if (smfi_getsymval(ctx, "{auth_type}") != NULL)
		return SMFIS_ACCEPT;

	/* store message ID */
	msgid = smfi_getsymval(ctx, "{i}");
	if (msgid != NULL) {
		priv->msgid = strdup(msgid);
		if (priv->msgid == NULL) {
			mlog(LOG_ERR, "%s: %s: Memory allocation failed",
			     priv->connectfrom, "mlfi_envfrom()");
			mlfi_cleanup(ctx);
			return SMFIS_TEMPFAIL;
		}
	}

	else
		priv->msgid = NULL;

	/* store sender's address */
	priv->envfrom = strdup(argv[0]);
	if (priv->envfrom == NULL) {
		mlog(LOG_ERR, "%s: %s: Memory allocation failed",
		     (priv->msgid != NULL)? priv->msgid : priv->connectfrom,
		     "mlfi_envfrom()");
		mlfi_cleanup(ctx);
		return SMFIS_TEMPFAIL;
	}

#if SMFI_VERSION > 3
	/* null-envelope sender address, defer DNS checks till mlfi_data() */
	if (strncmp(argv[0], "<>\0", 3) == 0) {
#ifdef DEBUG
		mlog(LOG_DEBUG,
		     "%s: Null-envelope sender address, deferring",
		     (priv->msgid != NULL)? priv->msgid : priv->connectfrom);
#endif
		priv->check = 1;
		return SMFIS_CONTINUE;
	}
#endif

	priv->check = 0;
	return mlfi_dnslcheck(ctx);
}
Пример #4
0
sfsistat mlfi_close(SMFICTX * ctx)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);

	if (priv == NULL)
		return SMFIS_CONTINUE;

	/* mlfi_connectfrom() */
	if (priv->connectfrom != NULL) {
		free(priv->connectfrom);
		priv->connectfrom = NULL;
	}

	free(priv);
	priv = NULL;
	smfi_setpriv(ctx, NULL);

	/* continue processing */
	return SMFIS_CONTINUE;
}
Пример #5
0
static sfsistat mlfi_cleanup(SMFICTX * ctx)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);

	if (priv == NULL)
		return SMFIS_CONTINUE;

	/* mlfi_envfrom() */
	if (priv->msgid != NULL) {
		free(priv->msgid);
		priv->msgid = NULL;
	}

	if (priv->envfrom != NULL) {
		free(priv->envfrom);
		priv->envfrom = NULL;
	}

	/* continue processing */
	return SMFIS_CONTINUE;
}
Пример #6
0
void StackWalk(native_t * callstack, Context * pContext)
{
	HANDLE hProcess = GetCurrentProcess();
	HANDLE hThread  = GetCurrentThread();

	CONTEXT context = {0};
	STACKFRAME64 frame = {0};
	DWORD machine = 0;
	DWORD i = 0;
	if (NULL == pContext)
	{
		GETCONTEXT(context);
	}
	else
	{
#ifdef CPU_X86
		context.Eip = (uint32_t) pContext->InstructionPointer;
		context.Esp = (uint32_t) pContext->StackFramePointer;
		context.Ebp = (uint32_t) pContext->StackBasePointer;
#endif /* CPU_X86 */
#ifdef CPU_X64
		context.Rip = (uint32_t) pContext->InstructionPointer;
		context.Rsp = (uint32_t) pContext->StackFramePointer;
		context.Rbp = (uint32_t) pContext->StackBasePointer;
#endif /* CPU_X64 */
	}
	context.ContextFlags = CONTEXT_FULL;
#ifdef CPU_X86
	machine = IMAGE_FILE_MACHINE_I386;
	frame.AddrPC.Offset    = context.Eip;
	frame.AddrPC.Mode      = AddrModeFlat;
	frame.AddrFrame.Offset = context.Ebp;
	frame.AddrFrame.Mode   = AddrModeFlat;
	frame.AddrStack.Offset = context.Esp;
	frame.AddrStack.Mode   = AddrModeFlat;
#endif /* CPU_X86 */
#ifdef CPU_X64
	machine = IMAGE_FILE_MACHINE_AMD64;
	frame.AddrPC.Offset    = context.Rip;
	frame.AddrPC.Mode      = AddrModeFlat;
	frame.AddrFrame.Offset = context.Rbp;
	frame.AddrFrame.Mode   = AddrModeFlat;
	frame.AddrStack.Offset = context.Rsp;
	frame.AddrStack.Mode   = AddrModeFlat;
#endif /* CPU_X64 */
#ifdef CPU_IA64
	machine = IMAGE_FILE_MACHINE_IA64;
#endif /* CPU_IA64 */
	memset(callstack, 0, sizeof(native_t) * MaxCallStack);
	for (i = 0; i < MaxCallStack; ++i)
	{
		if (!pStackWalk64(machine, hProcess, hThread, &frame, &context, NULL, pSymFunctionTableAccess64, pSymGetModuleBase64, NULL))
		{
			break;
		}
		if (0 == frame.AddrReturn.Offset)
		{
			break;
		}
		if (0 != frame.AddrPC.Offset)
		{
			callstack[i] = (native_t) frame.AddrPC.Offset;
		}
	}
}
Пример #7
0
static sfsistat mlfi_dnslcheck(SMFICTX * ctx)
{
	struct mlfiPriv *priv = GETCONTEXT(ctx);
	struct listNode *blp;
	uint8_t blisted;
	struct listNode *wlp;
	uint8_t wlisted;
	size_t len;
	char *msg;

	uint8_t a = (priv->hostaddr & 0xff000000) >> 24;
	uint8_t b = (priv->hostaddr & 0x00ff0000) >> 16;
	uint8_t c = (priv->hostaddr & 0x0000ff00) >> 8;
	uint8_t d = (priv->hostaddr & 0x000000ff);

	switch (a) {

		/* Loopback */
	case 127:
		priv->stamp = STAMP_SKIPPED;
		return SMFIS_CONTINUE;
		break;

		/* RFC1910 (Private networks) */
	case 10:		/* Class A (10.0.0.0/8) */
		priv->stamp = STAMP_SKIPPED;
		return SMFIS_CONTINUE;
		break;
	case 172:
		/* Class B (172.16.0.0/12) */
		if ((b & 0xf0) == 0x10) {
			priv->stamp = STAMP_SKIPPED;
			return SMFIS_CONTINUE;
		}
		break;
	case 192:
		/* Class C (192.168.0.0/16) */
		if (b == 168) {
			priv->stamp = STAMP_SKIPPED;
			return SMFIS_CONTINUE;
		}
		break;

	default:
		break;
	}

	/* blacklist */
	blp = blacklist;
	blisted = 0;
	while ((blp != NULL) && (blisted == 0)) {
#ifdef DEBUG
		mlog(LOG_DEBUG, "%s: Looking up %u.%u.%u.%u.%s.",
		     (priv->msgid != NULL)? priv->msgid : priv->connectfrom,
		     d, c, b, a, blp->dnsl);
#endif

		if (dns_check(a, b, c, d, blp->dnsl) == DNSL_EXIST) {
			mlog(LOG_INFO,
			     "%s: %s [%u.%u.%u.%u] is blacklisted on %s",
			     (priv->msgid != NULL)? priv->msgid
			     : priv->connectfrom, priv->connectfrom,
			     a, b, c, d, blp->dnsl);
			blisted = 1;
		} else
			blp = blp->next;
	}

	if (blisted == 0) {
		priv->stamp = STAMP_PASSED;
		return SMFIS_CONTINUE;
	}

	/* whitelist */
	wlp = whitelist;
	wlisted = 0;
	while ((wlp != NULL) && (wlisted == 0)) {
#ifdef DEBUG
		mlog(LOG_DEBUG, "%s: Looking up %u.%u.%u.%u.%s.",
		     (priv->msgid != NULL)? priv->msgid : priv->connectfrom,
		     d, c, b, a, wlp->dnsl);
#endif

		if (dns_check(a, b, c, d, wlp->dnsl) == DNSL_EXIST) {
			mlog(LOG_INFO,
			     "%s: %s [%u.%u.%u.%u] is whitelisted on %s",
			     (priv->msgid != NULL)? priv->msgid
			     : priv->connectfrom, priv->connectfrom,
			     a, b, c, d, wlp->dnsl);
			wlisted = 1;
		} else
			wlp = wlp->next;
	}

	if (wlisted != 0) {
		priv->stamp = STAMP_WHITELISTED;
		return SMFIS_CONTINUE;
	}

	priv->stamp = STAMP_BLACKLISTED;
	if(config.drymode)
		return SMFIS_CONTINUE;

	/* "Client address [aaa.bbb.ccc.ddd] blocked. " + msg + "aaa.bbb.ccc.ddd"
	   + '\0' */
	len = 43 + strlen(blp->msg) + 15 + 1;
	msg = malloc(len);
	if (msg == NULL) {
		mlog(LOG_ERR, "%s: %s: Memory allocation failed",
		     (priv->msgid != NULL)? priv->msgid : priv->connectfrom,
		     "mlfi_dnslcheck()");
		smfi_setreply(ctx, "550", "5.7.1", blp->msg);
	} else {
		snprintf(msg, len,
			 "Client address [%u.%u.%u.%u] blocked. %s%u.%u.%u.%u",
			 (unsigned int) a, (unsigned int) b,
			 (unsigned int) c, (unsigned int) d, blp->msg,
			 (unsigned int) a, (unsigned int) b,
			 (unsigned int) c, (unsigned int) d);
		smfi_setreply(ctx, "550", "5.7.1", msg);
		free(msg);
		msg = NULL;
	}

	mlfi_cleanup(ctx);
	return SMFIS_REJECT;
}