Coverage Report

Created: 2026-10-28 07:11

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