static int new_client_session_cb(SSL *ssl, SSL_SESSION *session) { const char *myname = "new_client_session_cb"; TLS_SESS_STATE *TLScontext; VSTRING *session_data; /* * The cache name (if caching is enabled in tlsmgr(8)) and the cache ID * string for this session are stored in the TLScontext. It cannot be * null at this point. */ if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0) msg_panic("%s: null TLScontext in new session callback", myname); /* * We only get here if the cache_type is not empty. This callback is not * set unless caching is enabled and the cache_type is stored in the * server SSL context. */ if (TLScontext->cache_type == 0) msg_panic("%s: null session cache type in new session callback", myname); if (TLScontext->log_mask & TLS_LOG_CACHE) /* serverid already contains namaddrport information */ msg_info("save session %s to %s cache", TLScontext->serverid, TLScontext->cache_type); #if (OPENSSL_VERSION_NUMBER < 0x00906011L) || (OPENSSL_VERSION_NUMBER == 0x00907000L) /* * Ugly Hack: OpenSSL before 0.9.6a does not store the verify result in * sessions for the client side. We modify the session directly which is * version specific, but this bug is version specific, too. * * READ: 0-09-06-01-1 = 0-9-6-a-beta1: all versions before beta1 have this * bug, it has been fixed during development of 0.9.6a. The development * version of 0.9.7 can have this bug, too. It has been fixed on * 2000/11/29. */ session->verify_result = SSL_get_verify_result(TLScontext->con); #endif /* * Passivate and save the session object. Errors are non-fatal, since * caching is only an optimization. */ if ((session_data = tls_session_passivate(session)) != 0) { tls_mgr_update(TLScontext->cache_type, TLScontext->serverid, STR(session_data), LEN(session_data)); vstring_free(session_data); } /* * Clean up. */ SSL_SESSION_free(session); /* 200502 */ return (1); }
static int new_server_session_cb(SSL *ssl, SSL_SESSION *session) { const char *myname = "new_server_session_cb"; VSTRING *cache_id; TLS_SESS_STATE *TLScontext; VSTRING *session_data; if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0) msg_panic("%s: null TLScontext in new session callback", myname); GEN_CACHE_ID(cache_id, session->session_id, session->session_id_length, TLScontext->serverid); if (TLScontext->log_level >= 2) msg_info("%s: save session %s to %s cache", TLScontext->namaddr, STR(cache_id), TLScontext->cache_type); /* * Passivate and save the session state. */ session_data = tls_session_passivate(session); if (session_data) tls_mgr_update(TLScontext->cache_type, STR(cache_id), STR(session_data), LEN(session_data)); /* * Clean up. */ if (session_data) vstring_free(session_data); vstring_free(cache_id); SSL_SESSION_free(session); /* 200502 */ return (1); }
static int new_client_session_cb(SSL *ssl, SSL_SESSION *session) { const char *myname = "new_client_session_cb"; TLS_SESS_STATE *TLScontext; VSTRING *session_data; /* * The cache name (if caching is enabled in tlsmgr(8)) and the cache ID * string for this session are stored in the TLScontext. It cannot be * null at this point. */ if ((TLScontext = SSL_get_ex_data(ssl, TLScontext_index)) == 0) msg_panic("%s: null TLScontext in new session callback", myname); /* * We only get here if the cache_type is not empty. This callback is not * set unless caching is enabled and the cache_type is stored in the * server SSL context. */ if (TLScontext->cache_type == 0) msg_panic("%s: null session cache type in new session callback", myname); if (TLScontext->log_mask & TLS_LOG_CACHE) /* serverid contains transport:addr:port information */ msg_info("save session %s to %s cache", TLScontext->serverid, TLScontext->cache_type); /* * Passivate and save the session object. Errors are non-fatal, since * caching is only an optimization. */ if ((session_data = tls_session_passivate(session)) != 0) { tls_mgr_update(TLScontext->cache_type, TLScontext->serverid, STR(session_data), LEN(session_data)); vstring_free(session_data); } /* * Clean up. */ SSL_SESSION_free(session); /* 200502 */ return (1); }
int main(int unused_ac, char **av) { VSTRING *inbuf = vstring_alloc(10); int status; ARGV *argv = 0; msg_vstream_init(av[0], VSTREAM_ERR); msg_verbose = 3; mail_conf_read(); msg_info("using config files in %s", var_config_dir); if (chdir(var_queue_dir) < 0) msg_fatal("chdir %s: %m", var_queue_dir); while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) { argv = argv_split(STR(inbuf), " \t\r\n"); if (argv->argc == 0) { argv_free(argv); continue; } #define COMMAND(argv, str, len) \ (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len) if (COMMAND(argv, "policy", 2)) { int cachable; int timeout; status = tls_mgr_policy(argv->argv[1], &cachable, &timeout); vstream_printf("status=%d cachable=%d timeout=%d\n", status, cachable, timeout); } else if (COMMAND(argv, "seed", 2)) { VSTRING *buf = vstring_alloc(10); VSTRING *hex = vstring_alloc(10); int len = atoi(argv->argv[1]); status = tls_mgr_seed(buf, len); hex_encode(hex, STR(buf), LEN(buf)); vstream_printf("status=%d seed=%s\n", status, STR(hex)); vstring_free(hex); vstring_free(buf); } else if (COMMAND(argv, "lookup", 3)) { VSTRING *buf = vstring_alloc(10); status = tls_mgr_lookup(argv->argv[1], argv->argv[2], buf); vstream_printf("status=%d session=%.*s\n", status, LEN(buf), STR(buf)); vstring_free(buf); } else if (COMMAND(argv, "update", 4)) { status = tls_mgr_update(argv->argv[1], argv->argv[2], argv->argv[3], strlen(argv->argv[3])); vstream_printf("status=%d\n", status); } else if (COMMAND(argv, "delete", 3)) { status = tls_mgr_delete(argv->argv[1], argv->argv[2]); vstream_printf("status=%d\n", status); } else { vstream_printf("usage:\n" "seed byte_count\n" "policy smtpd|smtp|lmtp\n" "lookup smtpd|smtp|lmtp cache_id\n" "update smtpd|smtp|lmtp cache_id session\n" "delete smtpd|smtp|lmtp cache_id\n"); } vstream_fflush(VSTREAM_OUT); argv_free(argv); } vstring_free(inbuf); return (0); }
int main(int unused_ac, char **av) { ACL_VSTRING *inbuf = acl_vstring_alloc(10); int status; ARGV *argv = 0; ACL_EVENT *eventp = acl_event_new_select(1, 0); acl_msg_verbose = 3; mail_conf_read(); acl_msg_info("using config files in %s", var_config_dir); if (chdir(var_queue_dir) < 0) acl_msg_fatal("chdir %s: %s", var_queue_dir, acl_last_serror()); tls_mgr_open(eventp); while (acl_vstring_fgets_nonl(inbuf, ACL_VSTREAM_IN)) { argv = argv_split(STR(inbuf), " \t\r\n"); if (argv->argc == 0) { argv_free(argv); continue; } #define COMMAND(argv, str, len) \ (strcasecmp(argv->argv[0], str) == 0 && argv->argc == len) if (COMMAND(argv, "policy", 2)) { int cachable; status = tls_mgr_policy(argv->argv[1], &cachable); acl_vstream_printf("status=%d cachable=%d\n", status, cachable); } else if (COMMAND(argv, "seed", 2)) { ACL_VSTRING *buf = acl_vstring_alloc(10); ACL_VSTRING *hex = acl_vstring_alloc(10); int len = atoi(argv->argv[1]); status = tls_mgr_seed(buf, len); hex_encode(hex, STR(buf), LEN(buf)); acl_vstream_printf("status=%d seed=%s\n", status, STR(hex)); acl_vstring_free(hex); acl_vstring_free(buf); } else if (COMMAND(argv, "lookup", 3)) { ACL_VSTRING *buf = acl_vstring_alloc(10); status = tls_mgr_lookup(argv->argv[1], argv->argv[2], buf); acl_vstream_printf("status=%d session=%.*s\n", status, LEN(buf), STR(buf)); acl_vstring_free(buf); } else if (COMMAND(argv, "update", 4)) { status = tls_mgr_update(argv->argv[1], argv->argv[2], argv->argv[3], strlen(argv->argv[3])); acl_vstream_printf("status=%d\n", status); } else if (COMMAND(argv, "delete", 3)) { status = tls_mgr_delete(argv->argv[1], argv->argv[2]); acl_vstream_printf("status=%d\n", status); } else { acl_vstream_printf("usage:\n" "seed byte_count\n" "policy smtpd|smtp|lmtp\n" "lookup smtpd|smtp|lmtp cache_id\n" "update smtpd|smtp|lmtp cache_id session\n" "delete smtpd|smtp|lmtp cache_id\n"); } acl_vstream_fflush(ACL_VSTREAM_OUT); argv_free(argv); } acl_vstring_free(inbuf); acl_event_free(eventp); return (0); }