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};
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()
155 if (getln(&
bi,&line,&
match,
'\n') == -1) temp_read();
156 if (case_starts(
line.s,
"DKIM-Signature: ")) r = 1;
158 for (
int i = 0; i <
line.len; i++) {
159 if (*(
line.s + i) ==
'=' && *(
line.s + i - 1) ==
'd') r = 2;
162 if (ch ==
'\n')
break;
163 if (ch ==
';') { r = 3;
break; }
164 if (ch !=
'=' && ch !=
' ' && ch !=
'\t' && ch !=
'\r')
169 if (r == 3 || !
match)
break;
178static int dkim_verify()
185 args[0] =
"qmail-dkim";
192 if (!(child = fork())) {
194 if (errno)
_exit(111);
198 wait_pid(&wstat,child);
199 if (wait_crashed(wstat))
return 1;
201 switch (r = wait_exitcode(wstat)) {
207static int dkim_result(
const char *me)
216 if ((
fd = open_read(
fndkout.s)) == -1)
return 0;
222 if (result.len > 2) {
223 if (case_starts(result.s,
"pass")) r = 0;
224 if (case_starts(result.s,
"fail")) r = 35;
230 if (!stralloc_cats(&dkheader,
"; dkim="))
temp_nomem();
234 for (
int j = 0;
j < result.len;
j++) {
236 if (ch ==
'\r' || ch ==
'\n' || ch ==
'\0')
continue;
237 if (
j <= max)
if (!stralloc_catb(&dkheader,&ch,1))
temp_nomem();
238 if (ch ==
' ' && (
j > max)) {
239 if (!stralloc_cats(&dkheader,
"\n "))
temp_nomem();
244 if (!stralloc_cats(&dkheader,
"; "))
temp_nomem();
245 if (!stralloc_cats(&dkheader,me))
temp_nomem();
251static int qmail_queue()
261 if (pipe(pi) == -1) die_pipe(
fndkin.s);
263 args[0] =
"qmail-queue";
266 switch (child = vfork()) {
268 close(pi[0]); close(pi[1]);
272 if (fd_move(0,pi[0]) == -1) die_pipe(
fndkin.s);
275 if (errno)
_exit(111);
282 if (dkheader.len > 2) {
291 while ((r = read(
fd,&ch,1)) > 0)
298 wait_pid(&wstat,child);
299 if (wait_crashed(wstat))
return 1;
301 switch (r = wait_exitcode(wstat)) {
307static void dkim_unlink()
309 if (unlink(
fndkin.s) == -1)
310 if (errno != ENOENT) temp_unlink();
312 if (errno != ENOENT) temp_unlink();
330 r = dkim_result(
me.s);
335 mode = env_get(
"DKIM");
336 if (!mode || *mode !=
'+') r = 0;
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]