- switch(what) {
- case DKIM_ALGO:
- switch(dkim_cur_sig->algo) {
- case PDKIM_ALGO_RSA_SHA1:
- return US"rsa-sha1";
- case PDKIM_ALGO_RSA_SHA256:
- default:
- return US"rsa-sha256";
- }
- 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:
- switch(dkim_cur_sig->canon_body) {
- case PDKIM_CANON_RELAXED:
- return US"relaxed";
- case PDKIM_CANON_SIMPLE:
- default:
- return US"simple";
- }
- case DKIM_CANON_HEADERS:
- switch(dkim_cur_sig->canon_headers) {
- case PDKIM_CANON_RELAXED:
- return US"relaxed";
- case PDKIM_CANON_SIMPLE:
- default:
- return US"simple";
- }
- 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"";
- }
+
+
+/* For the given identity, run the DKIM ACL once for each matching signature.
+
+Arguments
+ id Identity to look for in dkim signatures
+ res_ptr ptr to growable string-list of status results,
+ appended to per ACL run
+ user_msgptr where to put a user error (for SMTP response)
+ log_msgptr where to put a logging message (not for SMTP response)
+
+Returns: OK access is granted by an ACCEPT verb
+ DISCARD access is granted by a DISCARD verb
+ FAIL access is denied
+ FAIL_DROP access is denied; drop the connection
+ DEFER can't tell at the moment
+ ERROR disaster
+*/
+
+int
+dkim_exim_acl_run(uschar * id, gstring ** res_ptr,
+ uschar ** user_msgptr, uschar ** log_msgptr)
+{
+pdkim_signature * sig;
+uschar * cmp_val;
+int rc = -1;
+
+dkim_verify_status = US"none";
+dkim_verify_reason = US"";
+dkim_cur_signer = id;
+
+if (dkim_disable_verify || !id || !dkim_verify_ctx)
+ return OK;
+
+/* Find signatures to run ACL on */
+
+for (sig = dkim_signatures; sig; sig = sig->next)
+ if ( (cmp_val = Ustrchr(id, '@') != NULL ? US sig->identity : US sig->domain)
+ && strcmpic(cmp_val, id) == 0
+ )
+ {
+ /* 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_cur_sig = sig;
+ dkim_signing_domain = US sig->domain;
+ dkim_signing_selector = US sig->selector;
+ dkim_key_length = sig->sighash.len * 8;
+
+ /* These two return static strings, so we can compare the addr
+ later to see if the ACL overwrote them. Check that when logging */
+
+ dkim_verify_status = dkim_exim_expand_query(DKIM_VERIFY_STATUS);
+ dkim_verify_reason = dkim_exim_expand_query(DKIM_VERIFY_REASON);
+
+ if ((rc = dkim_acl_call(id, res_ptr, user_msgptr, log_msgptr)) != OK)
+ return rc;
+ }
+
+if (rc != -1)
+ return rc;
+
+/* No matching sig found. Call ACL once anyway. */
+
+dkim_cur_sig = NULL;
+return dkim_acl_call(id, res_ptr, user_msgptr, log_msgptr);