-/* $Cambridge: exim/src/src/dkim.c,v 1.1.2.14 2009/05/27 17:29:35 tom Exp $ */
+/* $Cambridge: exim/src/src/dkim.c,v 1.1.2.15 2009/06/08 21:06:31 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
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;
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;
/* 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;
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;
&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 */
}
-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"";
}
}
-/* $Cambridge: exim/src/src/expand.c,v 1.97.2.2 2009/05/27 17:26:54 tom Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.97.2.3 2009/06/08 21:06:31 tom Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
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. */
{ "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 },
}
return var_buffer;
+ #ifndef DKIM_DISABLE
+ case vtype_dkim:
+ return dkim_exim_expand_query((int)var_table[middle].value);
+ #endif
+
}
}