1 #ifndef SMTP_CLIENT_PRIVATE_H
2 #define SMTP_CLIENT_PRIVATE_H
3 
4 #include "connection.h"
5 
6 #include "smtp-common.h"
7 #include "smtp-params.h"
8 #include "smtp-client.h"
9 #include "smtp-client-command.h"
10 #include "smtp-client-transaction.h"
11 #include "smtp-client-connection.h"
12 
13 #define SMTP_CLIENT_BASE_LINE_LENGTH_LIMIT 512
14 #define SMTP_CLIENT_DATA_CHUNK_SIZE IO_BLOCK_SIZE
15 
16 struct smtp_client_command {
17 	pool_t pool;
18 	int refcount;
19 	struct event *event;
20 
21 	struct smtp_client_command *prev, *next;
22 
23 	buffer_t *data;
24 	unsigned int send_pos;
25 	const char *name;
26 
27 	enum smtp_client_command_flags flags;
28 
29 	struct smtp_client_connection *conn;
30 	enum smtp_client_command_state state;
31 	unsigned int replies_expected;
32 	unsigned int replies_seen;
33 
34 	struct istream *stream;
35 	uoff_t stream_size;
36 
37 	struct smtp_reply *delayed_failure;
38 
39 	smtp_client_command_callback_t *callback;
40 	void *context;
41 
42 	void (*abort_callback)(void *context);
43 	void *abort_context;
44 
45 	void (*sent_callback)(void *context);
46 	void *sent_context;
47 
48 	bool has_stream:1;
49 	bool stream_dot:1;
50 	bool stream_finished:1;
51 	bool ehlo:1;
52 	bool locked:1;
53 	bool plug:1;
54 	bool failed:1;
55 	bool aborting:1;
56 	bool delay_failure:1;
57 	bool delaying_failure:1;
58 	bool event_finished:1;
59 };
60 
61 struct smtp_client_transaction_mail {
62 	pool_t pool;
63 	struct smtp_client_transaction *trans;
64 
65 	struct smtp_client_transaction_mail *prev, *next;
66 
67 	struct smtp_address *mail_from;
68 	struct smtp_params_mail mail_params;
69 
70 	smtp_client_command_callback_t *mail_callback;
71 	void *context;
72 
73 	struct smtp_client_command *cmd_mail_from;
74 };
75 
76 struct smtp_client_transaction_rcpt {
77 	pool_t pool;
78 	struct smtp_client_transaction *trans;
79 	struct event *event;
80 
81 	struct smtp_client_transaction_rcpt *prev, *next;
82 
83 	struct smtp_address *rcpt_to;
84 	struct smtp_params_rcpt rcpt_params;
85 
86 	smtp_client_command_callback_t *rcpt_callback;
87 	void *context;
88 
89 	smtp_client_command_callback_t *data_callback;
90 	void *data_context;
91 
92 	struct smtp_client_command *cmd_rcpt_to;
93 
94 	bool external_pool:1;
95 	bool queued:1;
96 	bool finished:1;
97 };
98 
99 struct smtp_client_transaction {
100 	pool_t pool;
101 	int refcount;
102 	struct event *event;
103 
104 	struct smtp_client_transaction *prev, *next;
105 
106 	struct smtp_client_connection *conn;
107 	enum smtp_client_transaction_flags flags;
108 
109 	enum smtp_client_transaction_state state;
110 	struct smtp_client_command *cmd_data, *cmd_rset;
111 	struct smtp_client_command *cmd_plug, *cmd_last;
112 	struct smtp_reply *failure, *mail_failure, *data_failure;
113 
114 	struct smtp_client_transaction_mail *mail_head, *mail_tail;
115 	struct smtp_client_transaction_mail *mail_send;
116 
117 	struct smtp_client_transaction_rcpt *rcpts_queue_head, *rcpts_queue_tail;
118 	struct smtp_client_transaction_rcpt *rcpts_send;
119 	struct smtp_client_transaction_rcpt *rcpts_head, *rcpts_tail;
120 	struct smtp_client_transaction_rcpt *rcpts_data;
121 	unsigned int rcpts_queue_count;
122 	unsigned int rcpts_count;
123 
124 	unsigned int rcpts_total;
125 	unsigned int rcpts_aborted;
126 	unsigned int rcpts_denied;
127 	unsigned int rcpts_failed;
128 	unsigned int rcpts_succeeded;
129 
130 	struct istream *data_input;
131 	smtp_client_command_callback_t *data_callback;
132 	void *data_context;
133 
134 	smtp_client_command_callback_t *reset_callback;
135 	void *reset_context;
136 
137 	smtp_client_transaction_callback_t *callback;
138 	void *context;
139 
140 	struct smtp_client_transaction_times times;
141 
142 	unsigned int finish_timeout_msecs;
143 	struct timeout *to_finish, *to_send;
144 
145 	bool immediate:1;
146 	bool sender_accepted:1;
147 	bool data_provided:1;
148 	bool reset:1;
149 	bool finished:1;
150 	bool submitting:1;
151 	bool failing:1;
152 	bool submitted_data:1;
153 };
154 
155 struct smtp_client_login_callback {
156 	smtp_client_command_callback_t *callback;
157 	void *context;
158 };
159 
160 struct smtp_client_connection {
161 	struct connection conn;
162 	pool_t pool;
163 	int refcount;
164 	struct event *event;
165 
166 	struct smtp_client *client;
167 
168 	enum smtp_protocol protocol;
169 	const char *path, *host;
170 	in_port_t port;
171 	enum smtp_client_connection_ssl_mode ssl_mode;
172 
173 	int connect_errno;
174 
175 	struct smtp_client_settings set;
176 	char *password;
177 	ARRAY(struct smtp_client_capability_extra) extra_capabilities;
178 
179 	pool_t cap_pool;
180 	struct {
181 		enum smtp_capability standard;
182 		ARRAY(struct smtp_capability_extra) extra;
183 		const char **auth_mechanisms;
184 		const char **xclient_args;
185 		uoff_t size;
186 
187 		/* Lists of custom MAIL/RCPT parameters supported by peer. These
188 		   arrays always end in NULL pointer once created. */
189 		ARRAY_TYPE(const_string) mail_param_extensions;
190 		ARRAY_TYPE(const_string) rcpt_param_extensions;
191 	} caps;
192 
193 	struct smtp_reply_parser *reply_parser;
194 	struct smtp_reply reply;
195 	unsigned int xclient_replies_expected;
196 
197 	struct dns_lookup *dns_lookup;
198 	struct dsasl_client *sasl_client;
199 	struct timeout *to_connect, *to_trans, *to_commands, *to_cmd_fail;
200 	struct io *io_cmd_payload;
201 
202 	struct istream *raw_input;
203 	struct ostream *raw_output, *dot_output;
204 
205 	struct ssl_iostream_context *ssl_ctx;
206 	struct ssl_iostream *ssl_iostream;
207 
208 	enum smtp_client_connection_state state;
209 	pool_t state_pool;
210 	struct {
211 		struct smtp_reply *login_reply;
212 	} state_data;
213 
214 	ARRAY(struct smtp_client_login_callback) login_callbacks;
215 
216 	/* commands pending in queue to be sent */
217 	struct smtp_client_command *cmd_send_queue_head, *cmd_send_queue_tail;
218 	unsigned int cmd_send_queue_count;
219 	/* commands that have been (mostly) sent, waiting for response */
220 	struct smtp_client_command *cmd_wait_list_head, *cmd_wait_list_tail;
221 	unsigned int cmd_wait_list_count;
222 	/* commands that have failed before submission */
223 	struct smtp_client_command *cmd_fail_list;
224 	/* command sending data stream */
225 	struct smtp_client_command *cmd_streaming;
226 
227 	/* active transactions */
228 	struct smtp_client_transaction *transactions_head, *transactions_tail;
229 
230 	unsigned int ips_count, prev_connect_idx;
231 	struct ip_addr *ips;
232 
233 	bool host_is_ip:1;
234 	bool old_smtp:1;
235 	bool authenticated:1;
236 	bool xclient_sent:1;
237 	bool connect_failed:1;
238 	bool connect_succeeded:1;
239 	bool handshake_failed:1;
240 	bool corked:1;
241 	bool sent_quit:1;
242 	bool sending_command:1;
243 	bool reset_needed:1;
244 	bool failing:1;
245 	bool destroying:1;
246 	bool closed:1;
247 };
248 
249 struct smtp_client {
250 	pool_t pool;
251 
252 	struct smtp_client_settings set;
253 
254 	struct event *event;
255 	struct ioloop *ioloop;
256 	struct ssl_iostream_context *ssl_ctx;
257 
258 	struct connection_list *conn_list;
259 };
260 
261 /*
262  * Command
263  */
264 
265 void smtp_client_command_free(struct smtp_client_command *cmd);
266 int smtp_client_command_send_more(struct smtp_client_connection *conn);
267 int smtp_client_command_input_reply(struct smtp_client_command *cmd,
268 				    const struct smtp_reply *reply);
269 
270 void smtp_client_command_drop_callback(struct smtp_client_command *cmd);
271 
272 void smtp_client_command_fail(struct smtp_client_command **_cmd,
273 			      unsigned int status, const char *error);
274 void smtp_client_command_fail_reply(struct smtp_client_command **_cmd,
275 				    const struct smtp_reply *reply);
276 
277 void smtp_client_commands_list_abort(struct smtp_client_command *cmds_list,
278 				     unsigned int cmds_list_count);
279 void smtp_client_commands_list_fail_reply(
280 	struct smtp_client_command *cmds_list, unsigned int cmds_list_count,
281 	const struct smtp_reply *reply);
282 
283 void smtp_client_commands_abort_delayed(struct smtp_client_connection *conn);
284 void smtp_client_commands_fail_delayed(struct smtp_client_connection *conn);
285 
286 /*
287  * Transaction
288  */
289 
290 void smtp_client_transaction_connection_result(
291 	struct smtp_client_transaction *trans,
292 	const struct smtp_reply *reply);
293 void smtp_client_transaction_connection_destroyed(
294 	struct smtp_client_transaction *trans);
295 
296 void smtp_client_transaction_switch_ioloop(
297 	struct smtp_client_transaction *trans);
298 
299 /*
300  * Connection
301  */
302 
303 struct connection_list *smtp_client_connection_list_init(void);
304 
305 void smtp_client_connection_send_xclient(struct smtp_client_connection *conn);
306 
307 void smtp_client_connection_fail(struct smtp_client_connection *conn,
308 				 unsigned int status, const char *error);
309 
310 void smtp_client_connection_handle_output_error(
311 	struct smtp_client_connection *conn);
312 void smtp_client_connection_trigger_output(
313 	struct smtp_client_connection *conn);
314 
315 void smtp_client_connection_start_cmd_timeout(
316 	struct smtp_client_connection *conn);
317 void smtp_client_connection_update_cmd_timeout(
318 	struct smtp_client_connection *conn);
319 
320 void smtp_client_connection_add_transaction(
321 	struct smtp_client_connection *conn,
322 	struct smtp_client_transaction *trans);
323 void smtp_client_connection_abort_transaction(
324 	struct smtp_client_connection *conn,
325 	struct smtp_client_transaction *trans);
326 void smtp_client_connection_next_transaction(
327 	struct smtp_client_connection *conn,
328 	struct smtp_client_transaction *trans);
329 
330 /*
331  * Client
332  */
333 
334 int smtp_client_init_ssl_ctx(struct smtp_client *client, const char **error_r);
335 
336 #endif
337