1 #ifndef SMTP_SERVER_PRIVATE_H
2 #define SMTP_SERVER_PRIVATE_H
3 
4 #include "connection.h"
5 
6 #include "smtp-server.h"
7 
8 #define SMTP_SERVER_COMMAND_POOL_MAX              (8 * 1024)
9 
10 #define SMTP_SERVER_DEFAULT_MAX_COMMAND_LINE      (4 * 1024)
11 #define SMTP_SERVER_DEFAULT_MAX_BAD_COMMANDS      10
12 #define SMTP_SERVER_DEFAULT_MAX_SIZE_EXCESS_LIMIT (1024*1024)
13 
14 #define SMTP_SERVER_DEFAULT_CAPABILITIES \
15 	(SMTP_CAPABILITY_SIZE | SMTP_CAPABILITY_ENHANCEDSTATUSCODES | \
16 	 SMTP_CAPABILITY_8BITMIME | SMTP_CAPABILITY_CHUNKING)
17 
18 struct smtp_server_cmd_hook;
19 struct smtp_server_reply;
20 struct smtp_server_command;
21 struct smtp_server_connection;
22 
23 ARRAY_DEFINE_TYPE(smtp_server_reply, struct smtp_server_reply);
24 ARRAY_DEFINE_TYPE(smtp_server_cmd_hook, struct smtp_server_cmd_hook);
25 
26 enum smtp_server_command_state {
27 	/* New command; callback to command start handler executing. */
28 	SMTP_SERVER_COMMAND_STATE_NEW = 0,
29 	/* This command is being processed; command data is fully read, but no
30 	   reply is yet submitted */
31 	SMTP_SERVER_COMMAND_STATE_PROCESSING,
32 	/* A reply is submitted for this command. If not all command data was
33 	   read by the handler, it is first skipped on the input. If this is a
34 	   multi-reply command (LMTP->DATA), not all replies may be submitted
35 	   yet. */
36 	SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY,
37 	/* Request is ready for sending reply; a reply is submitted and the
38 	   command payload is fully read. If this is a multi-reply command
39 	   (LMTP->DATA), not all replies may be submitted yet. In that case the
40 	   command state goes back to PROCESSING once the all submitted replies
41 	   are sent. */
42 	SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY,
43 	/* The reply for the command is sent */
44 	SMTP_SERVER_COMMAND_STATE_FINISHED,
45 	/* Request is aborted; still lingering due to references */
46 	SMTP_SERVER_COMMAND_STATE_ABORTED
47 };
48 
49 struct smtp_server_command_hook {
50 	enum smtp_server_command_hook_type type;
51 	struct smtp_server_command_hook *prev, *next;
52 
53 	smtp_server_cmd_func_t *func;
54 	void *context;
55 };
56 
57 struct smtp_server_recipient_hook {
58 	enum smtp_server_recipient_hook_type type;
59 	struct smtp_server_recipient_hook *prev, *next;
60 
61 	smtp_server_rcpt_func_t *func;
62 	void *context;
63 };
64 
65 struct smtp_server_reply_content {
66 	unsigned int status;
67 	const char *enhanced_code;
68 	const char *status_prefix;
69 
70 	string_t *text;
71 	size_t last_line;
72 };
73 
74 struct smtp_server_reply {
75 	struct smtp_server_command *command;
76 	unsigned int index;
77 	struct event *event;
78 
79 	/* Replies may share content */
80 	struct smtp_server_reply_content *content;
81 
82 	bool submitted:1;
83 	bool sent:1;
84 	bool forwarded:1;
85 };
86 
87 struct smtp_server_command_reg {
88 	const char *name;
89 	enum smtp_server_command_flags flags;
90 	smtp_server_cmd_start_func_t *func;
91 };
92 
93 struct smtp_server_command {
94 	struct smtp_server_cmd_ctx context;
95 	const struct smtp_server_command_reg *reg;
96 	int refcount;
97 
98 	enum smtp_server_command_state state;
99 
100 	struct smtp_server_command *prev, *next;
101 
102 	struct smtp_server_command_hook *hooks_head, *hooks_tail;
103 	void *data;
104 
105 	ARRAY_TYPE(smtp_server_reply) replies;
106 	unsigned int replies_expected;
107 	unsigned int replies_submitted;
108 
109 	bool input_locked:1;
110 	bool input_captured:1;
111 	bool reply_early:1;
112 	bool destroying:1;
113 };
114 
115 struct smtp_server_recipient_private {
116 	struct smtp_server_recipient rcpt;
117 	int refcount;
118 
119 	struct smtp_server_recipient_hook *hooks_head, *hooks_tail;
120 
121 	bool destroying:1;
122 };
123 
124 struct smtp_server_state_data {
125 	enum smtp_server_state state;
126 	char *args;
127 	time_t timestamp;
128 
129 	unsigned int pending_mail_cmds;
130 	unsigned int pending_rcpt_cmds, denied_rcpt_cmds;
131 	unsigned int pending_data_cmds;
132 
133 	struct smtp_server_transaction *trans;
134 	struct istream *data_input, *data_chain_input;
135 	struct istream_chain *data_chain;
136 	unsigned int data_chunks;
137 	uoff_t data_size;
138 
139 	bool data_failed:1;
140 };
141 
142 struct smtp_server_connection {
143 	struct connection conn;
144 	struct smtp_server *server;
145 	pool_t pool;
146 	int refcount;
147 	struct event *event, *next_trans_event;
148 
149 	struct smtp_server_settings set;
150 
151 	ARRAY(struct smtp_capability_extra) extra_capabilities;
152 	ARRAY_TYPE(const_string) mail_param_extensions; /* NULL-terminated */
153 	ARRAY_TYPE(const_string) rcpt_param_extensions; /* NULL-terminated */
154 
155 	const struct smtp_server_callbacks *callbacks;
156 	void *context;
157 
158 	enum smtp_proxy_protocol proxy_proto;
159 	unsigned int proxy_ttl_plus_1;
160 	unsigned int proxy_timeout_secs;
161 	char *proxy_helo;
162 
163 	struct smtp_server_helo_data helo, *pending_helo;
164 	char *helo_domain, *username;
165 
166 	struct timeout *to_idle;
167 	struct istream *raw_input;
168 	struct ostream *raw_output;
169 	struct ssl_iostream_context *ssl_ctx;
170 	struct ssl_iostream *ssl_iostream;
171 	struct smtp_command_parser *smtp_parser;
172 
173 	struct smtp_server_command *command_queue_head, *command_queue_tail;
174 	unsigned int command_queue_count;
175 	unsigned int bad_counter;
176 
177 	struct smtp_server_state_data state;
178 
179 	struct smtp_server_stats stats;
180 
181 	bool started:1;
182 	bool halted:1;
183 	bool ssl_start:1;
184 	bool ssl_secured:1;
185 	bool authenticated:1;
186 	bool created_from_streams:1;
187 	bool corked:1;
188 	bool disconnected:1;
189 	bool closing:1;
190 	bool closed:1;
191 	bool input_broken:1;
192 	bool input_locked:1;
193 	bool handling_input:1;
194 	bool rawlog_checked:1;
195 	bool rawlog_enabled:1;
196 };
197 
198 struct smtp_server {
199 	pool_t pool;
200 
201 	struct smtp_server_settings set;
202 
203 	struct event *event;
204 	struct ssl_iostream_context *ssl_ctx;
205 
206 	ARRAY(struct smtp_server_command_reg) commands_reg;
207 
208 	struct connection_list *conn_list;
209 
210 	bool commands_unsorted:1;
211 };
212 
213 bool smtp_server_connection_pending_command_data(
214 	struct smtp_server_connection *conn);
215 
216 /*
217  * Reply
218  */
219 
220 void smtp_server_reply_free(struct smtp_server_command *cmd);
221 
222 int smtp_server_reply_send(struct smtp_server_reply *resp);
223 
224 const char *
225 smtp_server_reply_get_one_line(const struct smtp_server_reply *reply);
226 const char *
227 smtp_server_reply_get_message(const struct smtp_server_reply *reply);
228 
229 void smtp_server_reply_add_to_event(const struct smtp_server_reply *reply,
230 				    struct event_passthrough *e);
231 
232 /*
233  * Command
234  */
235 
236 void smtp_server_commands_init(struct smtp_server *server);
237 
238 void smtp_server_command_debug(struct smtp_server_cmd_ctx *cmd,
239 	const char *format, ...) ATTR_FORMAT(2, 3);
240 
241 struct smtp_server_command *
242 smtp_server_command_new_invalid(struct smtp_server_connection *conn);
243 struct smtp_server_command *
244 smtp_server_command_new(struct smtp_server_connection *conn, const char *name);
245 
246 void smtp_server_command_execute(struct smtp_server_command *cmd,
247 				 const char *params);
248 
249 void smtp_server_command_ref(struct smtp_server_command *cmd);
250 bool smtp_server_command_unref(struct smtp_server_command **_cmd);
251 void smtp_server_command_abort(struct smtp_server_command **_cmd);
252 
253 bool smtp_server_command_call_hooks(struct smtp_server_command **_cmd,
254 				    enum smtp_server_command_hook_type type,
255 				    bool remove);
256 void smtp_server_command_remove_hooks(struct smtp_server_command *cmd,
257 				      enum smtp_server_command_hook_type type);
258 
259 void smtp_server_command_submit_reply(struct smtp_server_command *cmd);
260 
261 int smtp_server_connection_flush(struct smtp_server_connection *conn);
262 
263 void smtp_server_command_ready_to_reply(struct smtp_server_command *cmd);
264 void smtp_server_command_finished(struct smtp_server_command *cmd);
265 
266 bool smtp_server_command_next_to_reply(struct smtp_server_command **_cmd);
267 bool smtp_server_command_completed(struct smtp_server_command **_cmd);
268 
269 static inline bool
smtp_server_command_is_complete(struct smtp_server_command * cmd)270 smtp_server_command_is_complete(struct smtp_server_command *cmd)
271 {
272 	struct smtp_server_connection *conn = cmd->context.conn;
273 
274 	return (conn->input_broken || (cmd->next != NULL) || cmd->reply_early ||
275 		!smtp_server_connection_pending_command_data(conn));
276 }
277 
278 void smtp_server_cmd_ehlo(struct smtp_server_cmd_ctx *cmd, const char *params);
279 void smtp_server_cmd_helo(struct smtp_server_cmd_ctx *cmd, const char *params);
280 void smtp_server_cmd_xclient(struct smtp_server_cmd_ctx *cmd,
281 			     const char *params);
282 
283 void smtp_server_cmd_starttls(struct smtp_server_cmd_ctx *cmd,
284 			      const char *params);
285 void smtp_server_cmd_auth(struct smtp_server_cmd_ctx *cmd, const char *params);
286 
287 void smtp_server_cmd_mail(struct smtp_server_cmd_ctx *cmd, const char *params);
288 void smtp_server_cmd_rcpt(struct smtp_server_cmd_ctx *cmd, const char *params);
289 void smtp_server_cmd_data(struct smtp_server_cmd_ctx *cmd, const char *params);
290 void smtp_server_cmd_bdat(struct smtp_server_cmd_ctx *cmd, const char *params);
291 void smtp_server_cmd_rset(struct smtp_server_cmd_ctx *cmd, const char *params);
292 
293 void smtp_server_cmd_noop(struct smtp_server_cmd_ctx *cmd, const char *params);
294 void smtp_server_cmd_vrfy(struct smtp_server_cmd_ctx *cmd, const char *params);
295 
296 void smtp_server_cmd_quit(struct smtp_server_cmd_ctx *cmd, const char *params);
297 
298 /*
299  * Connection
300  */
301 
302 typedef void smtp_server_input_callback_t(void *context);
303 
304 void smtp_server_connection_debug(struct smtp_server_connection *conn,
305 				  const char *format, ...) ATTR_FORMAT(2, 3);
306 
307 struct connection_list *smtp_server_connection_list_init(void);
308 
309 void smtp_server_connection_switch_ioloop(struct smtp_server_connection *conn);
310 
311 void smtp_server_connection_handle_output_error(
312 	struct smtp_server_connection *conn);
313 void smtp_server_connection_trigger_output(struct smtp_server_connection *conn);
314 bool smtp_server_connection_pending_payload(struct smtp_server_connection *conn);
315 
316 void smtp_server_connection_cork(struct smtp_server_connection *conn);
317 void smtp_server_connection_uncork(struct smtp_server_connection *conn);
318 
319 void smtp_server_connection_input_halt(struct smtp_server_connection *conn);
320 void smtp_server_connection_input_resume(struct smtp_server_connection *conn);
321 void smtp_server_connection_input_capture(
322 	struct smtp_server_connection *conn,
323 	smtp_server_input_callback_t *callback, void *context);
324 #define smtp_server_connection_input_capture(conn, callback, context) \
325 	smtp_server_connection_input_capture(conn - \
326 		CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
327 		(smtp_server_input_callback_t *)callback, context)
328 
329 void smtp_server_connection_timeout_stop(struct smtp_server_connection *conn);
330 void smtp_server_connection_timeout_start(struct smtp_server_connection *conn);
331 void smtp_server_connection_timeout_reset(struct smtp_server_connection *conn);
332 
333 void smtp_server_connection_send_line(struct smtp_server_connection *conn,
334 				      const char *fmt, ...) ATTR_FORMAT(2, 3);
335 void smtp_server_connection_reply_lines(struct smtp_server_connection *conn,
336 				        unsigned int status,
337 					const char *enh_code,
338 					const char *const *text_lines);
339 void smtp_server_connection_reply_immediate(
340 	struct smtp_server_connection *conn, unsigned int status,
341 	const char *fmt, ...) ATTR_FORMAT(3, 4);
342 
343 void smtp_server_connection_reset_state(struct smtp_server_connection *conn);
344 void smtp_server_connection_set_state(struct smtp_server_connection *conn,
345 				      enum smtp_server_state state,
346 				      const char *args) ATTR_NULL(3);
347 
348 int smtp_server_connection_ssl_init(struct smtp_server_connection *conn);
349 
350 void smtp_server_connection_clear(struct smtp_server_connection *conn);
351 
352 struct smtp_server_transaction *
353 smtp_server_connection_get_transaction(struct smtp_server_connection *conn);
354 
355 /*
356  * Recipient
357  */
358 
359 struct smtp_server_recipient *
360 smtp_server_recipient_create(struct smtp_server_cmd_ctx *cmd,
361 			     const struct smtp_address *rcpt_to,
362 			     const struct smtp_params_rcpt *params);
363 void smtp_server_recipient_ref(struct smtp_server_recipient *rcpt);
364 bool smtp_server_recipient_unref(struct smtp_server_recipient **_rcpt);
365 void smtp_server_recipient_destroy(struct smtp_server_recipient **_rcpt);
366 
367 bool smtp_server_recipient_approved(struct smtp_server_recipient **_rcpt);
368 void smtp_server_recipient_denied(struct smtp_server_recipient *rcpt,
369 				  const struct smtp_server_reply *reply);
370 
371 void smtp_server_recipient_data_command(struct smtp_server_recipient *rcpt,
372 					struct smtp_server_cmd_ctx *cmd);
373 void smtp_server_recipient_data_replied(struct smtp_server_recipient *rcpt);
374 
375 void smtp_server_recipient_reset(struct smtp_server_recipient *rcpt);
376 void smtp_server_recipient_finished(struct smtp_server_recipient *rcpt,
377 				    const struct smtp_server_reply *reply);
378 
379 bool smtp_server_recipient_call_hooks(
380 	struct smtp_server_recipient **_rcpt,
381 	enum smtp_server_recipient_hook_type type);
382 
383 /*
384  * Transaction
385  */
386 
387 struct smtp_server_transaction *
388 smtp_server_transaction_create(struct smtp_server_connection *conn,
389 			       const struct smtp_server_cmd_mail *mail_data);
390 void smtp_server_transaction_free(struct smtp_server_transaction **_trans);
391 
392 void smtp_server_transaction_add_rcpt(struct smtp_server_transaction *trans,
393 				      struct smtp_server_recipient *rcpt);
394 bool smtp_server_transaction_has_rcpt(struct smtp_server_transaction *trans);
395 unsigned int
396 smtp_server_transaction_rcpt_count(struct smtp_server_transaction *trans);
397 
398 void smtp_server_transaction_data_command(struct smtp_server_transaction *trans,
399 					  struct smtp_server_cmd_ctx *cmd);
400 
401 void smtp_server_transaction_received(struct smtp_server_transaction *trans,
402 				      uoff_t data_size);
403 
404 void smtp_server_transaction_reset(struct smtp_server_transaction *trans);
405 void smtp_server_transaction_finished(struct smtp_server_transaction *trans,
406 				      struct smtp_server_cmd_ctx *cmd);
407 
408 /*
409  * Server
410  */
411 
412 void smtp_server_event_init(struct smtp_server *server, struct event *event);
413 int smtp_server_init_ssl_ctx(struct smtp_server *server, const char **error_r);
414 
415 #endif
416