Commit Diff


commit - 5f5f9df0fb9731664a2b3fe1c002f569aaa9239e
commit + 2bff1e0dd3746ad335de1c4fcc8f43e7790b4839
blob - a80fe73155a15ab043e1a707f959f87e196668da
blob + c655cc4e4bb605f09ee68cf2aae27c8c0359340e
--- ltok.c
+++ ltok.c
@@ -1862,15 +1862,88 @@ osmtpd_ltok_skip_x_key_t_tag_flag(const char *ptr, int
 const char *
 osmtpd_ltok_skip_ar_pvalue(const char *ptr, int optional)
 {
-	const char *start = ptr, *tmp;
+	const char *start = ptr, *value, *addr, *local;
 
-	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
-	if ((tmp = osmtpd_ltok_skip_value(ptr, 0)) != NULL)
-		return tmp;
-	ptr = osmtpd_ltok_skip_local_part(ptr, 1);
-	if (ptr[0] == '@')
-		ptr++;
-	if ((ptr = osmtpd_ltok_skip_domain(ptr, 0)) == NULL)
+	ptr = osmtpd_ltok_skip_cfws(start, 1);
+
+	value = osmtpd_ltok_skip_value(ptr, 1);
+	addr = osmtpd_ltok_skip_addr_spec(ptr, 1);
+	local = osmtpd_ltok_skip_local_part(ptr, 1);
+
+	if (value > ptr)
+		ptr = value;
+
+	if (addr > ptr)
+		ptr = addr;
+
+	if (local > ptr)
+		ptr = local;
+
+	if (ptr == NULL)
 		return optional ? start : NULL;
+
 	return ptr;
 }
+
+const char *
+osmtpd_ltok_skip_ar_propspec(const char *ptr, int optional)
+{
+	const char *start = ptr;
+
+	if (strncmp(ptr, "smtp", sizeof("smtp") - 1) == 0)
+		ptr += sizeof("smtp") - 1;
+	else if (strncmp(ptr, "header", sizeof("header") - 1) == 0)
+		ptr += sizeof("header") - 1;
+	else if (strncmp(ptr, "body", sizeof("body") - 1) == 0)
+		ptr += sizeof("body") - 1;
+	else if (strncmp(ptr, "policy", sizeof("policy") - 1) == 0)
+		ptr += sizeof("policy") - 1;
+	else
+		return optional ? start : NULL;
+
+	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
+
+	if (*ptr != '.')
+		return optional ? start : NULL;
+	ptr++;
+
+	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
+
+	if ((ptr = osmtpd_ltok_skip_keyword(ptr, 0)) == NULL)
+		return optional ? start : NULL;
+
+	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
+
+	if (*ptr != '=')
+		return optional ? start : NULL;
+	ptr++;
+
+	if ((ptr = osmtpd_ltok_skip_ar_pvalue(ptr, 0)) == NULL)
+		return optional ? start : NULL;
+
+	return ptr;
+}
+
+const char *
+osmtpd_ltok_skip_ar_reasonspec(const char *ptr, int optional)
+{
+	const char *start = ptr;
+
+	if (strncmp(ptr, "reason", sizeof("reason") - 1) != 0)
+		return optional ? start : NULL;
+
+	ptr += sizeof("reason") - 1;
+
+	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
+
+	if (*ptr != '=')
+		return optional ? start : NULL;
+	ptr++;
+
+	ptr = osmtpd_ltok_skip_cfws(ptr, 1);
+
+	if ((ptr = osmtpd_ltok_skip_value(ptr, 0)) == NULL)
+		return optional ? start : NULL;
+
+	return ptr;
+}
blob - cee68002870cea1b7b26b1c6f40800b7b93f04c1
blob + cfc1e74a9bf973c4ca7a00ced5849076188a2453
--- ltok.h
+++ ltok.h
@@ -167,6 +167,8 @@ const char *osmtpd_ltok_skip_key_t_tag_flag(const char
 const char *osmtpd_ltok_skip_x_key_t_tag_flag(const char *, int);
 
 /* Authentication-Results */
+const char *osmtpd_ltok_skip_ar_propspec(const char *, int);
+const char *osmtpd_ltok_skip_ar_reasonspec(const char *, int);
 const char *osmtpd_ltok_skip_ar_pvalue(const char *, int);
 
 const char *osmtpd_ltok_domain_uncomment(const char *);
blob - 886cf1e7e01098aa49c5e1a3511f8c6f41466e68
blob + 397b26033ea5ced5eeb1a66bfdf14a35bbc6b97a
--- main.c
+++ main.c
@@ -1684,6 +1684,7 @@ dkim_ar_print(struct osmtpd_ctx *ctx, const char *star
 			start = osmtpd_ltok_skip_cfws(checkpoint, 1);
 			if (*start == '\0')
 				return;
+			ncheckpoint = start;
 			scan = start;
 			arlen = 8;
 			first = 0;
@@ -1704,16 +1705,19 @@ dkim_ar_print(struct osmtpd_ctx *ctx, const char *star
 			/* reasonspec */
 			} else if (strncmp(ncheckpoint, "reason",
 			    sizeof("reason") - 1) == 0) {
-				ncheckpoint = osmtpd_ltok_skip_value(
-				    ncheckpoint + sizeof("reason"), 0);
+				ncheckpoint = osmtpd_ltok_skip_ar_reasonspec(
+				    ncheckpoint, 0);
 			/* propspec */
 			} else {
-				ncheckpoint += sizeof("header.x=") - 1;
-				ncheckpoint = osmtpd_ltok_skip_ar_pvalue(
+				ncheckpoint = osmtpd_ltok_skip_ar_propspec(
 				    ncheckpoint, 0);
-				if (ncheckpoint[0] == ';')
-					ncheckpoint++;
-			}
+			}
+
+			if (ncheckpoint == NULL)
+				osmtpd_errx(1, "Invalid AR line: |%s", scan);
+
+			if (*ncheckpoint == ';')
+				ncheckpoint++;
 		}
 	}
 	osmtpd_filter_dataline(ctx, "%s%s", first ? "" : "\t", start);