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; }
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); }
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); }
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; }
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; }
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; } } }
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; }