1 /*	$OpenBSD: report_smtp.c,v 1.11 2020/01/07 23:03:37 gilles Exp $	*/
2 
3 /*
4  * Copyright (c) 2018 Gilles Chehade <gilles@poolp.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "includes.h"
20 
21 #include <sys/types.h>
22 #include <sys/queue.h>
23 #include <sys/tree.h>
24 #include <sys/socket.h>
25 #include <sys/uio.h>
26 
27 #include <netinet/in.h>
28 
29 #include <ctype.h>
30 #include <errno.h>
31 #include <event.h>
32 #include <imsg.h>
33 #include <limits.h>
34 #include <inttypes.h>
35 #include <openssl/ssl.h>
36 #include <resolv.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #if defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS)
42 #include <vis.h>
43 #else
44 #include "bsd-vis.h"
45 #endif
46 
47 #include "smtpd.h"
48 #include "log.h"
49 #include "ssl.h"
50 #include "rfc5322.h"
51 
52 void
report_smtp_link_connect(const char * direction,uint64_t qid,const char * rdns,int fcrdns,const struct sockaddr_storage * ss_src,const struct sockaddr_storage * ss_dest)53 report_smtp_link_connect(const char *direction, uint64_t qid, const char *rdns, int fcrdns,
54     const struct sockaddr_storage *ss_src,
55     const struct sockaddr_storage *ss_dest)
56 {
57 	struct timeval	tv;
58 
59 	gettimeofday(&tv, NULL);
60 
61 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_CONNECT, 0, 0, -1);
62 	m_add_string(p_lka, direction);
63 	m_add_timeval(p_lka, &tv);
64 	m_add_id(p_lka, qid);
65 	m_add_string(p_lka, rdns);
66 	m_add_int(p_lka, fcrdns);
67 	m_add_sockaddr(p_lka, (const struct sockaddr *)ss_src);
68 	m_add_sockaddr(p_lka, (const struct sockaddr *)ss_dest);
69 	m_close(p_lka);
70 }
71 
72 void
report_smtp_link_greeting(const char * direction,uint64_t qid,const char * domain)73 report_smtp_link_greeting(const char *direction, uint64_t qid,
74     const char *domain)
75 {
76 	struct timeval	tv;
77 
78 	gettimeofday(&tv, NULL);
79 
80 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_GREETING, 0, 0, -1);
81 	m_add_string(p_lka, direction);
82 	m_add_timeval(p_lka, &tv);
83 	m_add_id(p_lka, qid);
84 	m_add_string(p_lka, domain);
85 	m_close(p_lka);
86 }
87 
88 void
report_smtp_link_identify(const char * direction,uint64_t qid,const char * method,const char * identity)89 report_smtp_link_identify(const char *direction, uint64_t qid, const char *method, const char *identity)
90 {
91 	struct timeval	tv;
92 
93 	gettimeofday(&tv, NULL);
94 
95 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_IDENTIFY, 0, 0, -1);
96 	m_add_string(p_lka, direction);
97 	m_add_timeval(p_lka, &tv);
98 	m_add_id(p_lka, qid);
99 	m_add_string(p_lka, method);
100 	m_add_string(p_lka, identity);
101 	m_close(p_lka);
102 }
103 
104 void
report_smtp_link_tls(const char * direction,uint64_t qid,const char * ssl)105 report_smtp_link_tls(const char *direction, uint64_t qid, const char *ssl)
106 {
107 	struct timeval	tv;
108 
109 	gettimeofday(&tv, NULL);
110 
111 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_TLS, 0, 0, -1);
112 	m_add_string(p_lka, direction);
113 	m_add_timeval(p_lka, &tv);
114 	m_add_id(p_lka, qid);
115 	m_add_string(p_lka, ssl);
116 	m_close(p_lka);
117 }
118 
119 void
report_smtp_link_disconnect(const char * direction,uint64_t qid)120 report_smtp_link_disconnect(const char *direction, uint64_t qid)
121 {
122 	struct timeval	tv;
123 
124 	gettimeofday(&tv, NULL);
125 
126 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_DISCONNECT, 0, 0, -1);
127 	m_add_string(p_lka, direction);
128 	m_add_timeval(p_lka, &tv);
129 	m_add_id(p_lka, qid);
130 	m_close(p_lka);
131 }
132 
133 void
report_smtp_link_auth(const char * direction,uint64_t qid,const char * user,const char * result)134 report_smtp_link_auth(const char *direction, uint64_t qid, const char *user, const char *result)
135 {
136 	struct timeval	tv;
137 
138 	gettimeofday(&tv, NULL);
139 
140 	m_create(p_lka, IMSG_REPORT_SMTP_LINK_AUTH, 0, 0, -1);
141 	m_add_string(p_lka, direction);
142 	m_add_timeval(p_lka, &tv);
143 	m_add_id(p_lka, qid);
144 	m_add_string(p_lka, user);
145 	m_add_string(p_lka, result);
146 	m_close(p_lka);
147 }
148 
149 void
report_smtp_tx_reset(const char * direction,uint64_t qid,uint32_t msgid)150 report_smtp_tx_reset(const char *direction, uint64_t qid, uint32_t msgid)
151 {
152 	struct timeval	tv;
153 
154 	gettimeofday(&tv, NULL);
155 
156 	m_create(p_lka, IMSG_REPORT_SMTP_TX_RESET, 0, 0, -1);
157 	m_add_string(p_lka, direction);
158 	m_add_timeval(p_lka, &tv);
159 	m_add_id(p_lka, qid);
160 	m_add_u32(p_lka, msgid);
161 	m_close(p_lka);
162 }
163 
164 void
report_smtp_tx_begin(const char * direction,uint64_t qid,uint32_t msgid)165 report_smtp_tx_begin(const char *direction, uint64_t qid, uint32_t msgid)
166 {
167 	struct timeval	tv;
168 
169 	gettimeofday(&tv, NULL);
170 
171 	m_create(p_lka, IMSG_REPORT_SMTP_TX_BEGIN, 0, 0, -1);
172 	m_add_string(p_lka, direction);
173 	m_add_timeval(p_lka, &tv);
174 	m_add_id(p_lka, qid);
175 	m_add_u32(p_lka, msgid);
176 	m_close(p_lka);
177 }
178 
179 void
report_smtp_tx_mail(const char * direction,uint64_t qid,uint32_t msgid,const char * address,int ok)180 report_smtp_tx_mail(const char *direction, uint64_t qid, uint32_t msgid, const char *address, int ok)
181 {
182 	struct timeval	tv;
183 
184 	gettimeofday(&tv, NULL);
185 
186 	m_create(p_lka, IMSG_REPORT_SMTP_TX_MAIL, 0, 0, -1);
187 	m_add_string(p_lka, direction);
188 	m_add_timeval(p_lka, &tv);
189 	m_add_id(p_lka, qid);
190 	m_add_u32(p_lka, msgid);
191 	m_add_string(p_lka, address);
192 	m_add_int(p_lka, ok);
193 	m_close(p_lka);
194 }
195 
196 void
report_smtp_tx_rcpt(const char * direction,uint64_t qid,uint32_t msgid,const char * address,int ok)197 report_smtp_tx_rcpt(const char *direction, uint64_t qid, uint32_t msgid, const char *address, int ok)
198 {
199 	struct timeval	tv;
200 
201 	gettimeofday(&tv, NULL);
202 
203 	m_create(p_lka, IMSG_REPORT_SMTP_TX_RCPT, 0, 0, -1);
204 	m_add_string(p_lka, direction);
205 	m_add_timeval(p_lka, &tv);
206 	m_add_id(p_lka, qid);
207 	m_add_u32(p_lka, msgid);
208 	m_add_string(p_lka, address);
209 	m_add_int(p_lka, ok);
210 	m_close(p_lka);
211 }
212 
213 void
report_smtp_tx_envelope(const char * direction,uint64_t qid,uint32_t msgid,uint64_t evpid)214 report_smtp_tx_envelope(const char *direction, uint64_t qid, uint32_t msgid, uint64_t evpid)
215 {
216 	struct timeval	tv;
217 
218 	gettimeofday(&tv, NULL);
219 
220 	m_create(p_lka, IMSG_REPORT_SMTP_TX_ENVELOPE, 0, 0, -1);
221 	m_add_string(p_lka, direction);
222 	m_add_timeval(p_lka, &tv);
223 	m_add_id(p_lka, qid);
224 	m_add_u32(p_lka, msgid);
225 	m_add_id(p_lka, evpid);
226 	m_close(p_lka);
227 }
228 
229 void
report_smtp_tx_data(const char * direction,uint64_t qid,uint32_t msgid,int ok)230 report_smtp_tx_data(const char *direction, uint64_t qid, uint32_t msgid, int ok)
231 {
232 	struct timeval	tv;
233 
234 	gettimeofday(&tv, NULL);
235 
236 	m_create(p_lka, IMSG_REPORT_SMTP_TX_DATA, 0, 0, -1);
237 	m_add_string(p_lka, direction);
238 	m_add_timeval(p_lka, &tv);
239 	m_add_id(p_lka, qid);
240 	m_add_u32(p_lka, msgid);
241 	m_add_int(p_lka, ok);
242 	m_close(p_lka);
243 }
244 
245 void
report_smtp_tx_commit(const char * direction,uint64_t qid,uint32_t msgid,size_t msgsz)246 report_smtp_tx_commit(const char *direction, uint64_t qid, uint32_t msgid, size_t msgsz)
247 {
248 	struct timeval	tv;
249 
250 	gettimeofday(&tv, NULL);
251 
252 	m_create(p_lka, IMSG_REPORT_SMTP_TX_COMMIT, 0, 0, -1);
253 	m_add_string(p_lka, direction);
254 	m_add_timeval(p_lka, &tv);
255 	m_add_id(p_lka, qid);
256 	m_add_u32(p_lka, msgid);
257 	m_add_size(p_lka, msgsz);
258 	m_close(p_lka);
259 }
260 
261 void
report_smtp_tx_rollback(const char * direction,uint64_t qid,uint32_t msgid)262 report_smtp_tx_rollback(const char *direction, uint64_t qid, uint32_t msgid)
263 {
264 	struct timeval	tv;
265 
266 	gettimeofday(&tv, NULL);
267 
268 	m_create(p_lka, IMSG_REPORT_SMTP_TX_ROLLBACK, 0, 0, -1);
269 	m_add_string(p_lka, direction);
270 	m_add_timeval(p_lka, &tv);
271 	m_add_id(p_lka, qid);
272 	m_add_u32(p_lka, msgid);
273 	m_close(p_lka);
274 }
275 
276 void
report_smtp_protocol_client(const char * direction,uint64_t qid,const char * command)277 report_smtp_protocol_client(const char *direction, uint64_t qid, const char *command)
278 {
279 	struct timeval	tv;
280 
281 	gettimeofday(&tv, NULL);
282 
283 	m_create(p_lka, IMSG_REPORT_SMTP_PROTOCOL_CLIENT, 0, 0, -1);
284 	m_add_string(p_lka, direction);
285 	m_add_timeval(p_lka, &tv);
286 	m_add_id(p_lka, qid);
287 	m_add_string(p_lka, command);
288 	m_close(p_lka);
289 }
290 
291 void
report_smtp_protocol_server(const char * direction,uint64_t qid,const char * response)292 report_smtp_protocol_server(const char *direction, uint64_t qid, const char *response)
293 {
294 	struct timeval	tv;
295 
296 	gettimeofday(&tv, NULL);
297 
298 	m_create(p_lka, IMSG_REPORT_SMTP_PROTOCOL_SERVER, 0, 0, -1);
299 	m_add_string(p_lka, direction);
300 	m_add_timeval(p_lka, &tv);
301 	m_add_id(p_lka, qid);
302 	m_add_string(p_lka, response);
303 	m_close(p_lka);
304 }
305 
306 void
report_smtp_filter_response(const char * direction,uint64_t qid,int phase,int response,const char * param)307 report_smtp_filter_response(const char *direction, uint64_t qid, int phase, int response, const char *param)
308 {
309 	struct timeval	tv;
310 
311 	gettimeofday(&tv, NULL);
312 
313 	m_create(p_lka, IMSG_REPORT_SMTP_FILTER_RESPONSE, 0, 0, -1);
314 	m_add_string(p_lka, direction);
315 	m_add_timeval(p_lka, &tv);
316 	m_add_id(p_lka, qid);
317 	m_add_int(p_lka, phase);
318 	m_add_int(p_lka, response);
319 	m_add_string(p_lka, param);
320 	m_close(p_lka);
321 }
322 
323 void
report_smtp_timeout(const char * direction,uint64_t qid)324 report_smtp_timeout(const char *direction, uint64_t qid)
325 {
326 	struct timeval	tv;
327 
328 	gettimeofday(&tv, NULL);
329 
330 	m_create(p_lka, IMSG_REPORT_SMTP_TIMEOUT, 0, 0, -1);
331 	m_add_string(p_lka, direction);
332 	m_add_timeval(p_lka, &tv);
333 	m_add_id(p_lka, qid);
334 	m_close(p_lka);
335 }
336