tom 2009/06/08 22:06:32 BST
Modified files: (Branch: DEVEL_PDKIM)
exim-src/src dkim.c dkim.h expand.c receive.c
Log:
Add a bunch of expandables and some DKIM ACL red tape
Revision Changes Path
1.1.2.15 +176 -22 exim/exim-src/src/dkim.c
1.1.2.5 +23 -12 exim/exim-src/src/dkim.h
1.97.2.3 +24 -0 exim/exim-src/src/expand.c
1.45.2.5 +19 -4 exim/exim-src/src/receive.c
Index: dkim.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/Attic/dkim.c,v
retrieving revision 1.1.2.14
retrieving revision 1.1.2.15
diff -u -r1.1.2.14 -r1.1.2.15
--- dkim.c 27 May 2009 17:29:35 -0000 1.1.2.14
+++ dkim.c 8 Jun 2009 21:06:31 -0000 1.1.2.15
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/dkim.c,v 1.1.2.14 2009/05/27 17:29:35 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/dkim.c,v 1.1.2.15 2009/06/08 21:06:31 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -18,6 +18,7 @@
pdkim_ctx *dkim_verify_ctx = NULL;
pdkim_signature *dkim_signatures = NULL;
+pdkim_signature *dkim_cur_sig = NULL;
int dkim_exim_query_dns_txt(char *name, char *answer) {
dns_answer dnsa;
@@ -79,6 +80,7 @@
void dkim_exim_verify_finish(void) {
+ pdkim_signature *sig = NULL;
int dkim_signing_domains_size = 0;
int dkim_signing_domains_ptr = 0;
dkim_signing_domains = NULL;
@@ -99,49 +101,49 @@
/* Finish DKIM operation and fetch link to signatures chain */
if (pdkim_feed_finish(dkim_verify_ctx,&dkim_signatures) != PDKIM_OK) return;
-
- while (dkim_signatures != NULL) {
+ sig = dkim_signatures;
+ while (sig != NULL) {
int size = 0;
int ptr = 0;
/* Log a line for each signature */
uschar *logmsg = string_append(NULL, &size, &ptr, 5,
string_sprintf( "DKIM: d=%s s=%s c=%s/%s a=%s ",
- dkim_signatures->domain,
- dkim_signatures->selector,
- (dkim_signatures->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
- (dkim_signatures->canon_body == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
- (dkim_signatures->algo == PDKIM_ALGO_RSA_SHA256)?"rsa-sha256":"rsa-sha1"
+ sig->domain,
+ sig->selector,
+ (sig->canon_headers == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
+ (sig->canon_body == PDKIM_CANON_SIMPLE)?"simple":"relaxed",
+ (sig->algo == PDKIM_ALGO_RSA_SHA256)?"rsa-sha256":"rsa-sha1"
),
- ((dkim_signatures->identity != NULL)?
- string_sprintf("i=%s ", dkim_signatures->identity)
+ ((sig->identity != NULL)?
+ string_sprintf("i=%s ", sig->identity)
:
US""
),
- ((dkim_signatures->created > 0)?
- string_sprintf("t=%lu ", dkim_signatures->created)
+ ((sig->created > 0)?
+ string_sprintf("t=%lu ", sig->created)
:
US""
),
- ((dkim_signatures->expires > 0)?
- string_sprintf("x=%lu ", dkim_signatures->expires)
+ ((sig->expires > 0)?
+ string_sprintf("x=%lu ", sig->expires)
:
US""
),
- ((dkim_signatures->bodylength > -1)?
- string_sprintf("l=%lu ", dkim_signatures->bodylength)
+ ((sig->bodylength > -1)?
+ string_sprintf("l=%lu ", sig->bodylength)
:
US""
)
);
- switch(dkim_signatures->verify_status) {
+ switch(sig->verify_status) {
case PDKIM_VERIFY_NONE:
logmsg = string_append(logmsg, &size, &ptr, 1, "[not verified]");
break;
case PDKIM_VERIFY_INVALID:
logmsg = string_append(logmsg, &size, &ptr, 1, "[invalid - ");
- switch (dkim_signatures->verify_ext_status) {
+ switch (sig->verify_ext_status) {
case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
logmsg = string_append(logmsg, &size, &ptr, 1, "public key record (currently?) unavailable]");
break;
@@ -157,7 +159,7 @@
break;
case PDKIM_VERIFY_FAIL:
logmsg = string_append(logmsg, &size, &ptr, 1, "[verification failed - ");
- switch (dkim_signatures->verify_ext_status) {
+ switch (sig->verify_ext_status) {
case PDKIM_VERIFY_FAIL_BODY:
logmsg = string_append(logmsg, &size, &ptr, 1, "body hash mismatch (body probably modified in transit)]");
break;
@@ -181,12 +183,12 @@
&dkim_signing_domains_size,
&dkim_signing_domains_ptr,
2,
- dkim_signatures->domain,
+ sig->domain,
":"
);
/* Process next signature */
- dkim_signatures = dkim_signatures->next;
+ sig = sig->next;
}
/* Chop the last colon from the domain list */
@@ -196,9 +198,161 @@
}
-void dkim_exim_verify_result(uschar *domain, uschar **result, uschar **error) {
- if (dkim_verify_ctx) {
+void dkim_exim_acl_setup(uschar *id) {
+ pdkim_signature *sig = dkim_signatures;
+ dkim_cur_sig = NULL;
+ if (dkim_disable_verify ||
+ !id || !sig ||
+ !dkim_verify_ctx) return;
+ /* Find signature to run ACL on */
+ while (sig != NULL) {
+ uschar *cmp_val = NULL;
+ if (Ustrchr(id,'@') != NULL) cmp_val = (uschar *)sig->identity;
+ else cmp_val = (uschar *)sig->domain;
+ if (cmp_val && (strcmpic(cmp_val,id) == 0)) {
+ dkim_cur_sig = sig;
+ /* The "dkim_domain" and "dkim_selector" expansion variables have
+ related globals, since they are used in the signing code too.
+ Instead of inventing separate names for verification, we set
+ them here. This is easy since a domain and selector is guaranteed
+ to be in a signature. The other dkim_* expansion items are
+ dynamically fetched from dkim_cur_sig at expansion time (see
+ function below). */
+ dkim_signing_domain = (uschar *)sig->domain;
+ dkim_signing_selector = (uschar *)sig->selector;
+ return;
+ }
+ sig = sig->next;
+ }
+}
+
+
+uschar *dkim_exim_expand_query(int what) {
+
+ if (!dkim_verify_ctx ||
+ dkim_disable_verify ||
+ !dkim_cur_sig) return dkim_exim_expand_defaults(what);
+
+ switch(what) {
+ case DKIM_ALGO:
+ return dkim_cur_sig->algo?
+ (uschar *)(dkim_cur_sig->algo)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_BODYLENGTH:
+ return (dkim_cur_sig->bodylength >= 0)?
+ (uschar *)string_sprintf(OFF_T_FMT,(LONGLONG_T)dkim_cur_sig->bodylength)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_CANON_BODY:
+ return dkim_cur_sig->canon_body?
+ (uschar *)(dkim_cur_sig->canon_body)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_CANON_HEADERS:
+ return dkim_cur_sig->canon_headers?
+ (uschar *)(dkim_cur_sig->canon_headers)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_COPIEDHEADERS:
+ return dkim_cur_sig->copiedheaders?
+ (uschar *)(dkim_cur_sig->copiedheaders)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_CREATED:
+ return (dkim_cur_sig->created > 0)?
+ (uschar *)string_sprintf("%llu",dkim_cur_sig->created)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_EXPIRES:
+ return (dkim_cur_sig->expires > 0)?
+ (uschar *)string_sprintf("%llu",dkim_cur_sig->expires)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_HEADERNAMES:
+ return dkim_cur_sig->headernames?
+ (uschar *)(dkim_cur_sig->headernames)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_IDENTITY:
+ return dkim_cur_sig->identity?
+ (uschar *)(dkim_cur_sig->identity)
+ :dkim_exim_expand_defaults(what);
+ case DKIM_KEY_GRANULARITY:
+ return dkim_cur_sig->pubkey?
+ (dkim_cur_sig->pubkey->granularity?
+ (uschar *)(dkim_cur_sig->pubkey->granularity)
+ :dkim_exim_expand_defaults(what)
+ )
+ :dkim_exim_expand_defaults(what);
+ case DKIM_KEY_SRVTYPE:
+ return dkim_cur_sig->pubkey?
+ (dkim_cur_sig->pubkey->srvtype?
+ (uschar *)(dkim_cur_sig->pubkey->srvtype)
+ :dkim_exim_expand_defaults(what)
+ )
+ :dkim_exim_expand_defaults(what);
+ case DKIM_KEY_NOTES:
+ return dkim_cur_sig->pubkey?
+ (dkim_cur_sig->pubkey->notes?
+ (uschar *)(dkim_cur_sig->pubkey->notes)
+ :dkim_exim_expand_defaults(what)
+ )
+ :dkim_exim_expand_defaults(what);
+ case DKIM_KEY_TESTING:
+ return dkim_cur_sig->pubkey?
+ (dkim_cur_sig->pubkey->testing?
+ US"1"
+ :dkim_exim_expand_defaults(what)
+ )
+ :dkim_exim_expand_defaults(what);
+ case DKIM_NOSUBDOMAINS:
+ return dkim_cur_sig->pubkey?
+ (dkim_cur_sig->pubkey->no_subdomaining?
+ US"1"
+ :dkim_exim_expand_defaults(what)
+ )
+ :dkim_exim_expand_defaults(what);
+ case DKIM_VERIFY_STATUS:
+ switch(dkim_cur_sig->verify_status) {
+ case PDKIM_VERIFY_INVALID:
+ return US"invalid";
+ case PDKIM_VERIFY_FAIL:
+ return US"fail";
+ case PDKIM_VERIFY_PASS:
+ return US"pass";
+ case PDKIM_VERIFY_NONE:
+ default:
+ return US"none";
+ }
+ case DKIM_VERIFY_REASON:
+ switch (dkim_cur_sig->verify_ext_status) {
+ case PDKIM_VERIFY_INVALID_PUBKEY_UNAVAILABLE:
+ return US"pubkey_unavailable";
+ case PDKIM_VERIFY_INVALID_PUBKEY_PARSING:
+ return US"pubkey_syntax";
+ case PDKIM_VERIFY_FAIL_BODY:
+ return US"bodyhash_mismatch";
+ case PDKIM_VERIFY_FAIL_MESSAGE:
+ return US"signature_incorrect";
+ }
+ default:
+ return US"";
+ }
+}
+
+uschar *dkim_exim_expand_defaults(int what) {
+ switch(what) {
+ case DKIM_ALGO: return US"";
+ case DKIM_BODYLENGTH: return US"9999999999999";
+ case DKIM_CANON_BODY: return US"";
+ case DKIM_CANON_HEADERS: return US"";
+ case DKIM_COPIEDHEADERS: return US"";
+ case DKIM_CREATED: return US"0";
+ case DKIM_EXPIRES: return US"9999999999999";
+ case DKIM_HEADERNAMES: return US"";
+ case DKIM_IDENTITY: return US"";
+ case DKIM_KEY_GRANULARITY: return US"*";
+ case DKIM_KEY_SRVTYPE: return US"*";
+ case DKIM_KEY_NOTES: return US"";
+ case DKIM_KEY_TESTING: return US"0";
+ case DKIM_NOSUBDOMAINS: return US"0";
+ case DKIM_VERIFY_STATUS: return US"none";
+ case DKIM_VERIFY_REASON: return US"";
+ default: return US"";
}
}
Index: dkim.h
===================================================================
RCS file: /home/cvs/exim/exim-src/src/Attic/dkim.h,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- dkim.h 20 May 2009 14:30:14 -0000 1.1.2.4
+++ dkim.h 8 Jun 2009 21:06:31 -0000 1.1.2.5
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/dkim.h,v 1.1.2.4 2009/05/20 14:30:14 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/dkim.h,v 1.1.2.5 2009/06/08 21:06:31 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -7,16 +7,27 @@
/* Copyright (c) University of Cambridge 2009 */
/* See the file NOTICE for conditions of use and distribution. */
-uschar *dkim_exim_sign(int,
- uschar *,
- uschar *,
- uschar *,
- uschar *,
- uschar *);
+uschar *dkim_exim_sign(int,uschar *,uschar *,uschar *,uschar *,uschar *);
+void dkim_exim_verify_init(void);
+void dkim_exim_verify_feed(uschar *, int);
+void dkim_exim_verify_finish(void);
+void dkim_exim_acl_setup(uschar *);
+uschar *dkim_exim_expand_query(int);
+uschar *dkim_exim_expand_defaults(int);
-void dkim_exim_verify_init(void);
-void dkim_exim_verify_feed(uschar *, int);
-void dkim_exim_verify_finish(void);
-void dkim_exim_verify_result(uschar *,
- uschar **,
- uschar **);
+#define DKIM_ALGO 1
+#define DKIM_BODYLENGTH 2
+#define DKIM_CANON_BODY 3
+#define DKIM_CANON_HEADERS 4
+#define DKIM_COPIEDHEADERS 5
+#define DKIM_CREATED 6
+#define DKIM_EXPIRES 7
+#define DKIM_HEADERNAMES 8
+#define DKIM_IDENTITY 9
+#define DKIM_KEY_GRANULARITY 10
+#define DKIM_KEY_SRVTYPE 11
+#define DKIM_KEY_NOTES 12
+#define DKIM_KEY_TESTING 13
+#define DKIM_NOSUBDOMAINS 14
+#define DKIM_VERIFY_STATUS 15
+#define DKIM_VERIFY_REASON 16
Index: expand.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/expand.c,v
retrieving revision 1.97.2.2
retrieving revision 1.97.2.3
diff -u -r1.97.2.2 -r1.97.2.3
--- expand.c 27 May 2009 17:26:54 -0000 1.97.2.2
+++ expand.c 8 Jun 2009 21:06:31 -0000 1.97.2.3
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/expand.c,v 1.97.2.2 2009/05/27 17:26:54 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/expand.c,v 1.97.2.3 2009/06/08 21:06:31 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -364,6 +364,9 @@
vtype_load_avg, /* value not used; result is int from os_getloadavg */
vtype_pspace, /* partition space; value is T/F for spool/log */
vtype_pinodes /* partition inodes; value is T/F for spool/log */
+ #ifndef DISABLE_DKIM
+ ,vtype_dkim /* Lookup of value in DKIM signature */
+ #endif
};
/* This table must be kept in alphabetical order. */
@@ -402,9 +405,25 @@
{ "demime_reason", vtype_stringptr, &demime_reason },
#endif
#ifndef DISABLE_DKIM
+ { "dkim_algo", vtype_dkim, (void *)DKIM_ALGO },
+ { "dkim_bodylength", vtype_dkim, (void *)DKIM_BODYLENGTH },
+ { "dkim_canon_body", vtype_dkim, (void *)DKIM_CANON_BODY },
+ { "dkim_canon_headers", vtype_dkim, (void *)DKIM_CANON_HEADERS },
+ { "dkim_copiedheaders", vtype_dkim, (void *)DKIM_COPIEDHEADERS },
+ { "dkim_created", vtype_dkim, (void *)DKIM_CREATED },
{ "dkim_domain", vtype_stringptr, &dkim_signing_domain },
+ { "dkim_expires", vtype_dkim, (void *)DKIM_EXPIRES },
+ { "dkim_headernames", vtype_dkim, (void *)DKIM_HEADERNAMES },
+ { "dkim_identity", vtype_dkim, (void *)DKIM_IDENTITY },
+ { "dkim_key_granularity",vtype_dkim, (void *)DKIM_KEY_GRANULARITY },
+ { "dkim_key_nosubdomains",vtype_dkim, (void *)DKIM_NOSUBDOMAINS },
+ { "dkim_key_notes", vtype_dkim, (void *)DKIM_KEY_NOTES },
+ { "dkim_key_srvtype", vtype_dkim, (void *)DKIM_KEY_SRVTYPE },
+ { "dkim_key_testing", vtype_dkim, (void *)DKIM_KEY_TESTING },
{ "dkim_selector", vtype_stringptr, &dkim_signing_selector },
{ "dkim_signing_domains",vtype_stringptr, &dkim_signing_domains },
+ { "dkim_verify_reason", vtype_dkim, (void *)DKIM_VERIFY_REASON },
+ { "dkim_verify_status", vtype_dkim, (void *)DKIM_VERIFY_STATUS},
#endif
{ "dnslist_domain", vtype_stringptr, &dnslist_domain },
{ "dnslist_matched", vtype_stringptr, &dnslist_matched },
@@ -1546,6 +1565,11 @@
}
return var_buffer;
+ #ifndef DKIM_DISABLE
+ case vtype_dkim:
+ return dkim_exim_expand_query((int)var_table[middle].value);
+ #endif
+
}
}
Index: receive.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/receive.c,v
retrieving revision 1.45.2.4
retrieving revision 1.45.2.5
diff -u -r1.45.2.4 -r1.45.2.5
--- receive.c 27 May 2009 17:26:55 -0000 1.45.2.4
+++ receive.c 8 Jun 2009 21:06:32 -0000 1.45.2.5
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/receive.c,v 1.45.2.4 2009/05/27 17:26:55 tom Exp $ */
+/* $Cambridge: exim/exim-src/src/receive.c,v 1.45.2.5 2009/06/08 21:06:32 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -2998,20 +2998,35 @@
itembuf,
sizeof(itembuf))) != NULL)
{
-
-
+ dkim_exim_acl_setup(item);
rc = acl_check(ACL_WHERE_DKIM, NULL, acl_smtp_dkim, &user_msg, &log_msg);
if (rc != OK) break;
}
-
add_acl_headers(US"DKIM");
+ if (rc == DISCARD)
+ {
+ recipients_count = 0;
+ blackholed_by = US"DKIM ACL";
+ if (log_msg != NULL)
+ blackhole_log_msg = string_sprintf(": %s", log_msg);
+ }
+ else if (rc != OK)
+ {
+ Uunlink(spool_name);
+ if (smtp_handle_acl_fail(ACL_WHERE_DKIM, rc, user_msg, log_msg) != 0)
+ smtp_yield = FALSE; /* No more messsages after dropped connection */
+ smtp_reply = US""; /* Indicate reply already sent */
+ message_id[0] = 0; /* Indicate no message accepted */
+ goto TIDYUP; /* Skip to end of function */
+ }
}
}
}
#endif /* DISABLE_DKIM */
#ifdef WITH_CONTENT_SCAN
- if (acl_smtp_mime != NULL &&
+ if (recipients_count > 0 &&
+ acl_smtp_mime != NULL &&
!run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by))
goto TIDYUP;
#endif /* WITH_CONTENT_SCAN */