1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "net.h"
#include "str.h"
#include "hash.h"
#include "hostpid.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "connection.h"
#include "dns-lookup.h"
#include "iostream-rawlog.h"
#include "iostream-ssl.h"
#include "smtp-server-private.h"
static struct event_category event_category_smtp_server = {
.name = "smtp-server"
};
/*
* Server
*/
struct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
{
struct smtp_server *server;
pool_t pool;
pool = pool_alloconly_create("smtp server", 1024);
server = p_new(pool, struct smtp_server, 1);
server->pool = pool;
server->set.protocol = set->protocol;
server->set.reason_code_module =
p_strdup(pool, set->reason_code_module);
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
server->set.hostname = p_strdup(pool, my_hostdomain());
if (set->login_greeting != NULL && *set->login_greeting != '\0')
server->set.login_greeting = p_strdup(pool, set->login_greeting);
else
server->set.login_greeting = DOVECOT_NAME" ready.";
if (set->capabilities == 0) {
server->set.capabilities = SMTP_SERVER_DEFAULT_CAPABILITIES;
} else {
server->set.capabilities = set->capabilities;
}
server->set.workarounds = set->workarounds;
server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs;
server->set.max_pipelined_commands = (set->max_pipelined_commands > 0 ?
set->max_pipelined_commands : 1);
server->set.max_bad_commands = (set->max_bad_commands > 0 ?
set->max_bad_commands : SMTP_SERVER_DEFAULT_MAX_BAD_COMMANDS);
server->set.max_recipients = set->max_recipients;
server->set.command_limits = set->command_limits;
server->set.max_message_size = set->max_message_size;
if (set->mail_param_extensions != NULL) {
server->set.mail_param_extensions =
p_strarray_dup(pool, set->mail_param_extensions);
}
if (set->rcpt_param_extensions != NULL) {
server->set.rcpt_param_extensions =
p_strarray_dup(pool, set->rcpt_param_extensions);
}
if (set->xclient_extensions != NULL) {
server->set.xclient_extensions =
p_strarray_dup(pool, set->xclient_extensions);
}
server->set.socket_send_buffer_size = set->socket_send_buffer_size;
server->set.socket_recv_buffer_size = set->socket_recv_buffer_size;
server->set.tls_required = set->tls_required;
server->set.auth_optional = set->auth_optional;
server->set.rcpt_domain_optional = set->rcpt_domain_optional;
server->set.mail_path_allow_broken = set->mail_path_allow_broken;
server->set.no_greeting = set->no_greeting;
server->set.debug = set->debug;
server->set.no_state_in_reason = set->no_state_in_reason;
/* There is no event log prefix added here, since the server itself does
not log anything. */
server->event = event_create(set->event_parent);
smtp_server_event_init(server, server->event);
event_set_forced_debug(server->event, set->debug);
server->conn_list = smtp_server_connection_list_init();
smtp_server_commands_init(server);
return server;
}
void smtp_server_event_init(struct smtp_server *server, struct event *event)
{
event_add_category(event, &event_category_smtp_server);
event_add_str(event, "protocol",
smtp_protocol_name(server->set.protocol));
}
void smtp_server_deinit(struct smtp_server **_server)
{
struct smtp_server *server = *_server;
connection_list_deinit(&server->conn_list);
if (server->ssl_ctx != NULL)
ssl_iostream_context_unref(&server->ssl_ctx);
event_unref(&server->event);
pool_unref(&server->pool);
*_server = NULL;
}
void smtp_server_switch_ioloop(struct smtp_server *server)
{
struct connection *_conn = server->conn_list->connections;
/* move connections */
/* FIXME: we wouldn't necessarily need to switch all of them
immediately, only those that have commands now. but also connections
that get new commands before ioloop is switched again.. */
for (; _conn != NULL; _conn = _conn->next) {
struct smtp_server_connection *conn =
(struct smtp_server_connection *)_conn;
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;
}
|