1 #line 982 "../../src/builtin/snarf.m4"
2 /* -*- buffer-read-only: t -*- vi: set ro:
3 THIS FILE IS GENERATED AUTOMATICALLY. PLEASE DO NOT EDIT.
4 */
5 #line 982
6 #ifdef HAVE_CONFIG_H
7 #line 982
8 # include <config.h>
9 #line 982
10 #endif
11 #line 982
12 #include <sys/types.h>
13 #line 982
14
15 #line 982
16 #include "mailfromd.h"
17 #line 982
18 #include "prog.h"
19 #line 982
20 #include "builtin.h"
21 #line 982
22
23 #line 65 "dkim.bi"
24 static mu_debug_handle_t debug_handle;
25 #line 982 "../../src/builtin/snarf.m4"
26
27 #line 1022 "../../src/builtin/snarf.m4"
28
29 /* End of snarf.m4 */
30 #line 1 "dkim.bi"
31 /* This file is part of Mailfromd. -*- c -*-
32 Copyright (C) 2020-2021 Sergey Poznyakoff
33
34 This program is free software; you can redistribute it and/or modify
35 it under the terms of the GNU General Public License as published by
36 the Free Software Foundation; either version 3, or (at your option)
37 any later version.
38
39 This program is distributed in the hope that it will be useful,
40 but WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 GNU General Public License for more details.
43
44 You should have received a copy of the GNU General Public License
45 along with this program. If not, see <http://www.gnu.org/licenses/>. */
46
47
48 #ifdef WITH_DKIM
49 #line 18
50
51
52 #include "dkim.h"
53 #include "msg.h"
54
55 struct msgmod_data {
56 mu_message_t msg;
57 char const *h_list;
58 struct msgmod_closure *e_msgmod;
59 };
60
61 static int
message_replace_body(mu_message_t msg,mu_stream_t stream)62 message_replace_body(mu_message_t msg, mu_stream_t stream)
63 {
64 mu_body_t body;
65 int rc;
66
67 rc = mu_body_create(&body, msg);
68 if (rc) {
69 mu_diag_funcall(MU_DIAG_ERROR, "mu_body_create", NULL, rc);
70 return rc;
71 }
72
73 rc = mu_body_set_stream(body, stream, msg);
74 if (rc) {
75 mu_body_destroy(&body, msg);
76 mu_diag_funcall(MU_DIAG_ERROR, "mu_body_set_stream", NULL, rc);
77 return rc;
78 }
79
80 rc = mu_message_set_body(msg, body, mu_message_get_owner(msg));
81 if (rc) {
82 mu_body_destroy(&body, msg);
83 mu_diag_funcall(MU_DIAG_ERROR, "mu_message_set_body", NULL, rc);
84 }
85 return rc;
86 }
87
88 static int
do_msgmod(void * item,void * data)89 do_msgmod(void *item, void *data)
90 {
91 struct msgmod_closure *msgmod = item;
92 struct msgmod_data *md = data;
93 mu_header_t hdr;
94 mu_stream_t stream;
95 int rc;
96
97
98 #line 65 "dkim.bi"
99
100 #line 65
101 mu_debug(debug_handle, MU_DEBUG_TRACE6,("%s %s: %s %u",
102 msgmod_opcode_str(msgmod->opcode),
103 SP(msgmod->name), SP(msgmod->value), msgmod->idx));
104 #line 69
105
106 mu_message_get_header(md->msg, &hdr);
107
108 switch (msgmod->opcode) {
109 case header_replace:
110 if (!dkim_header_list_match(md->h_list, msgmod->name))
111 break;
112 if (mu_header_sget_value(hdr, msgmod->name, NULL) == 0) {
113 rc = mu_header_insert(hdr, msgmod->name, msgmod->value,
114 NULL,
115 msgmod->idx, MU_HEADER_REPLACE);
116 if (rc == MU_ERR_NOENT) {
117 rc = mu_header_append(hdr, msgmod->name, msgmod->value);
118 if (rc)
119 mu_diag_funcall(MU_DIAG_ERROR,
120 "mu_header_insert",
121 msgmod->name,
122 rc);
123 } else if (rc) {
124 mu_diag_funcall(MU_DIAG_ERROR,
125 "mu_header_insert",
126 msgmod->name,
127 rc);
128 }
129 } else {
130 rc = mu_header_append(hdr, msgmod->name, msgmod->value);
131 if (rc)
132 mu_diag_funcall(MU_DIAG_ERROR,
133 "mu_header_append",
134 msgmod->name,
135 rc);
136 }
137 if (rc) {
138 md->e_msgmod = msgmod;
139 return rc;
140 }
141 break;
142
143 case header_delete:
144 if (!dkim_header_list_match(md->h_list, msgmod->name))
145 break;
146 rc = mu_header_remove(hdr, msgmod->name, msgmod->idx);
147 if (rc && rc != MU_ERR_NOENT) {
148 mu_diag_funcall(MU_DIAG_ERROR,
149 "mu_header_remove",
150 msgmod->name,
151 rc);
152 md->e_msgmod = msgmod;
153 return rc;
154 }
155 break;
156
157 case body_repl:
158 rc = mu_static_memory_stream_create(&stream, msgmod->value,
159 strlen(msgmod->value));
160 if (rc) {
161 md->e_msgmod = msgmod;
162 return rc;
163 }
164 rc = message_replace_body(md->msg, stream);
165 if (rc) {
166 mu_stream_destroy(&stream);
167 md->e_msgmod = msgmod;
168 return rc;
169 }
170 break;
171
172 case body_repl_fd:
173 rc = mu_fd_stream_create (&stream, "<body_repl_fd>",
174 msgmod->idx,
175 MU_STREAM_READ);
176 if (rc) {
177 md->e_msgmod = msgmod;
178 return rc;
179 }
180 rc = message_replace_body(md->msg, stream);
181 if (rc) {
182 mu_stream_destroy(&stream);
183 md->e_msgmod = msgmod;
184 return rc;
185 }
186 break;
187
188 case header_add:
189 case header_insert:
190 if (!dkim_header_list_match(md->h_list, msgmod->name))
191 break;
192 md->e_msgmod = msgmod;
193 return MU_ERR_USER0;
194
195 case rcpt_add:
196 case rcpt_delete:
197 case quarantine:
198 case set_from:
199 break;
200 }
201 return 0;
202 }
203
204
205
206 void
207 #line 170
bi_dkim_sign(eval_environ_t env)208 bi_dkim_sign(eval_environ_t env)
209 #line 170
210
211 #line 170
212
213 #line 170 "dkim.bi"
214 {
215 #line 170
216
217 #line 170
218
219 #line 170
220 long __bi_argcnt;
221 #line 170
222 char * d;
223 #line 170
224 char * s;
225 #line 170
226 char * keyfile;
227 #line 170
228 char * canon_h;
229 #line 170
230 char * canon_b;
231 #line 170
232 char * headers;
233 #line 170
234
235 #line 170
236 get_string_arg(env, 1, &d);
237 #line 170
238 get_string_arg(env, 2, &s);
239 #line 170
240 get_string_arg(env, 3, &keyfile);
241 #line 170
242 get_string_arg(env, 4, &canon_h);
243 #line 170
244 get_string_arg(env, 5, &canon_b);
245 #line 170
246 get_string_arg(env, 6, &headers);
247 #line 170
248
249 #line 170
250 get_numeric_arg(env, 0, &__bi_argcnt);
251 #line 170
252 adjust_stack(env, __bi_argcnt + 1);
253 #line 170
254
255 #line 170
256
257 #line 170
258 if (builtin_module_trace(BUILTIN_IDX_dkim))
259 #line 170
260 prog_trace(env, "dkim_sign %s %s %s %s %s %s",d, s, keyfile, ((__bi_argcnt > 3) ? canon_h : ""), ((__bi_argcnt > 4) ? canon_b : ""), ((__bi_argcnt > 5) ? headers : ""));;
261 #line 172
262
263 {
264 struct dkim_signature sig = {
265 .v = DKIM_VERSION,
266 .a = DKIM_ALGORITHM,
267 .d = d,
268 .s = s,
269 .canon = { DKIM_CANON_SIMPLE, DKIM_CANON_SIMPLE },
270 .q = DKIM_QUERY_METHOD,
271 .l = DKIM_LENGTH_ALL
272 };
273 static char default_headers[] =
274 "From:From:"
275 "Reply-To:Reply-To:"
276 "Subject:Subject:"
277 "Date:Date:"
278 "To:"
279 "Cc:"
280 "Resent-Date:"
281 "Resent-From:"
282 "Resent-To:"
283 "Resent-Cc:"
284 "In-Reply-To:"
285 "References:"
286 "List-Id:"
287 "List-Help:"
288 "List-Unsubscribe:"
289 "List-Subscribe:"
290 "List-Post:"
291 "List-Owner:"
292 "List-Archive";
293 mu_message_t msg;
294 int rc;
295 char *sighdr, *p;
296 struct mu_locus_range locus;
297
298 env_get_locus(env, &locus);
299
300 if ((__bi_argcnt > 3)) {
301 sig.canon[0] = dkim_str_to_canon_type(canon_h, NULL);
302 if (sig.canon[0] == DKIM_CANON_ERR)
303 (
304 #line 213
305 env_throw_bi(env, mfe_failure, "dkim_sign", _("bad canonicalization type: %s"),canon_h)
306 #line 213
307 );
308 #line 215
309 }
310 if ((__bi_argcnt > 4)) {
311 sig.canon[1] = dkim_str_to_canon_type(canon_b, NULL);
312 if (sig.canon[1] == DKIM_CANON_ERR)
313 (
314 #line 219
315 env_throw_bi(env, mfe_failure, "dkim_sign", _("bad canonicalization type: %s"),canon_b)
316 #line 219
317 );
318 #line 221
319 }
320
321 sig.h = ((__bi_argcnt > 5) ? headers : default_headers);
322 bi_get_current_message(env, &msg);
323 if (env_msgmod_count(env)) {
324 struct msgmod_data mdat;
325
326 rc = mu_message_create_copy(&mdat.msg, msg);
327 if (rc) {
328 mu_diag_funcall(MU_DIAG_ERROR,
329 "mu_message_create_copy",
330 NULL, rc);
331 (
332 #line 233
333 env_throw_bi(env, mfe_failure, "dkim_sign", "mu_message_create_copy: %s",mu_strerror(rc))
334 #line 233
335 );
336 #line 236
337 }
338 mdat.h_list = sig.h;
339 mdat.e_msgmod = 0;
340 rc = env_msgmod_apply(env, do_msgmod, &mdat);
341 if (rc) {
342 mu_message_unref(mdat.msg);
343 if (rc == MU_ERR_USER0) {
344 (
345 #line 243
346 env_throw_bi(env, mfe_badmmq, "dkim_sign", _("MMQ incompatible with dkim_sign: %s on %s, value %s"),msgmod_opcode_str(mdat.e_msgmod->opcode),mdat.e_msgmod->name,SP(mdat.e_msgmod->value))
347 #line 243
348 );
349 #line 248
350 } else if (mdat.e_msgmod) {
351 (
352 #line 249
353 env_throw_bi(env, mfe_failure, "dkim_sign", _("%s failed on %s, value %s: %s"),msgmod_opcode_str(mdat.e_msgmod->opcode),mdat.e_msgmod->name,SP(mdat.e_msgmod->value),mu_strerror(rc))
354 #line 249
355 );
356 #line 255
357 } else
358 (
359 #line 256
360 env_throw_bi(env, mfe_failure, "dkim_sign", _("error: %s"),mu_strerror(rc))
361 #line 256
362 );
363 #line 259
364 }
365 msg = mdat.msg;
366 } else
367 mu_message_ref(msg);
368
369 rc = mfd_dkim_sign(msg, &sig, keyfile, &sighdr);
370 mu_message_unref(msg);
371 if (!(rc == 0))
372 #line 266
373 (
374 #line 266
375 env_throw_bi(env, mfe_failure, "dkim_sign", _("DKIM failed"))
376 #line 266
377 )
378 #line 266
379 ;
380
381 p = strchr(sighdr, ':');
382 *p++ = 0;
383 while (mu_isblank(*p))
384 p++;
385
386 trace("%s%s:%u: %s %d \"%s: %s\"",
387 mailfromd_msgid(env_get_context(env)),
388 locus.beg.mu_file, locus.beg.mu_line,
389 msgmod_opcode_str(header_insert),
390 0,
391 sighdr, p);
392 env_msgmod_append(env, header_insert, sighdr, p, 0);
393 free(sighdr);
394 }
395
396 #line 282
397 env_function_cleanup_flush(env, NULL);
398 #line 282
399 return;
400 #line 282
401 }
402
403 static size_t dkim_explanation_code_loc
404 #line 284 "dkim.bi"
405 ;
406 static size_t dkim_explanation_loc
407 #line 285 "dkim.bi"
408 ;
409 static size_t dkim_verified_signature_loc
410 #line 286 "dkim.bi"
411 ;
412
413
414 void
415 #line 289
bi_dkim_verify(eval_environ_t env)416 bi_dkim_verify(eval_environ_t env)
417 #line 289
418
419 #line 289
420
421 #line 289 "dkim.bi"
422 {
423 #line 289
424
425 #line 289
426
427 #line 289
428
429 #line 289
430 long nmsg;
431 #line 289
432
433 #line 289
434 get_numeric_arg(env, 0, &nmsg);
435 #line 289
436
437 #line 289
438
439 #line 289
440 adjust_stack(env, 1);
441 #line 289
442
443 #line 289
444
445 #line 289
446 if (builtin_module_trace(BUILTIN_IDX_dkim))
447 #line 289
448 prog_trace(env, "dkim_verify %lu",nmsg);;
449 #line 289
450
451 {
452 mu_message_t msg = bi_message_from_descr(env, nmsg);
453 char *sig;
454 int result = mfd_dkim_verify(msg, &sig);
455 mf_c_val(*env_data_ref(env, dkim_explanation_code_loc),long) = (result);
456
457 #line 295
458 { size_t __off;
459 #line 295
460 const char *__s = dkim_explanation_str[result];
461 #line 295
462 if (__s)
463 #line 295
464 strcpy((char*)env_data_ref(env, __off = heap_reserve(env, strlen(__s) + 1)), __s);
465 #line 295
466 else
467 #line 295
468 __off = 0;
469 #line 295
470 mf_c_val(*env_data_ref(env, dkim_explanation_loc),size) = (__off); }
471 #line 295
472 ;
473 if (dkim_result_trans[result] == DKIM_VERIFY_OK) {
474
475 #line 297
476 { size_t __off;
477 #line 297
478 const char *__s = sig;
479 #line 297
480 if (__s)
481 #line 297
482 strcpy((char*)env_data_ref(env, __off = heap_reserve(env, strlen(__s) + 1)), __s);
483 #line 297
484 else
485 #line 297
486 __off = 0;
487 #line 297
488 mf_c_val(*env_data_ref(env, dkim_verified_signature_loc),size) = (__off); }
489 #line 297
490 ;
491 } else {
492
493 #line 299
494 { size_t __off;
495 #line 299
496 const char *__s = "";
497 #line 299
498 if (__s)
499 #line 299
500 strcpy((char*)env_data_ref(env, __off = heap_reserve(env, strlen(__s) + 1)), __s);
501 #line 299
502 else
503 #line 299
504 __off = 0;
505 #line 299
506 mf_c_val(*env_data_ref(env, dkim_verified_signature_loc),size) = (__off); }
507 #line 299
508 ;
509 }
510
511 #line 301
512 do {
513 #line 301
514 push(env, (STKVAL)(mft_number)(dkim_result_trans[result]));
515 #line 301
516 goto endlab;
517 #line 301
518 } while (0);
519 }
520 endlab:
521 #line 303
522 env_function_cleanup_flush(env, NULL);
523 #line 303
524 return;
525 #line 303
526 }
527 #line 982 "../../src/builtin/snarf.m4"
528
529 #line 982
530
531 #line 982
532 #endif /* WITH_DKIM */
533 #line 982
534
535 #line 982
536 void
537 #line 982
dkim_init_builtin(void)538 dkim_init_builtin(void)
539 #line 982
540 {
541 #line 982
542 debug_handle = mu_debug_register_category("bi_dkim");
543 #line 982
544
545 #line 982
546 #ifdef WITH_DKIM
547 #line 982
548 pp_define("WITH_DKIM");
549 #line 982
550 #line 170 "dkim.bi"
551 va_builtin_install_ex("dkim_sign", bi_dkim_sign, STATMASK(smtp_state_eom), dtype_unspecified, 6, 3, MFD_BUILTIN_CAPTURE|0, dtype_string, dtype_string, dtype_string, dtype_string, dtype_string, dtype_string);
552 #line 284 "dkim.bi"
553 builtin_variable_install("dkim_explanation_code", dtype_number, SYM_VOLATILE, &dkim_explanation_code_loc);
554 #line 285 "dkim.bi"
555 builtin_variable_install("dkim_explanation", dtype_string, SYM_VOLATILE, &dkim_explanation_loc);
556 #line 286 "dkim.bi"
557 builtin_variable_install("dkim_verified_signature", dtype_string, SYM_VOLATILE, &dkim_verified_signature_loc);
558 #line 289 "dkim.bi"
559 va_builtin_install_ex("dkim_verify", bi_dkim_verify, 0, dtype_number, 1, 0, 0|0, dtype_number);
560
561 #line 982 "../../src/builtin/snarf.m4"
562
563 #line 982
564 #endif /* WITH_DKIM */
565 #line 982
566 }
567 #line 982 "../../src/builtin/snarf.m4"
568
569