void psc_free_session_state(PSC_STATE *state) { const char *myname = "psc_free_session_state"; HTABLE_INFO *ht; /* * Update the per-client session count. */ if ((ht = htable_locate(psc_client_concurrency, state->smtp_client_addr)) == 0) msg_panic("%s: unknown client address: %s", myname, state->smtp_client_addr); if (--(ht->value) == 0) htable_delete(psc_client_concurrency, state->smtp_client_addr, (void (*) (char *)) 0); if (state->smtp_client_stream != 0) { event_server_disconnect(state->smtp_client_stream); psc_check_queue_length--; } if (state->smtp_server_fd >= 0) { close(state->smtp_server_fd); psc_post_queue_length--; } if (state->send_buf != 0) state->send_buf = vstring_free(state->send_buf); myfree(state->smtp_client_addr); myfree(state->smtp_client_port); myfree(state->smtp_server_addr); myfree(state->smtp_server_port); if (state->dnsbl_reply) vstring_free(state->dnsbl_reply); if (state->helo_name) myfree(state->helo_name); if (state->sender) myfree(state->sender); if (state->cmd_buffer) vstring_free(state->cmd_buffer); if (state->expand_buf) vstring_free(state->expand_buf); myfree((char *) state); if (psc_check_queue_length < 0 || psc_post_queue_length < 0) msg_panic("bad queue length: check_queue=%d, post_queue=%d", psc_check_queue_length, psc_post_queue_length); /* * Update the stress level. */ if (psc_stress != 0 && psc_check_queue_length <= psc_lowat_check_queue_length) { psc_stress = 0; msg_info("leaving STRESS mode with %d connections", psc_check_queue_length); } }
void tlsp_state_free(TLSP_STATE *state) { myfree(state->service); if (state->plaintext_buf) /* turns off plaintext events */ nbbio_free(state->plaintext_buf); event_server_disconnect(state->plaintext_stream); if (state->ciphertext_fd >= 0) { event_disable_readwrite(state->ciphertext_fd); (void) close(state->ciphertext_fd); } if (state->ciphertext_timer) event_cancel_timer(state->ciphertext_timer, (char *) state); if (state->remote_endpt) { msg_info("DISCONNECT %s", state->remote_endpt); myfree(state->remote_endpt); } if (state->server_id) myfree(state->server_id); if (state->tls_context) tls_free_context(state->tls_context); myfree((char *) state); }
static void tlsp_service(VSTREAM *stream, char *unused_service, char **unused_argv) { msg_info("TLS support is not compiled in -- exiting"); event_server_disconnect(stream); }
static void psc_endpt_lookup_done(int endpt_status, VSTREAM *smtp_client_stream, MAI_HOSTADDR_STR *smtp_client_addr, MAI_SERVPORT_STR *smtp_client_port, MAI_HOSTADDR_STR *smtp_server_addr, MAI_SERVPORT_STR *smtp_server_port) { const char *myname = "psc_endpt_lookup_done"; PSC_STATE *state; const char *stamp_str; int saved_flags; /* * Best effort - if this non-blocking write(2) fails, so be it. */ if (endpt_status < 0) { (void) write(vstream_fileno(smtp_client_stream), "421 4.3.2 No system resources\r\n", sizeof("421 4.3.2 No system resources\r\n") - 1); event_server_disconnect(smtp_client_stream); return; } if (msg_verbose > 1) msg_info("%s: sq=%d cq=%d connect from [%s]:%s", myname, psc_post_queue_length, psc_check_queue_length, smtp_client_addr->buf, smtp_client_port->buf); msg_info("CONNECT from [%s]:%s to [%s]:%s", smtp_client_addr->buf, smtp_client_port->buf, smtp_server_addr->buf, smtp_server_port->buf); /* * Bundle up all the loose session pieces. This zeroes all flags and time * stamps. */ state = psc_new_session_state(smtp_client_stream, smtp_client_addr->buf, smtp_client_port->buf, smtp_server_addr->buf, smtp_server_port->buf); /* * Reply with 421 when the client has too many open connections. */ if (var_psc_cconn_limit > 0 && state->client_concurrency > var_psc_cconn_limit) { msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: too many connections", state->smtp_client_addr, state->smtp_client_port); PSC_DROP_SESSION_STATE(state, "421 4.7.0 Error: too many connections\r\n"); return; } /* * Reply with 421 when we can't forward more connections. */ if (var_psc_post_queue_limit > 0 && psc_post_queue_length >= var_psc_post_queue_limit) { msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: all server ports busy", state->smtp_client_addr, state->smtp_client_port); PSC_DROP_SESSION_STATE(state, "421 4.3.2 All server ports are busy\r\n"); return; } /* * The permanent white/blacklist has highest precedence. */ if (psc_acl != 0) { switch (psc_acl_eval(state, psc_acl, VAR_PSC_ACL)) { /* * Permanently blacklisted. */ case PSC_ACL_ACT_BLACKLIST: msg_info("BLACKLISTED [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_BLIST_FAIL); switch (psc_blist_action) { case PSC_ACT_DROP: PSC_DROP_SESSION_STATE(state, "521 5.3.2 Service currently unavailable\r\n"); return; case PSC_ACT_ENFORCE: PSC_ENFORCE_SESSION_STATE(state, "550 5.3.2 Service currently unavailable\r\n"); break; case PSC_ACT_IGNORE: PSC_UNFAIL_SESSION_STATE(state, PSC_STATE_FLAG_BLIST_FAIL); /* * Not: PSC_PASS_SESSION_STATE. Repeat this test the next * time. */ break; default: msg_panic("%s: unknown blacklist action value %d", myname, psc_blist_action); } break; /* * Permanently whitelisted. */ case PSC_ACL_ACT_WHITELIST: msg_info("WHITELISTED [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); psc_conclude(state); return; /* * Other: dunno (don't know) or error. */ default: break; } } /* * The temporary whitelist (i.e. the postscreen cache) has the lowest * precedence. This cache contains information about the results of prior * tests. Whitelist the client when all enabled test results are still * valid. */ if ((state->flags & PSC_STATE_MASK_ANY_FAIL) == 0 && psc_cache_map != 0 && (stamp_str = psc_cache_lookup(psc_cache_map, state->smtp_client_addr)) != 0) { saved_flags = state->flags; psc_parse_tests(state, stamp_str, event_time()); state->flags |= saved_flags; if (msg_verbose) msg_info("%s: cached + recent flags: %s", myname, psc_print_state_flags(state->flags, myname)); if ((state->flags & PSC_STATE_MASK_ANY_TODO_FAIL) == 0) { msg_info("PASS OLD [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); psc_conclude(state); return; } } else { saved_flags = state->flags; psc_new_tests(state); state->flags |= saved_flags; if (msg_verbose) msg_info("%s: new + recent flags: %s", myname, psc_print_state_flags(state->flags, myname)); } /* * Don't whitelist clients that connect to backup MX addresses. Fail * "closed" on error. */ if (addr_match_list_match(psc_wlist_if, smtp_server_addr->buf) == 0) { state->flags |= (PSC_STATE_FLAG_WLIST_FAIL | PSC_STATE_FLAG_NOFORWARD); msg_info("WHITELIST VETO [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); } /* * Reply with 421 when we can't analyze more connections. That also means * no deep protocol tests when the noforward flag is raised. */ if (var_psc_pre_queue_limit > 0 && psc_check_queue_length - psc_post_queue_length >= var_psc_pre_queue_limit) { msg_info("reject: connect from [%s]:%s: all screening ports busy", state->smtp_client_addr, state->smtp_client_port); PSC_DROP_SESSION_STATE(state, "421 4.3.2 All screening ports are busy\r\n"); return; } /* * If the client has no up-to-date results for some tests, do those tests * first. Otherwise, skip the tests and hand off the connection. */ if (state->flags & PSC_STATE_MASK_EARLY_TODO) psc_early_tests(state); else if (state->flags & (PSC_STATE_MASK_SMTPD_TODO | PSC_STATE_FLAG_NOFORWARD)) psc_smtpd_tests(state); else psc_conclude(state); }