return (cmd == NULL || !cmd->input_locked);
}
+static int
+smtp_server_connection_init_ssl_ctx(struct smtp_server_connection *conn,
+ const char **error_r)
+{
+ struct smtp_server *server = conn->server;
+ const char *error;
+
+ if (conn->ssl_ctx != NULL || conn->set.ssl == NULL)
+ return 0;
+ if (conn->set.ssl == server->set.ssl) {
+ if (smtp_server_init_ssl_ctx(server, error_r) < 0)
+ return -1;
+ conn->ssl_ctx = server->ssl_ctx;
+ ssl_iostream_context_ref(conn->ssl_ctx);
+ return 0;
+ }
+
+ if (ssl_iostream_server_context_cache_get(conn->set.ssl,
+ &conn->ssl_ctx, &error) < 0) {
+ *error_r = t_strdup_printf("Couldn't initialize SSL context: %s",
+ error);
+ return -1;
+ }
+ return 0;
+}
+
int smtp_server_connection_ssl_init(struct smtp_server_connection *conn)
{
const char *error;
+ int ret;
+
+ if (smtp_server_connection_init_ssl_ctx(conn, &error) < 0) {
+ smtp_server_connection_error(conn,
+ "Couldn't initialize SSL: %s", error);
+ return -1;
+ }
smtp_server_connection_debug(conn, "Starting SSL handshake");
}
smtp_server_connection_input_halt(conn);
- if (master_service_ssl_init(master_service,
- &conn->conn.input, &conn->conn.output,
- &conn->ssl_iostream, &error) < 0) {
+ if (conn->ssl_ctx == NULL) {
+ ret = master_service_ssl_init(master_service,
+ &conn->conn.input, &conn->conn.output,
+ &conn->ssl_iostream, &error);
+ } else {
+ ret = io_stream_create_ssl_server(conn->ssl_ctx,
+ conn->set.ssl, &conn->conn.input, &conn->conn.output,
+ &conn->ssl_iostream, &error);
+ }
+ if (ret < 0) {
smtp_server_connection_error(conn,
"Couldn't initialize SSL server for %s: %s",
conn->conn.name, error);
conn->set.protocol = server->set.protocol;
if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
conn->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
+
+ if (set->ssl != NULL)
+ conn->set.ssl = ssl_iostream_settings_dup(pool, set->ssl);
+
if (set->hostname != NULL && *set->hostname != '\0')
conn->set.hostname = p_strdup(pool, set->hostname);
if (set->login_greeting != NULL &&
if (conn->smtp_parser != NULL)
smtp_command_parser_deinit(&conn->smtp_parser);
ssl_iostream_destroy(&conn->ssl_iostream);
+ if (conn->ssl_ctx != NULL)
+ ssl_iostream_context_unref(&conn->ssl_ctx);
if (conn->callbacks != NULL &&
conn->callbacks->conn_disconnect != NULL) {
struct timeout *to_idle;
struct istream *raw_input;
struct ostream *raw_output;
+ struct ssl_iostream_context *ssl_ctx;
struct ssl_iostream *ssl_iostream;
struct smtp_command_parser *smtp_parser;
struct smtp_server_settings set;
struct ioloop *ioloop;
+ struct ssl_iostream_context *ssl_ctx;
ARRAY(struct smtp_server_command_reg) commands_reg;
unsigned int
smtp_server_transaction_rcpt_count(struct smtp_server_transaction *trans);
+/*
+ * Server
+ */
+
+int smtp_server_init_ssl_ctx(struct smtp_server *server, const char **error_r);
+
#endif
server->pool = pool;
server->set.protocol = set->protocol;
server->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
+
+ if (set->ssl != NULL) {
+ server->set.ssl =
+ ssl_iostream_settings_dup(server->pool, set->ssl);
+ }
+
if (set->hostname != NULL && *set->hostname != '\0')
server->set.hostname = p_strdup(pool, set->hostname);
else
connection_list_deinit(&server->conn_list);
+ if (server->ssl_ctx != NULL)
+ ssl_iostream_context_unref(&server->ssl_ctx);
pool_unref(&server->pool);
*_server = NULL;
}
smtp_server_connection_switch_ioloop(conn);
}
}
+
+int smtp_server_init_ssl_ctx(struct smtp_server *server, const char **error_r)
+{
+ const char *error;
+
+ if (server->ssl_ctx != NULL || server->set.ssl == NULL)
+ return 0;
+
+ if (ssl_iostream_server_context_cache_get(server->set.ssl,
+ &server->ssl_ctx, &error) < 0) {
+ *error_r = t_strdup_printf("Couldn't initialize SSL context: %s",
+ error);
+ return -1;
+ }
+ return 0;
+}