From: Baptiste Daroussin Date: Fri, 13 Jun 2025 13:33:57 +0000 (+0200) Subject: probe: send message-id is possibel in probe emails X-Git-Tag: RELEASE_1.6.0~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2550bb1af74b33131e88f67bb855e86ba48ad0fa;p=thirdparty%2Fmlmmj.git probe: send message-id is possibel in probe emails When sending the probe emails, tries to add the message-id in the message, to help users figuring finding the wrong email Fixes: #8 --- diff --git a/include/prepstdreply.h b/include/prepstdreply.h index 456b0e88..34f815f6 100644 --- a/include/prepstdreply.h +++ b/include/prepstdreply.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004 Mads Martin Joergensen * Copyright (C) 2011 Ben Schmidt - * Copyright (C) 2023-2024 Baptiste Daroussin + * Copyright (C) 2023-2025 Baptiste Daroussin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -48,8 +48,10 @@ void finish_memory_lines(memory_lines_state *s); file_lines_state *init_file_lines(const char *filename, char truncate); file_lines_state *init_file_lines_fd(int fd, char truncate); +file_lines_state *init_file_lines_data(int fd, char truncate, void *data); void rewind_file_lines(void *state); const char *get_file_line(void *state); +const char *get_msgid_line(void *state); void finish_file_lines(file_lines_state *s); char *substitute(const char *line, int listfd, int ctrlfd, text *txt); diff --git a/src/mlmmj.c b/src/mlmmj.c index eb158c60..d3016ced 100644 --- a/src/mlmmj.c +++ b/src/mlmmj.c @@ -84,9 +84,9 @@ send_probe(struct ml *ml, const char *addr) txt = open_text(ml->fd, "probe", NULL, NULL, NULL, "bounce-probe"); MY_ASSERT(txt); register_default_unformatted(txt, ml); - fls = init_file_lines_fd(openat(bfd, addr, O_RDONLY), ':'); + fls = init_file_lines_data(openat(bfd, addr, O_RDONLY), ':', ml); register_formatted(txt, "bouncenumbers", - rewind_file_lines, get_file_line, fls); + rewind_file_lines, get_msgid_line, fls); queuefilename = prepstdreply(txt, ml, "$listowner$", myaddr, NULL); MY_ASSERT(queuefilename); close_text(txt); diff --git a/src/prepstdreply.c b/src/prepstdreply.c index b14ecb1e..7b340046 100644 --- a/src/prepstdreply.c +++ b/src/prepstdreply.c @@ -2,7 +2,7 @@ * Copyright (C) 2004 Mads Martin Joergensen * Copyright (C) 2007 Morten K. Poulsen * Copyright (C) 2011 Ben Schmidt - * Copyright (C) 2023 Baptiste Daroussin + * Copyright (C) 2023-2025 Baptiste Daroussin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -43,6 +43,7 @@ #include "mlmmj.h" #include "unistr.h" #include "xstring.h" +#include "do_all_the_voodoo_here.h" struct substitution { char *token; @@ -136,6 +137,8 @@ struct file_lines_state { char truncate; char *line; size_t linecap; + char *formatted_str; + void *data; }; @@ -211,6 +214,17 @@ file_lines_state return (s); } +file_lines_state * +init_file_lines_data(int fd, char truncate, void *data) +{ + file_lines_state *s; + + s = init_file_lines_fd(fd, truncate); + if (s == NULL) + return (NULL); + s->data = data; + return (s); +} void rewind_file_lines(void *state) { @@ -243,10 +257,44 @@ const char *get_file_line(void *state) return s->line; } +const char * +get_msgid_line(void *state) +{ + file_lines_state *s = (file_lines_state *)state; + const char *id = get_file_line(state); + if (id == NULL) + return (NULL); + if (s->data == NULL) { + return (id); + } + struct ml *m = (struct ml *)s->data; + struct mailhdr readhdrs[] = { + { "Message-ID", 0, NULL }, + { NULL, 0, NULL } + }; + int archive_fd = openat(m->fd, "archive", O_DIRECTORY|O_RDONLY); + if (archive_fd == -1) + return (id); + int msgfd = openat(archive_fd, id, O_RDONLY); + close(archive_fd); + if (msgfd == -1) + return (id); + FILE *f = fdopen(msgfd, "r"); + scan_headers(f, readhdrs, NULL, NULL); + fclose(f); + if (readhdrs[0].valuecount == 0) + return (id); + free(s->formatted_str); + xasprintf(&s->formatted_str, "%s, %s%s", + id, readhdrs[0].token, readhdrs[0].values[0]); + return (s->formatted_str); +} + void finish_file_lines(file_lines_state *s) { if (s == NULL) return; - if (s->line != NULL) free(s->line); + free(s->line); + free(s->formatted_str); if (s->fp != NULL) fclose(s->fp); if (s->filename != NULL) free(s->filename); free(s); diff --git a/tests/mlmmj.c b/tests/mlmmj.c index 1cb59bf0..9c74d318 100644 --- a/tests/mlmmj.c +++ b/tests/mlmmj.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "atf-c/macros.h" #include "atf-c/utils.h" @@ -158,7 +159,10 @@ ATF_TC_WITHOUT_HEAD(requeuemail); ATF_TC_WITHOUT_HEAD(gethdrline); ATF_TC_WITHOUT_HEAD(readlf); ATF_TC_WITHOUT_HEAD(mod_get_addr_type); +ATF_TC_WITHOUT_HEAD(send_probe_no_probefile); +ATF_TC_WITHOUT_HEAD(send_probe_arobase); ATF_TC_WITHOUT_HEAD(send_probe); +ATF_TC_WITHOUT_HEAD(send_probe_archive); ATF_TC_WITHOUT_HEAD(parse_content_type); ATF_TC_WITHOUT_HEAD(find_in_list); ATF_TC_WITHOUT_HEAD(do_access); @@ -2817,7 +2821,7 @@ ATF_TC_BODY(mod_get_addr_type, tc) atf_utils_wait(p, 1, "", ""); } -ATF_TC_BODY(send_probe, tc) +ATF_TC_BODY(send_probe_no_probefile, tc) { init_ml(true); struct ml ml; @@ -2844,19 +2848,79 @@ ATF_TC_BODY(send_probe, tc) atf_utils_cat_file("mailout.txt", ""); atf_tc_fail("invalid file"); } +} - p = atf_utils_fork(); +ATF_TC_BODY(send_probe_arobase, tc) +{ + init_ml(true); + struct ml ml; + ml_init(&ml); + ml.dir = "list"; + ml_open(&ml, false); + setup_listtext(tc); + atf_utils_create_file("list/control/smtpport", "25678"); + atf_utils_create_file("list/control/smtphelo", "heloname"); + int smtppipe[2]; + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0); + pid_t p = atf_utils_fork(); if (p == 0) { if (send_probe(&ml, "bapt@freebsd.org")) exit(0); exit(1); } atf_utils_wait(p, 1, "", ""); +} - atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n"); - p2 = single_mail_reception(smtppipe[1]); +ATF_TC_BODY(send_probe, tc) +{ + init_ml(true); + struct ml ml; + ml_init(&ml); + ml.dir = "list"; + ml_open(&ml, false); + setup_listtext(tc); + atf_utils_create_file("list/control/smtpport", "25678"); + atf_utils_create_file("list/control/smtphelo", "heloname"); + int smtppipe[2]; + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0); + pid_t p2 = single_mail_reception(smtppipe[1]); atf_utils_readline(smtppipe[0]); - p = atf_utils_fork(); + + atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n32:qftgd\n"); + pid_t p = atf_utils_fork(); + if (p == 0) { + if (send_probe(&ml, "bapt=freebsd.org")) + exit(0); + exit(1); + } + atf_utils_wait(p2, 0, "save:mailout.txt", ""); + atf_utils_wait(p, 0, "", ""); + + if (!atf_utils_grep_file("1234\r", "mailout.txt")) { + atf_utils_cat_file("mailout.txt", ">"); + atf_tc_fail("invalid mail sent"); + } +} + +ATF_TC_BODY(send_probe_archive, tc) +{ + init_ml(true); + struct ml ml; + ml_init(&ml); + ml.dir = "list"; + ml_open(&ml, false); + setup_listtext(tc); + atf_utils_create_file("list/control/smtpport", "25678"); + atf_utils_create_file("list/control/smtphelo", "heloname"); + int smtppipe[2]; + ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0); + pid_t p2 = single_mail_reception(smtppipe[1]); + atf_utils_readline(smtppipe[0]); + + atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n21:hey\n32:ertt\n"); + atf_utils_create_file("list/archive/1234", "From: bob@test\nMessage-ID: \nX-None: bla\n\nContent\n"); + atf_utils_create_file("list/archive/21", "From: bob@test\nMessage-ID: \nX-None: bla\n\nContent\n"); + pid_t p = atf_utils_fork(); if (p == 0) { if (send_probe(&ml, "bapt=freebsd.org")) exit(0); @@ -2864,7 +2928,16 @@ ATF_TC_BODY(send_probe, tc) } atf_utils_wait(p2, 0, "save:mailout.txt", ""); atf_utils_wait(p, 0, "", ""); - if (!atf_utils_grep_file("1234", "mailout.txt")) { + + if (!atf_utils_grep_file("- 1234, Message-ID: \r", "mailout.txt")) { + atf_utils_cat_file("mailout.txt", ">"); + atf_tc_fail("invalid mail sent"); + } + if (!atf_utils_grep_file("- 21, Message-ID: \r", "mailout.txt")) { + atf_utils_cat_file("mailout.txt", ">"); + atf_tc_fail("invalid mail sent"); + } + if (!atf_utils_grep_file("- 32\r", "mailout.txt")) { atf_utils_cat_file("mailout.txt", ">"); atf_tc_fail("invalid mail sent"); } @@ -3094,7 +3167,10 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, gethdrline); ATF_TP_ADD_TC(tp, readlf); ATF_TP_ADD_TC(tp, mod_get_addr_type); + ATF_TP_ADD_TC(tp, send_probe_no_probefile); + ATF_TP_ADD_TC(tp, send_probe_arobase); ATF_TP_ADD_TC(tp, send_probe); + ATF_TP_ADD_TC(tp, send_probe_archive); ATF_TP_ADD_TC(tp, parse_content_type); ATF_TP_ADD_TC(tp, find_in_list); ATF_TP_ADD_TC(tp, do_access);