29#define WHO "qmail-dkverify"
50static void die_pipe(
char *
fn) { unlink(
fn);
die(54); };
53static void out(
char *s) {
if (buffer_puts(&
bo,s) == -1)
_exit(111); }
54static void zero() {
if (buffer_put(&
bo,
"\0",1) == -1)
_exit(111); }
59 out(
"ZOut of memory. (#4.3.0)\n");
62static void temp_chdir()
64 out(
"ZUnable to switch to target directory. (#4.3.0)\n");
67static void temp_unlink()
69 out(
"ZUnable to unlink DKIM stage file. (#4.3.0)\n");
72static void temp_read()
74 out(
"ZUnable to read message. (#4.3.0)\n");
77static void temp_control()
79 out(
"ZUnable to read control files. (#4.3.0)\n");
83static stralloc
me = {0};
84static stralloc signdomain = {0};
85static stralloc dkheader = {0};
86static stralloc
fndkin = {0};
88static stralloc result = {0};
90static stralloc temp = {0};
92static void fnmake_dkim(
unsigned long id)
99static void dkim_stage()
112 fnmake_dkim(getpid());
134 if (buffer_flush(&
bo) == -1)
die(51);
140static int mess_dkim()
156 if (getln(&
bi,&line,&
match,
'\n') == -1) temp_read();
157 if (case_starts(
line.s,
"DKIM-Signature: ")) r = 1;
159 for (i = 1; i <
line.len; i++) {
160 if (r == 1 && *(
line.s + i) ==
'=' && *(
line.s + i - 1) ==
'd') r = 2;
163 if (ch ==
';') { r = 3;
goto DONE; }
164 if (ch ==
'\n')
break;
165 if (ch !=
'=' && ch !=
' ' && ch !=
'\t' && ch !=
'\r')
166 if (!stralloc_catb(&signdomain,&ch,1))
temp_nomem();
181static int dkim_verify()
188 args[0] =
"qmail-dkim";
195 if (!(child = fork())) {
197 if (errno)
_exit(111);
201 wait_pid(&wstat,child);
202 if (wait_crashed(wstat))
return 1;
204 switch (r = wait_exitcode(wstat)) {
210static int dkim_result(
const char *me)
219 if ((
fd = open_read(
fndkout.s)) == -1)
return 0;
225 if (result.len > 2) {
226 if (case_starts(result.s,
"pass")) r = 0;
227 if (case_starts(result.s,
"fail")) r = 35;
232 if (!stralloc_cats(&dkheader,signdomain.s))
temp_nomem();
233 if (!stralloc_cats(&dkheader,
"; dkim="))
temp_nomem();
237 for (
int j = 0;
j < result.len;
j++) {
239 if (ch ==
'\r' || ch ==
'\n' || ch ==
'\0')
continue;
240 if (
j <= max)
if (!stralloc_catb(&dkheader,&ch,1))
temp_nomem();
241 if (ch ==
' ' && (
j > max)) {
242 if (!stralloc_cats(&dkheader,
"\n "))
temp_nomem();
247 if (!stralloc_cats(&dkheader,
"; "))
temp_nomem();
248 if (!stralloc_cats(&dkheader,me))
temp_nomem();
254static int qmail_queue()
264 if (pipe(pi) == -1) die_pipe(
fndkin.s);
266 args[0] =
"qmail-queue";
269 switch (child = vfork()) {
271 close(pi[0]); close(pi[1]);
275 if (fd_move(0,pi[0]) == -1) die_pipe(
fndkin.s);
278 if (errno)
_exit(111);
285 if (dkheader.len > 2) {
294 while ((r = read(
fd,&ch,1)) > 0)
301 wait_pid(&wstat,child);
302 if (wait_crashed(wstat))
return 1;
304 switch (r = wait_exitcode(wstat)) {
310static void dkim_unlink()
312 if (unlink(
fndkin.s) == -1)
313 if (errno != ENOENT) temp_unlink();
315 if (errno != ENOENT) temp_unlink();
333 r = dkim_result(
me.s);
338 mode = env_get(
"DKIM");
339 if (!mode || *mode !=
'+') r = 0;
340 if (!r) qmail_queue();
int control_readline(stralloc *sa, char *fn)
int stralloc_copys(stralloc *, char const *)
unsigned int fmtqfn(char *s, char *dirslash, unsigned long id, int flagsplit)
char tmpbuf[BUFSIZE_LINE]
char outbuf[BUFSIZE_MESS]