2 #include <sys/socket.h>
12 #include "smtp_proc.h"
14 #define NITEMS(x) (sizeof(x) / sizeof(*x))
16 typedef int (*smtp_cb)(char *, int, time_t, char *, char *, uint64_t, uint64_t,
21 static int smtp_register(char *, char *, char *, smtp_cb);
22 static void smtp_connect(struct smtp_callback *, int, time_t, uint64_t,
24 static void smtp_data(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
26 static void smtp_data_line(struct smtp_callback *, int, time_t, uint64_t,
28 static void smtp_rset(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
30 static void smtp_quit(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
32 static void smtp_noop(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
34 static void smtp_help(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
36 static void smtp_wiz(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
38 static void smtp_commit(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
40 static void smtp_handle(struct smtp_callback *, int, time_t, uint64_t, uint64_t,
43 struct smtp_callback {
47 void (*smtp_parse)(struct smtp_callback *, int, time_t, uint64_t,
50 } smtp_callbacks[] = {
51 {"filter", "connect", "smtp-in", smtp_connect, NULL},
52 {"filter", "data", "smtp-in", smtp_data, NULL},
53 {"filter", "data-line", "smtp-in", smtp_data_line, NULL},
54 {"filter", "rset", "smtp-in", smtp_rset, NULL},
55 {"filter", "quit", "smtp-in", smtp_quit, NULL},
56 {"filter", "noop", "smtp-in", smtp_noop, NULL},
57 {"filter", "help", "smtp-in", smtp_help, NULL},
58 {"filter", "wiz", "smtp-in", smtp_wiz, NULL},
59 {"filter", "commit", "smtp-in", smtp_commit, NULL}
65 smtp_register_filter_connect(enum filter_decision (*cb)(char *, int, time_t,
66 char *, char *, uint64_t, uint64_t, struct smtp_filter_connect *))
68 return smtp_register("filter", "connect", "smtp-in", (smtp_cb) cb);
77 char *start, *end, *type, *direction, *phase, *params;
80 uint64_t reqid, token;
83 printf("register|ready\n");
86 while ((linelen = getline(&line, &linesize, stdin)) != -1) {
87 if (line[linelen - 1] != '\n')
88 errx(1, "Invalid line received: missing newline");
89 line[linelen - 1] = '\0';
91 if ((start = strchr(type, '|')) == NULL)
92 errx(1, "Invalid line received: missing version");
94 if ((end = strchr(start, '|')) == NULL)
95 errx(1, "Invalid line received: missing time");
97 if (strcmp(start, "1") != 0)
98 errx(1, "Unsupported protocol received: %s", start);
101 if ((direction = strchr(start, '|')) == NULL)
102 errx(1, "Invalid line received: missing direction");
103 direction++[0] = '\0';
104 tm = (time_t) strtoull(start, &end, 10);
105 if (start[0] == '\0' || end[0] != '\0')
106 errx(1, "Invalid line received: invalid timestamp");
107 if ((phase = strchr(direction, '|')) == NULL)
108 errx(1, "Invalid line receieved: missing phase");
110 if ((start = strchr(phase, '|')) == NULL)
111 errx(1, "Invalid line received: missing reqid");
113 reqid = strtoull(start, &end, 16);
114 if (start[0] == '|' || end[0] != '|')
115 errx(1, "Invalid line received: invalid reqid");
118 token = strtoull(start, &end, 16);
119 if (start[0] == '|' || end[0] != '|')
120 errx(1, "Invalid line received: invalid token");
123 for (i = 0; i < NITEMS(smtp_callbacks); i++) {
124 if (strcmp(type, smtp_callbacks[i].type) == 0 &&
125 strcmp(phase, smtp_callbacks[i].phase) == 0 &&
126 strcmp(direction, smtp_callbacks[i].direction) == 0)
129 if (i == NITEMS(smtp_callbacks)) {
130 errx(1, "Invalid line received: received unregistered "
131 "%s: %s", type, phase);
133 smtp_callbacks[i].smtp_parse(&(smtp_callbacks[i]), version, tm,
134 reqid, token, params);
139 smtp_connect(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
140 uint64_t token, char *params)
142 struct smtp_filter_connect sfconnect;
146 sfconnect.hostname = params;
147 if ((address = strchr(params, '|')) == NULL)
148 errx(1, "Invalid line received: missing address");
151 sfconnect.af = AF_INET;
152 if (strncasecmp(address, "ipv6:", 5) == 0) {
153 sfconnect.af = AF_INET6;
157 ret = inet_pton(sfconnect.af, address, sfconnect.af == AF_INET ?
158 (void *)&(sfconnect.addr) : (void *)&(sfconnect.addr6));
160 errx(1, "Invalid line received: Couldn't parse address");
162 err(1, "Couldn't convert address");
164 smtp_handle(cb, version, tm, reqid, token, (void *)(&sfconnect));
168 smtp_data(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
169 uint64_t token, char *params)
174 smtp_data_line(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
175 uint64_t token, char *params)
180 smtp_rset(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
181 uint64_t token, char *params)
186 smtp_quit(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
187 uint64_t token, char *params)
192 smtp_noop(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
193 uint64_t token, char *params)
198 smtp_help(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
199 uint64_t token, char *params)
204 smtp_wiz(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
205 uint64_t token, char *params)
210 smtp_commit(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
211 uint64_t token, char *params)
216 smtp_handle(struct smtp_callback *cb, int version, time_t tm, uint64_t reqid,
217 uint64_t token, void *params)
221 switch (cb->cb(cb->type, version, tm, cb->direction, cb->phase, reqid,
224 printf("filter-result|%016"PRIx64"|%016"PRIx64"|proceed\n",
228 printf("filter-result|%016"PRIx64"|%016"PRIx64"|reject|%s\n",
229 token, reqid, "451 Proper message later");
231 case FILTER_DISCONNECT:
232 printf("filter-result|%016"PRIx64"|%016"PRIx64"|disconnect|"
233 "%s\n", token, reqid, "421 Proper message later");
236 errx(1, "Not sure what is intended here yet");
241 smtp_register(char *type, char *phase, char *direction, smtp_cb cb)
246 errx(1, "Can't register when proc is running");
248 for (i = 0; i < NITEMS(smtp_callbacks); i++) {
249 if (strcmp(type, smtp_callbacks[i].type) == 0 &&
250 strcmp(phase, smtp_callbacks[i].phase) == 0 &&
251 strcmp(direction, smtp_callbacks[i].direction) == 0) {
252 if (smtp_callbacks[i].cb != NULL) {
256 smtp_callbacks[i].cb = cb;
257 printf("register|%s|%s|%s\n", type, direction, phase);
266 //filter|1|1553668146|smtp-in|connect|478cc771bf86f378|5161a9ce4540b4d1|<unknown>|100.64.7.2