bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "lib.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "net.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "str.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "hash.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "hostpid.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "array.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "ioloop.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "istream.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "ostream.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "connection.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "dns-lookup.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "iostream-rawlog.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "iostream-ssl.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch#include "smtp-server-private.h"
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch/*
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch * Server
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschstruct smtp_server *smtp_server_init(const struct smtp_server_settings *set)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server *server;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pool_t pool;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pool = pool_alloconly_create("smtp server", 1024);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server = p_new(pool, struct smtp_server, 1);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->pool = pool;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.protocol = set->protocol;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.rawlog_dir = p_strdup_empty(pool, set->rawlog_dir);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (set->hostname != NULL && *set->hostname != '\0')
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.hostname = p_strdup(pool, set->hostname);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch else
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.hostname = p_strdup(pool, my_hostdomain());
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (set->login_greeting != NULL && *set->login_greeting != '\0')
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.login_greeting = p_strdup(pool, set->login_greeting);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch else
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.login_greeting = PACKAGE_NAME" ready.";
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (set->capabilities == 0) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.capabilities = SMTP_SERVER_DEFAULT_CAPABILITIES;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch } else {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.capabilities = set->capabilities;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch }
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.max_pipelined_commands = (set->max_pipelined_commands > 0 ?
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch set->max_pipelined_commands : 1);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.max_bad_commands = (set->max_bad_commands > 0 ?
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch set->max_bad_commands : SMTP_SERVER_DEFAULT_MAX_BAD_COMMANDS);
4dd460cf19f1df3b51090427fea87e9c4b73c6d4Stephan Bosch server->set.max_recipients = set->max_recipients;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.command_limits = set->command_limits;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch if (set->xclient_extensions != NULL) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.xclient_extensions =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch p_strarray_dup(pool, set->xclient_extensions);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch }
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.socket_send_buffer_size = set->socket_send_buffer_size;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.socket_recv_buffer_size = set->socket_recv_buffer_size;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.tls_required = set->tls_required;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.auth_optional = set->auth_optional;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.rcpt_domain_optional = set->rcpt_domain_optional;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.param_extensions = set->param_extensions;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->set.debug = set->debug;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch server->conn_list = smtp_server_connection_list_init();
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_commands_init(server);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch return server;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_deinit(struct smtp_server **_server)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server *server = *_server;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch connection_list_deinit(&server->conn_list);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch pool_unref(&server->pool);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch *_server = NULL;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Boschvoid smtp_server_switch_ioloop(struct smtp_server *server)
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch{
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct connection *_conn = server->conn_list->connections;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* move connections */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch /* FIXME: we wouldn't necessarily need to switch all of them
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch immediately, only those that have commands now. but also connections
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch that get new commands before ioloop is switched again.. */
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch for (; _conn != NULL; _conn = _conn->next) {
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch struct smtp_server_connection *conn =
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch (struct smtp_server_connection *)_conn;
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch smtp_server_connection_switch_ioloop(conn);
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch }
56dd928c164ec5c0d1158a1760154b58c5f1f6e7Stephan Bosch}