/* ** Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers. ** All rights reserved. */ #ifndef lint static char dkim_tables_c_id[] = "@(#)$Id: dkim-tables.c,v 1.32 2007/11/28 18:49:49 msk Exp $"; #endif /* !lint */ /* system includes */ #include #include #include /* libsm includes */ #include #include #include /* libdkim includes */ #include "dkim-tables.h" #include "dkim.h" /* lookup tables */ static struct chartable prv_keyparams[] = /* key parameters */ { { 'a', DKIM_KEY_ALGORITHM }, { 'g', DKIM_KEY_GRANULARITY }, { 'n', DKIM_KEY_NOTES }, { 'p', DKIM_KEY_DATA }, { 's', DKIM_KEY_SERVICE }, { 't', DKIM_KEY_FLAGS }, { 'v', DKIM_KEY_VERSION }, { '\0', -1 } }; struct chartable *keyparams = prv_keyparams; static struct nametable prv_policyflags[] = /* policy flags */ { { "y", DKIM_PFLAG_TEST }, { "s", DKIM_PFLAG_NOSUBDOMAIN }, { NULL, -1 } }; struct nametable *policyflags = prv_policyflags; static struct nametable prv_keyflags[] = /* policy flags */ { { "y", DKIM_SIGFLAG_TESTKEY }, { "s", DKIM_SIGFLAG_NOSUBDOMAIN }, { NULL, -1 } }; struct nametable *keyflags = prv_keyflags; static struct nametable prv_policyparams[] = /* policy parameters */ { { "dkim", DKIM_PPARAM_POLICY }, { "handling", DKIM_PPARAM_HANDLING }, { "r", DKIM_PPARAM_REPORTADDR }, { "t", DKIM_PPARAM_FLAGS }, { NULL, -1 } }; struct nametable *policyparams = prv_policyparams; static struct nametable prv_policies[] = /* policies */ { { "unknown", DKIM_POLICY_UNKNOWN }, { "all", DKIM_POLICY_ALL }, { "strict", DKIM_POLICY_STRICT }, { NULL, -1 } }; struct nametable *policies = prv_policies; static struct nametable prv_handlings[] = /* SSP recommended handling */ { { "process", DKIM_HANDLING_PROCESS }, { "deny", DKIM_HANDLING_DENY }, { NULL, -1 } }; struct nametable *handlings = prv_handlings; static struct nametable prv_policyresults[] = /* policy results */ { { "none", DKIM_PRESULT_NONE }, { "domain does not exist", DKIM_PRESULT_NXDOMAIN }, { "policy \"unknown\"", DKIM_PRESULT_UNKNOWN }, { "top-level domain", DKIM_PRESULT_TOPLEVEL }, { "parent domain check", DKIM_PRESULT_PARENTOK }, { "policy test flag set", DKIM_PRESULT_TESTFLAG }, { "policy \"all\" and valid signature", DKIM_PRESULT_ALLVALIDSIG }, { "valid originator signature", DKIM_PRESULT_VALIDOSIG }, { "policy check failed", DKIM_PRESULT_POLICYERROR }, { NULL, -1 } }; struct nametable *policyresults = prv_policyresults; static struct nametable prv_sigparams[] = /* signature parameters */ { { "a", DKIM_PARAM_SIGNALG }, { "b", DKIM_PARAM_SIGNATURE }, { "bh", DKIM_PARAM_BODYHASH }, { "c", DKIM_PARAM_CANONALG }, { "d", DKIM_PARAM_DOMAIN }, { "h", DKIM_PARAM_HDRLIST }, { "i", DKIM_PARAM_IDENTITY }, { "l", DKIM_PARAM_BODYLENGTH }, { "q", DKIM_PARAM_QUERYMETHOD }, { "s", DKIM_PARAM_SELECTOR }, { "t", DKIM_PARAM_TIMESTAMP }, { "v", DKIM_PARAM_VERSION }, { "x", DKIM_PARAM_EXPIRATION }, { "z", DKIM_PARAM_COPIEDHDRS }, { NULL, -1 } }; struct nametable *sigparams = prv_sigparams; static struct nametable prv_algorithms[] = /* signing algorithms */ { { "rsa-sha1", DKIM_SIGN_RSASHA1 }, #ifdef SHA256_DIGEST_LENGTH { "rsa-sha256", DKIM_SIGN_RSASHA256 }, #endif /* SHA256_DIGEST_LENGTH */ { NULL, -1 }, }; struct nametable *algorithms = prv_algorithms; static struct nametable prv_canonicalizations[] = /* canonicalizations */ { { "simple", DKIM_CANON_SIMPLE }, { "relaxed", DKIM_CANON_RELAXED }, { NULL, -1 }, }; struct nametable *canonicalizations = prv_canonicalizations; static struct nametable prv_hashes[] = /* hashes */ { { "sha1", DKIM_HASHTYPE_SHA1 }, #ifdef SHA256_DIGEST_LENGTH { "sha256", DKIM_HASHTYPE_SHA256 }, #endif /* SHA256_DIGEST_LENGTH */ { NULL, -1 }, }; struct nametable *hashes = prv_hashes; static struct nametable prv_keytypes[] = /* key types */ { { "rsa", DKIM_KEYTYPE_RSA }, { NULL, -1 }, }; struct nametable *keytypes = prv_keytypes; static struct nametable prv_querytypes[] = /* query types */ { { "dns", DKIM_QUERY_DNS }, { NULL, -1 }, }; struct nametable *querytypes = prv_querytypes; static struct nametable prv_results[] = /* result codes */ { { "Success", DKIM_STAT_OK }, { "Bad signature", DKIM_STAT_BADSIG }, { "No signature", DKIM_STAT_NOSIG }, { "No key", DKIM_STAT_NOKEY }, { "Unable to verify", DKIM_STAT_CANTVRFY }, { "Syntax error", DKIM_STAT_SYNTAX }, { "Resource unavailable", DKIM_STAT_NORESOURCE }, { "Internal error", DKIM_STAT_INTERNAL }, { "Revoked key", DKIM_STAT_REVOKED }, { "Invalid parameter", DKIM_STAT_INVALID }, { "Not implemented", DKIM_STAT_NOTIMPLEMENT }, { "Key retrieval failed", DKIM_STAT_KEYFAIL }, { "Reject requested", DKIM_STAT_CBREJECT }, { "Invalid result", DKIM_STAT_CBINVALID }, { "Try again later", DKIM_STAT_CBTRYAGAIN }, { NULL, -1 }, }; struct nametable *results = prv_results; static struct nametable prv_settypes[] = /* set types */ { { "key", DKIM_SETTYPE_KEY }, { "policy", DKIM_SETTYPE_POLICY }, { "signature", DKIM_SETTYPE_SIGNATURE }, { NULL, -1 }, }; struct nametable *settypes = prv_settypes; static struct nametable prv_sigerrors[] = /* signature parsing errors */ { { "no signature error", DKIM_SIGERROR_OK }, { "unsupported signature version", DKIM_SIGERROR_VERSION }, { "invalid domain coverage", DKIM_SIGERROR_DOMAIN }, { "signature expired", DKIM_SIGERROR_EXPIRED }, { "signature timestamp in the future", DKIM_SIGERROR_FUTURE }, { "signature timestamp order error", DKIM_SIGERROR_TIMESTAMPS }, { "canonicalization missing", DKIM_SIGERROR_MISSING_C }, { "invalid header canonicalization", DKIM_SIGERROR_INVALID_HC }, { "invalid body canonicalization", DKIM_SIGERROR_INVALID_BC }, { "signature algorithm missing", DKIM_SIGERROR_MISSING_A }, { "signature algorithm invalid", DKIM_SIGERROR_INVALID_A }, { "header list missing", DKIM_SIGERROR_MISSING_H }, { "body length value invalid", DKIM_SIGERROR_INVALID_L }, { "query method invalid", DKIM_SIGERROR_INVALID_Q }, { "query option invalid", DKIM_SIGERROR_INVALID_QO }, { "domain tag missing", DKIM_SIGERROR_MISSING_D }, { "domain tag empty", DKIM_SIGERROR_EMPTY_D }, { "selector tag missing", DKIM_SIGERROR_MISSING_S }, { "selector tag empty", DKIM_SIGERROR_EMPTY_S }, { "signature data missing", DKIM_SIGERROR_MISSING_B }, { "signature data empty", DKIM_SIGERROR_EMPTY_B }, { "signature data corrupt", DKIM_SIGERROR_CORRUPT_B }, { "key not found in DNS", DKIM_SIGERROR_NOKEY }, { "key DNS reply corrupt", DKIM_SIGERROR_DNSSYNTAX }, { "key DNS query failed", DKIM_SIGERROR_KEYFAIL }, { "body hash missing", DKIM_SIGERROR_MISSING_BH }, { "body hash empty", DKIM_SIGERROR_EMPTY_BH }, { "body hash corrupt", DKIM_SIGERROR_CORRUPT_BH }, { "signature verification failed", DKIM_SIGERROR_BADSIG }, { "unauthorized subdomain", DKIM_SIGERROR_SUBDOMAIN }, { NULL, -1 }, }; struct nametable *sigerrors = prv_sigerrors; /* ===================================================================== */ /* ** DKIM_CODE_TO_NAME -- translate a mnemonic code to its name ** ** Parameters: ** tbl -- name table ** code -- code to translate ** ** Return value: ** Pointer to the name matching the provided code, or NULL if not found. */ const char * dkim_code_to_name(struct nametable *tbl, const int code) { int c; assert(tbl != NULL); for (c = 0; ; c++) { if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL) return NULL; if (tbl[c].tbl_code == code) return tbl[c].tbl_name; } } /* ** DKIM_NAME_TO_CODE -- translate a name to a mnemonic code ** ** Parameters: ** tbl -- name table ** name -- name to translate ** ** Return value: ** A mnemonic code matching the provided name, or -1 if not found. */ const int dkim_name_to_code(struct nametable *tbl, const char *name) { int c; assert(tbl != NULL); for (c = 0; ; c++) { if (tbl[c].tbl_code == -1 && tbl[c].tbl_name == NULL) return -1; if (strcasecmp(tbl[c].tbl_name, name) == 0) return tbl[c].tbl_code; } } /* ** DKIM_CODE_TO_CHAR -- translate a mnemonic code to its matching character ** ** Parameters: ** tbl -- name table ** code -- code to translate ** ** Return value: ** Character representing the mnemonic code provided, or '\0' if ** not found. */ const int dkim_code_to_char(struct chartable *tbl, const int code) { int c; assert(tbl != NULL); for (c = 0; ; c++) { if (tbl[c].tbl_code == -1 && tbl[c].tbl_char == '\0') return '\0'; if (tbl[c].tbl_code == code) return tbl[c].tbl_char; } } /* ** DKIM_CODE_TO_CHAR -- translate a mnemonic code to its matching character ** ** Parameters: ** tbl -- name table ** chr -- character to translate ** ** Return value: ** Mnemonic representing the character code provided, or '\0' if ** not found. */ const int dkim_char_to_code(struct chartable *tbl, const int chr) { int c; assert(tbl != NULL); for (c = 0; ; c++) { if (tbl[c].tbl_code == -1 && tbl[c].tbl_char == '\0') return -1; if (tbl[c].tbl_char == chr) return tbl[c].tbl_code; } }