/*
** 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 <sys/types.h>
#include <string.h>
#include <assert.h>
/* libsm includes */
#include <sm/gen.h>
#include <sm/types.h>
#include <sm/cdefs.h>
/* 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;
}
}
syntax highlighted by Code2HTML, v. 0.9.1