/*
 * Note: this file originally auto-generated by mib2c using
 *  $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <net-snmp/library/cert_util.h>
#include "tlstm-mib.h"
#include "snmpTlstmCertToTSNTable.h"

netsnmp_feature_require(table_tdata)
netsnmp_feature_require(cert_fingerprints)
netsnmp_feature_require(table_tdata_delete_table)
netsnmp_feature_require(table_tdata_extract_table)
netsnmp_feature_require(table_tdata_remove_row)
netsnmp_feature_require(tls_fingerprint_build)
#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(check_vb_storagetype)
netsnmp_feature_require(check_vb_type_and_max_size)
netsnmp_feature_require(check_vb_rowstatus_with_storagetype)
netsnmp_feature_require(table_tdata_insert_row)
#endif /* NETSNMP_NO_WRITE_SUPPORT */

/** XXX - move these to table_data header? */
#define FATE_NEWLY_CREATED    1
#define FATE_NO_CHANGE        0
#define FATE_DELETE_ME        -1

#define MAP_MIB_CONFIG_TOKEN "snmpTlstmCertToTSNEntry"

extern netsnmp_cert_map *netsnmp_certToTSN_parse_common(char **line);


    /*
     * structure for undo storage and other vars for set processing 
     */
typedef struct certToTSN_undo_s {
    char            fate;
    char            copied;
    char            is_consistent;
    netsnmp_request_info *req[SNMPTLSTMCERTTOTSN_TABLE_MAX_COL+1];

    /*
     * undo Column space 
     */
    char            fingerprint[SNMPTLSTMCERTTOTSN_FINGERPRINT_MAX_SIZE];
    size_t          fingerprint_len;
    int             mapType;
    char            data[SNMPTLSTMCERTTOTSN_DATA_MAX_SIZE];
    size_t          data_len;
    u_char          hashType;
    char            storageType;
    char            rowStatus;
} certToTSN_undo;

    /*
     * Typical data structure for a row entry 
     */
typedef struct certToTSN_entry_s {
    /*
     * Index values 
     */
    u_long          tlstmCertToTSNID;

    /*
     * Column values 
     */
    char            fingerprint[SNMPTLSTMCERTTOTSN_FINGERPRINT_MAX_SIZE];
    size_t          fingerprint_len;
    int             mapType;
    char            data[SNMPTLSTMCERTTOTSN_DATA_MAX_SIZE];
    size_t          data_len;
    char            storageType;
    char            rowStatus;
    u_char          hashType;
    char            map_flags;

    /*
     * used during set processing 
     */
    certToTSN_undo *undo;
} certToTSN_entry;

static Netsnmp_Node_Handler tlstmCertToTSNTable_handler;
static oid _oid2type(oid *val, int val_len);
/** static int _type2oid(int type, oid *val, int *val_len); */
static int _cache_load(netsnmp_cache *cache, netsnmp_tdata *table);
static void _cache_free(netsnmp_cache *cache, netsnmp_tdata *table);
static void _cert_map_add(certToTSN_entry *entry);
static void _cert_map_remove(certToTSN_entry *entry);
static int _count_handler(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *reqinfo,
                          netsnmp_request_info *requests);
static void _parse_mib_maps(const char *token, char *line);
static int _save_maps(int majorID, int minorID, void *server, void *client);
static int _save_map(netsnmp_cert_map *map, int row_status, void *type);
static void _cert_map_tweak_storage(certToTSN_entry *entry);

static netsnmp_tdata *_table = NULL;
static uint32_t _last_changed = 0;


/** Initializes the tlstmCertToTSNTable module */
void
init_snmpTlstmCertToTSNTable(void)
{
    init_snmpTlstmCertToTSNTable_context(NULL);
}

void
init_snmpTlstmCertToTSNTable_context(const char *contextName)
{
    oid             reg_oid[]   =  { SNMP_TLS_TM_CERT_TABLE };
    const size_t    reg_oid_len =  OID_LENGTH(reg_oid);
    netsnmp_handler_registration    *reg;
    netsnmp_table_registration_info *info;
    netsnmp_cache                   *cache;
    netsnmp_watcher_info            *watcher;
    const char *mib_map_help = 
        MAP_MIB_CONFIG_TOKEN " table persistence (internal use)";

    DEBUGMSGTL(("tlstmCertToSN:init",
                "initializing table tlstmCertToTSNTable\n"));

    reg = netsnmp_create_handler_registration
        ("tlstmCertToTSNTable", tlstmCertToTSNTable_handler,
         reg_oid, reg_oid_len,
         HANDLER_CAN_RWRITE);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for tlstmCertToSN\n");
        return;
    }

    if (NULL != contextName)
        reg->contextName = strdup(contextName);

    _table = netsnmp_tdata_create_table("tlstmCertToTSNTable", 0);
    if (NULL == _table) {
        snmp_log(LOG_ERR,
                 "error creating tdata table for tlstmCertToTSNTable\n");
        return;
    }
    info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == info) {
        snmp_log(LOG_ERR,
                 "error creating table info for tlstmCertToTSNTable\n");
        netsnmp_tdata_delete_table(_table);
        _table = NULL;
        return;
    }
    netsnmp_table_helper_add_indexes(info, 
                                     /* index: tlstmCertToTSNID */
                                     ASN_UNSIGNED,  0);

    info->min_column = SNMPTLSTMCERTTOTSN_TABLE_MIN_COL;
    info->max_column = SNMPTLSTMCERTTOTSN_TABLE_MAX_COL;

    /*
     * cache init
     */
    cache = netsnmp_cache_create(30, (NetsnmpCacheLoad*)_cache_load,
                                 (NetsnmpCacheFree*)_cache_free,
                                 reg_oid,
                                 reg_oid_len);
    if (NULL == cache) {
        snmp_log(LOG_ERR,"error creating cache for tlstmCertToTSNTable\n");
        netsnmp_tdata_delete_table(_table);
        _table = NULL;
        return;
    }
    cache->magic = (void *)_table;
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    netsnmp_tdata_register(reg, _table, info);

    if (cache) 
        netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get(cache),
                                       "table_container");

    /*
     * register scalars
     */
    reg_oid[10] = 1;
    reg = netsnmp_create_handler_registration("snmpTlstmCertToTSNCount",
                                              _count_handler, reg_oid,
                                              OID_LENGTH(reg_oid),
                                              HANDLER_CAN_RONLY);
    if (NULL == reg)
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmCertToTSNCount\n");
    else {
        if (NULL != contextName)
            reg->contextName = strdup(contextName);

        netsnmp_register_scalar(reg);
        if (cache) 
            netsnmp_inject_handler_before(reg, netsnmp_cache_handler_get(cache),
                                          "table_container");
    }
    
    reg_oid[10] = 2;
    reg = netsnmp_create_handler_registration(
        "snmpTlstmCertToTSNTableLastChanged", NULL, reg_oid,
        OID_LENGTH(reg_oid), HANDLER_CAN_RONLY);
    watcher = netsnmp_create_watcher_info((void*)&_last_changed,
                                          sizeof(_last_changed),
                                          ASN_TIMETICKS,
                                          WATCHER_FIXED_SIZE);
    if ((NULL == reg) || (NULL == watcher))
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmCertToTSNCount\n");
    else {
        if (NULL != contextName)
            reg->contextName = strdup(contextName);
        netsnmp_register_watched_scalar2(reg, watcher);
    }

    /*
     * persistence
     */
    register_config_handler(NULL, MAP_MIB_CONFIG_TOKEN, _parse_mib_maps, NULL,
                            mib_map_help);
    if (snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                               _save_maps, NULL) != SNMP_ERR_NOERROR)
        snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
                 "for certToTSN\n");

}

/*
 * create a new row in the table 
 */
netsnmp_tdata_row *
tlstmCertToTSNTable_createEntry(netsnmp_tdata * table, u_long tlstmCertToTSNID)
{
    certToTSN_entry *entry;
    netsnmp_tdata_row *row;

    entry = SNMP_MALLOC_TYPEDEF(certToTSN_entry);
    if (!entry)
        return NULL;

    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;

    DEBUGMSGT(("tlstmCertToSN:entry:create", "entry %p / row %p\n",
               entry, row));
    /*
     * populate index
     */
    entry->tlstmCertToTSNID = tlstmCertToTSNID;
    netsnmp_tdata_row_add_index(row, ASN_UNSIGNED,
                                &(entry->tlstmCertToTSNID),
                                sizeof(entry->tlstmCertToTSNID));
   /*
    * assign default column values
    */
    entry->mapType = TSNM_tlstmCertSpecified;
    entry->storageType = ST_NONVOLATILE;
    entry->rowStatus = RS_NOTREADY;

    if (table) {
        DEBUGMSGTL(("tlstmCertToTSN:row:insert", "row %p\n", row));
        netsnmp_tdata_add_row(table, row);
    }
    return row;
}

/*
 * allocate undo resources 
 */
static certToTSN_undo *
_allocUndo(certToTSN_entry * entry)
{
    if (!entry)
        return NULL;

    netsnmp_assert(!entry->undo);

    entry->undo = SNMP_MALLOC_TYPEDEF(certToTSN_undo);
    if (!entry->undo)
        return NULL;

    entry->undo->is_consistent = -1;   /* don't know */

    return entry->undo;
}

/*
 * free undo resources 
 */
static void
_freeUndo(certToTSN_entry * entry)
{
    if (!entry || !entry->undo)
        return;

    /*
     * TODO: release any allocated resources 
     */
    SNMP_FREE(entry->undo);
}

/*
 * remove a row from the table 
 */
void
tlstmCertToTSNTable_removeEntry(netsnmp_tdata * table,
                                netsnmp_tdata_row * row)
{
    certToTSN_entry *entry;

    if (!row)
        return;                 /* Nothing to remove */

    entry = (certToTSN_entry *) row->data;

    DEBUGMSGT(("tlstmCertToSN:entry:delete", "entry %p / row %p\n",
               entry, row));

    if (entry && entry->undo)
        _freeUndo(entry);
    SNMP_FREE(entry);

    if (table) {
        DEBUGMSGTL(("tlstmCertToSN:row:remove", "row %p\n", row));
        netsnmp_tdata_remove_and_delete_row(table, row);
    }
    else
        netsnmp_tdata_delete_row(row);
}


/** handles requests for the tlstmCertToTSNTable table */
static int
tlstmCertToTSNTable_handler(netsnmp_mib_handler *handler,
                            netsnmp_handler_registration *reginfo,
                            netsnmp_agent_request_info *reqinfo,
                            netsnmp_request_info *requests)
{
    oid tsnm[] = { SNMP_TLS_TM_BASE, 1, 1, 0 };
    static const int tsnm_pos = OID_LENGTH(tsnm) - 1;
    netsnmp_request_info *request = NULL;
    netsnmp_table_request_info *info;
    netsnmp_tdata  *table;
    netsnmp_tdata_row *row;
    certToTSN_entry *entry;
    int             ret = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("tlstmCertToSN:handler", "Processing request (mode %s (%d))\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode),
                reqinfo->mode));

    switch (reqinfo->mode) {
    /** ######################################################### GET #####
     *
     *   Read-support (also covers GetNext requests)
     */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);
            netsnmp_assert(entry && info);

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            {
                /*
                 * build SnmpTLSFingerprint
                 */
                u_char bin[42], *ptr = bin;
                size_t len = sizeof(bin);
                int    rc;
                rc = netsnmp_tls_fingerprint_build(entry->hashType,
                                                   entry->fingerprint,
                                                   &ptr, &len, 0);
                if (SNMPERR_SUCCESS != rc)
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_GENERR);
                else
                    snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                             bin, len);
            }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                tsnm[tsnm_pos] = entry->mapType;
                snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID,
                                         tsnm, sizeof(tsnm));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         entry->data, entry->data_len);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->storageType);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           entry->rowStatus);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                break;
            }                   /* switch colnum */
        }                       /* for requests */
        break;                  /* case MODE_GET */

        /*
         * Write-support
         */
    /** #################################################### RESERVE1 #####
     *
     *   In RESERVE1 we are just checking basic ASN.1 size/type restrictions.
     * You probably don't need to change any of this code. Don't change any
     * of the column values here. Save that for the ACTION phase.
     *
     *   The next phase is RESERVE2 or FREE.
     */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            netsnmp_assert(request->processed == 0);

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            if ((NULL != entry) && (ST_READONLY == entry->storageType)) {
                ret = SNMP_ERR_NOTWRITABLE;
                break;
            }

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(entry->fingerprint));
                /** check len/algorithm MIB requirements */
                if (ret == SNMP_ERR_NOERROR)
                    ret = netsnmp_cert_check_vb_fingerprint(request->requestvb);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OBJECT_ID,
                     SNMPTLSTMCERTTOTSN_MAPTYPE_MAX_SIZE);
                if (ret == SNMP_ERR_NOERROR) {
                    if (_oid2type(request->requestvb->val.objid,
                                  request->requestvb->val_len) >
                        TSNM_tlstmCert_MAX)
                        ret = SNMP_ERR_WRONGVALUE;
                }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR, sizeof(entry->data));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                ret = netsnmp_check_vb_storagetype
                    (request->requestvb,(entry ? entry->storageType : ST_NONE));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                ret = netsnmp_check_vb_rowstatus_with_storagetype
                    (request->requestvb,
                     (entry ? entry->rowStatus :RS_NONEXISTENT),
                     (entry ? entry->storageType :ST_NONE));
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            default:
                ret = SNMP_ERR_NOTWRITABLE;
            }                   /* switch colnum */

            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */
        break;                  /* case MODE_SET_RESERVE1 */

    /** #################################################### RESERVE2 #####
     *
     *   RESERVE2 is for checking additional restrictions from the MIB.
     * Since these restrictions are often in the description of the object,
     * mib2c can't generate code. It's possible that you need to add
     * additional checks here. However, don't change any of the column
     * values here. Save that for the ACTION phase.
     *
     *   The next phase is ACTION or FREE.
     */
    case MODE_SET_RESERVE2:
        for (request = requests; request; request = request->next) {
            netsnmp_assert(request->processed == 0);

            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            table = netsnmp_tdata_extract_table(request);
            info = netsnmp_extract_table_info(request);
            /*
             * if no row, create one
             */
            if (!entry) {
                row = tlstmCertToTSNTable_createEntry
                    (table,*info->indexes->val.integer);
                if (!row) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                entry = row->data;
                _allocUndo(entry);
                if (!entry->undo) {
                    tlstmCertToTSNTable_removeEntry(table, row);
                    row = NULL;
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                entry->undo->fate = FATE_NEWLY_CREATED;
                /** associate row with requests */
                netsnmp_insert_tdata_row(request, row);
            }

            /** allocate undo structure, if needed */
            if (!entry->undo) {
                _allocUndo(entry);
                if (!entry->undo) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
            }

            /*
             * save request ptr for column. if we already
             * have a value, bail.
             */
            if (entry->undo->req[info->colnum]) {
                DEBUGMSGT(("tlstmCertToSN:reserve2",
                           "multiple sets to col %d in request\n",
                           info->colnum));
                if (FATE_NEWLY_CREATED == entry->undo->fate)
                    ret = SNMP_ERR_INCONSISTENTNAME;
                else
                    ret = SNMP_ERR_INCONSISTENTVALUE;
                break;
            }
            entry->undo->req[info->colnum] = request;
            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* for requests */

        if (ret == SNMP_ERR_NOERROR) {
            /** make sure rowstatus is used to create rows */
            for (request = requests; request; request = request->next) {
                if (request->processed)
                    continue;

                entry = (certToTSN_entry *)
                    netsnmp_tdata_extract_entry(request);
                if ((entry->undo->fate != FATE_NEWLY_CREATED) ||
                    (entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]))
                    continue;
                ret = SNMP_ERR_INCONSISTENTNAME;
                break;
            } /* creation for requests */
        } /* no error */
        break;                  /* case MODE_SET_RESERVE2 */

    /** ######################################################## FREE #####
     *
     *   FREE is for cleaning up after a failed request (during either
     * RESERVE1 or RESERVE2). So any allocated resources need to be
     * released.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_FREE:
        /*
         * release undo resources
         * remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table = netsnmp_tdata_extract_table(request);
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if (!entry || !entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, row);

            if (FATE_NEWLY_CREATED == entry->undo->fate)
                tlstmCertToTSNTable_removeEntry(table, row);
            else
                _freeUndo(entry);
        }
        break;                  /* case MODE_SET_FREE */

    /** ###################################################### ACTION #####
     *
     *   In the ACTION phase, we perform any sets that can be undone.
     * (Save anything that can't be undone for the COMMIT phase.)
     *
     *   After individual columns have been done, you should check that the
     * row as a whole is consistent.
     *
     * The next phase is UNDO or COMMIT.
     */
    case MODE_SET_ACTION:
        for (request = requests; request; request = request->next) {
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            /** reserve2 should enforce this */
            netsnmp_assert(request == entry->undo->req[info->colnum]);

            /*
             * for each col, save old value and the set new value
             */
            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            {
                u_char *tmp = (u_char*)entry->fingerprint;
                u_int size = sizeof(entry->fingerprint);
                netsnmp_variable_list *vb = request->requestvb;

                memcpy(entry->undo->fingerprint,
                       entry->fingerprint, sizeof(entry->fingerprint));
                entry->undo->fingerprint_len = entry->fingerprint_len;
                entry->undo->hashType = entry->hashType;
                memset(entry->fingerprint, 0, sizeof(entry->fingerprint));

                (void)netsnmp_tls_fingerprint_parse(vb->val.string, vb->val_len,
                                                    (char**)&tmp, &size, 0,
                                                    &entry->hashType);
                entry->fingerprint_len = size;
                if (0 == entry->fingerprint_len)
                    ret = SNMP_ERR_GENERR;
            }
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                entry->undo->mapType = entry->mapType;
                entry->mapType = _oid2type(request->requestvb->val.objid,
                                           request->requestvb->val_len);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                memcpy(entry->undo->data, entry->data, sizeof(entry->data));
                entry->undo->data_len = entry->data_len;
                memset(entry->data, 0, sizeof(entry->data));
                memcpy(entry->data, request->requestvb->val.string,
                       request->requestvb->val_len);
                entry->data_len = request->requestvb->val_len;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                entry->undo->storageType = entry->storageType;
                entry->storageType = *request->requestvb->val.integer;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                entry->undo->rowStatus = entry->rowStatus;
                entry->rowStatus = *request->requestvb->val.integer;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            }                   /* switch colnum */
        }                       /* set values for requests */

        if (ret != SNMP_ERR_NOERROR) 
            break; /* skip consistency if we've already got error */

        /*
         * All columns now have their final values set. check the
         * internal consistency of each row.
         */
        for (request = requests; request; request = request->next) {
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            if (entry->undo->is_consistent != -1)
                continue;       /* already checked */

            /** assume consistency */
            entry->undo->is_consistent = 1;

            /*
             * per mib, can't have empty fingerprint and must
             * have data if indicated by map type.
             */
            if (0 == entry->fingerprint_len) {
                DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                            "fingerprint must not be empty\n"));
                entry->undo->is_consistent = 0;
            }
            else if ((TSNM_tlstmCertSpecified == entry->mapType) &&
                     (0 == entry->data_len)) {
                DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                            "must specify Data for CertSpecified identity\n"));
                entry->undo->is_consistent = 0;
            }

            if ((RS_IS_ACTIVE(entry->rowStatus)) &&
                ((!entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) ||
                 (RS_IS_ACTIVE(entry->undo->rowStatus)))) {
                /*
                 * per mib, can't modify these while row active
                 */
                char _cols[3] = { COL_SNMPTLSTMCERTTOTSN_FINGERPRINT,
                                  COL_SNMPTLSTMCERTTOTSN_MAPTYPE, COL_SNMPTLSTMCERTTOTSN_DATA };
                int i;
                for (i=0; i < 3; ++i ) {
                    if (!entry->undo->req[i])
                        continue;
                    DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                                "can't modify row %d while active\n",
                                _cols[i]));
                    entry->undo->is_consistent = 0;
                    ret = SNMP_ERR_NOTWRITABLE;
                    request= entry->undo->req[i];
                    break;
                }
            } else if (RS_IS_GOING_ACTIVE(entry->rowStatus)) {
                /*
                 * if going active, inconsistency is fatal
                 */
                if (!entry->undo->is_consistent) {
                    netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]);
                    if (FATE_NEWLY_CREATED == entry->undo->fate)
                        ret = SNMP_ERR_INCONSISTENTNAME;
                    else
                        ret = SNMP_ERR_INCONSISTENTVALUE;
                    request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS];
                }
            } else if (RS_DESTROY == entry->rowStatus) {
                /*
                 * can't destroy active row
                 */
                if (RS_IS_ACTIVE(entry->undo->rowStatus)) {
                    DEBUGMSGTL(("tlstmCertToTSNTable:inconsistent",
                                "can't destroy active row\n"));
                    netsnmp_assert(entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]);
                    ret = SNMP_ERR_INCONSISTENTVALUE;
                    request = entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS];
                }
            }
            if (ret != SNMP_ERR_NOERROR)
                break;
        }                       /* consistency for requests */
        break;                  /* case MODE_SET_ACTION */

    /** ######################################################## UNDO #####
     *
     *   UNDO is for cleaning up any failed requests that went through the
     * ACTION phase.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_UNDO:
        for (request = requests; request; request = request->next) {
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);
            info = netsnmp_extract_table_info(request);

            /*
             * skip newly created rows, as we're going to delete
             * them below anyways
             */
            if (FATE_NEWLY_CREATED == entry->undo->fate)
                continue;

            /*
             * restore values
             */
            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
                memcpy(entry->fingerprint, entry->undo->fingerprint,
                       sizeof(entry->fingerprint));
                entry->fingerprint_len = entry->undo->fingerprint_len;
                entry->hashType = entry->undo->hashType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT */
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
                entry->mapType = entry->undo->mapType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_MAPTYPE */
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                memcpy(entry->data, entry->undo->data, sizeof(entry->data));
                entry->data_len = entry->undo->data_len;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_DATA */
            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                entry->storageType = entry->undo->storageType;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                entry->rowStatus = entry->undo->rowStatus;
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */
            }                   /* switch colnum */
        }                       /* for requests */

        /*
         * release undo data
         * or remove any newly created rows
         */
        for (request = requests; request; request = request->next) {
            table = netsnmp_tdata_extract_table(request);
            row = netsnmp_tdata_extract_row(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if (!entry || !entry->undo)
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row(request, row);

            if (FATE_NEWLY_CREATED == entry->undo->fate)
                tlstmCertToTSNTable_removeEntry(table, row);
            else
                _freeUndo(entry);
        }                       /* for requests */
        break;                  /* case MODE_SET_UNDO */

    /** ###################################################### COMMIT #####
     *
     *   COMMIT is the final success state, when all changes are finalized.
     * There is not recovery state should something faile here.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_COMMIT:
        for (request = requests; request; request = request->next) {
            row = netsnmp_tdata_extract_row(request);
            table = netsnmp_tdata_extract_table(request);
            info = netsnmp_extract_table_info(request);
            entry = (certToTSN_entry *) netsnmp_tdata_extract_entry(request);

            if ((RS_NOTREADY == entry->rowStatus) && entry->undo->is_consistent)
                entry->rowStatus = RS_NOTINSERVICE;
            else if ((RS_NOTINSERVICE == entry->rowStatus) &&
                     (0 == entry->undo->is_consistent))
                entry->rowStatus = RS_NOTREADY;

            /** release undo data for requests with no rowstatus */
            if (entry->undo && !entry->undo->req[COL_SNMPTLSTMCERTTOTSN_ROWSTATUS]) {
                _freeUndo(entry);
                if ((0 == entry->map_flags) && (entry->rowStatus == RS_ACTIVE))
                    _cert_map_add(entry);
                else if ((0 != entry->map_flags) &&
                         (entry->rowStatus == RS_DESTROY))
                    _cert_map_remove(entry);
            }

            switch (info->colnum) {
            case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS:
                switch (entry->rowStatus) {
                case RS_CREATEANDGO:
                    /** Fall-through */
                case RS_ACTIVE:
                    netsnmp_assert(entry->undo->is_consistent);
                    entry->rowStatus = RS_ACTIVE;
                    if (0 == entry->map_flags)
                        _cert_map_add(entry);
                    break;

                case RS_CREATEANDWAIT:
                    /** Fall-through */
                case RS_NOTINSERVICE:
                    /** simply set status based on consistency */
                    if (entry->undo->is_consistent)
                        entry->rowStatus = RS_NOTINSERVICE;
                    else
                        entry->rowStatus = RS_NOTREADY;
                    if (0 != entry->map_flags)
                        _cert_map_remove(entry);
                    break;

                case RS_DESTROY:
                    /** remove from cert map */
                    if (0 != entry->map_flags)
                        _cert_map_remove(entry);
                    /** disassociate row with requests */
                    netsnmp_remove_tdata_row(request, row);
                    tlstmCertToTSNTable_removeEntry(table, row);
                    row = NULL;
                    entry = NULL;
                }
                /** release undo data */
                _freeUndo(entry);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_ROWSTATUS */

            case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE:
                if (RS_ACTIVE == entry->rowStatus)
                    _cert_map_tweak_storage(entry);
                break;          /* case COL_SNMPTLSTMCERTTOTSN_STORAGETYPE */

            case COL_SNMPTLSTMCERTTOTSN_FINGERPRINT:
            case COL_SNMPTLSTMCERTTOTSN_MAPTYPE:
            case COL_SNMPTLSTMCERTTOTSN_DATA:
                break;
            }                   /* switch colnum */

        }                       /* for requests */

        /** update last changed */
        _last_changed = netsnmp_get_agent_uptime();

        /** set up to save persistent store */
        snmp_store_needed(NULL);

        break;                  /* case MODE_SET_COMMIT */
    }                           /* switch (reqinfo->mode) */

    if (ret != SNMP_ERR_NOERROR)
        netsnmp_set_request_error(reqinfo, request, ret);

    return SNMP_ERR_NOERROR;
}

static int
_count_handler(netsnmp_mib_handler *handler,
               netsnmp_handler_registration *reginfo,
               netsnmp_agent_request_info *reqinfo,
               netsnmp_request_info *requests)
{
    int                val;

    if (MODE_GET != reqinfo->mode) {
        snmp_log(LOG_ERR, "bad mode in RO handler");
        return SNMP_ERR_GENERR;
    }

    if (NULL == _table->container)
        val = 0;
    else
        val = CONTAINER_SIZE(_table->container);

    snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
                             (u_char *) &val, sizeof(val));
   
    if (handler->next && handler->next->access_method)
        return netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
    
    return SNMP_ERR_NOERROR;
}

static void
_cert_map_add(certToTSN_entry *entry)
{
    netsnmp_cert_map *map;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmCertToTSNTable:map:add", "pri %ld, fp %s\n",
                entry->tlstmCertToTSNID, entry->fingerprint));

    map = netsnmp_cert_map_alloc(entry->fingerprint, NULL);
    if (NULL == map)
        return;

    map->priority = entry->tlstmCertToTSNID;
    map->mapType = entry->mapType;
    if (entry->data)
        map->data = strdup(entry->data);
    map->hashType = entry->hashType;

    map->flags = NSCM_FROM_MIB;
    if (entry->storageType == ST_NONVOLATILE)
        map->flags |= NSCM_NONVOLATILE;

    if (netsnmp_cert_map_add(map) != 0)
        netsnmp_cert_map_free(map);
}

static void
_cert_map_tweak_storage(certToTSN_entry *entry)
{
    netsnmp_container *maps;
    netsnmp_cert_map *map, index;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmCertToTSNTable:map:tweak", "pri %ld, st %d\n",
                entry->tlstmCertToTSNID, entry->storageType));

    /** get current active maps */
    maps = netsnmp_cert_map_container();
    if (NULL == maps)
        return;

    index.priority = entry->tlstmCertToTSNID;
    map = CONTAINER_FIND(maps, &index);
    if (NULL == map) {
        DEBUGMSGTL(("tlstmCertToTSNTable:map:tweak", "couldn't find map!\n"));
        return;
    }

    if (entry->storageType == ST_NONVOLATILE)
        map->flags |= NSCM_NONVOLATILE;
    else
        map->flags &= ~NSCM_NONVOLATILE;
}

static void
_cert_map_remove(certToTSN_entry *entry)
{
    netsnmp_container *maps;
    netsnmp_cert_map map;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmCertToTSNTable:map:remove", "pri %ld, fp %s\n",
                entry->tlstmCertToTSNID, entry->fingerprint));

    /** get current active maps */
    maps = netsnmp_cert_map_container();
    if (NULL == maps)
        return;

    map.priority = entry->tlstmCertToTSNID;
    map.fingerprint = entry->fingerprint;

    if (CONTAINER_REMOVE(maps, &map) != 0) {
        snmp_log(LOG_ERR, "could not remove certificate map");
    }
    entry->map_flags = 0;
}

static netsnmp_tdata_row *
_entry_from_map(netsnmp_cert_map  *map)
{
    netsnmp_tdata_row *row;
    certToTSN_entry   *entry;

    row = tlstmCertToTSNTable_createEntry(NULL, map->priority);
    if (NULL == row) {
        snmp_log(LOG_ERR, "can create tlstmCertToTSN row entry\n");
        return NULL;
    }
    entry = row->data;

    if (map->flags & NSCM_FROM_CONFIG)
        entry->storageType = ST_PERMANENT;
    else if (! (map->flags & NSCM_NONVOLATILE))
        entry->storageType = ST_VOLATILE;
    entry->map_flags = map->flags;

    entry->fingerprint_len = strlen(map->fingerprint);
    if (entry->fingerprint_len > sizeof(entry->fingerprint))
        entry->fingerprint_len = sizeof(entry->fingerprint) - 1;
    memcpy(entry->fingerprint, map->fingerprint, entry->fingerprint_len);
    entry->fingerprint[sizeof(entry->fingerprint) - 1] = 0;
    entry->hashType = map->hashType;
    
    if (map->data) {
        entry->data_len = strlen(map->data);
        if (entry->data_len) {
            if (entry->data_len > sizeof(entry->data))
                entry->data_len = sizeof(entry->data) - 1;
            memcpy(entry->data, map->data, entry->data_len);
            entry->data[sizeof(entry->data) - 1] = 0;
        }
    }
    entry->mapType = map->mapType;

    return row;
}

static int
_cache_load(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_container *maps;
    netsnmp_iterator  *map_itr;
    netsnmp_cert_map  *map;
    netsnmp_tdata_row *row;
    certToTSN_entry   *entry;
    int                rc = 0;

    DEBUGMSGTL(("tlstmCertToTSNTable:cache:load", "called, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    /** get current active maps */
    maps = netsnmp_cert_map_container();
    if (NULL == maps)
        return 0;
    DEBUGMSGTL(("tlstmCertToTSNTable:cache:load", "maps %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(maps)));

    map_itr = CONTAINER_ITERATOR(maps);
    if (NULL == map_itr) {
        DEBUGMSGTL(("tlstmCertToTSNTable:cache:load",
                    "cant get map iterator\n"));
        return -1;
    }

    /*
     * insert rows for active maps into tbl container
     */
    map = ITERATOR_FIRST(map_itr);
    for( ; map; map = ITERATOR_NEXT(map_itr)) {

        row = _entry_from_map(map);
        if (NULL == row) {
            rc =-1;
            break;
        }
        entry = (certToTSN_entry*)row->data;
        entry->rowStatus = RS_ACTIVE;

        if (netsnmp_tdata_add_row(table, row) != SNMPERR_SUCCESS) {
            tlstmCertToTSNTable_removeEntry(NULL, row);
            rc = -1;
            break;
        }
    }
    ITERATOR_RELEASE(map_itr);

    DEBUGMSGTL(("tlstmCertToTSNTable:cache:load", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    return rc;
}

static void
_cache_free(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_tdata_row *row;
    netsnmp_iterator   *tbl_itr;
    certToTSN_entry   *entry;

    DEBUGMSGTL(("tlstmCertToTSNTable:cache:free", "called, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    /** insert rows for active maps into tbl container */
    tbl_itr = CONTAINER_ITERATOR(table->container);
    if (NULL == tbl_itr) {
        DEBUGMSGTL(("tlstmCertToTSNTable:cache:free",
                    "cant get map iterator\n"));
        return;
    }

    row = ITERATOR_FIRST(tbl_itr);
    for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
        entry = row->data;

        /*
         * remove all active rows (they are in the maps container kept
         * by the library). Keep inactive ones for next time.
         */
        if (entry->rowStatus == RS_ACTIVE) {
            tlstmCertToTSNTable_removeEntry(NULL, row);
            ITERATOR_REMOVE(tbl_itr);
            continue;
        }
    }
    ITERATOR_RELEASE(tbl_itr);

    DEBUGMSGTL(("tlstmCertToTSNTable:cache:free", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));
}

static void
_parse_mib_maps(const char *token, char *line)
{
    netsnmp_tdata_row *row;
    certToTSN_entry   *entry;
    netsnmp_cert_map *map = netsnmp_certToTSN_parse_common(&line);

    if (NULL == line) {
        netsnmp_config_error("incomplete line");
        netsnmp_cert_map_free(map);
        return;
    }

    map->flags = NSCM_FROM_MIB | NSCM_NONVOLATILE;
    row = _entry_from_map(map);
    if (NULL == row) {
        netsnmp_cert_map_free(map);
        return;
    }
    
    entry = (certToTSN_entry*)row->data;
    entry->rowStatus = atoi(line);
    entry->storageType = ST_NONVOLATILE;

    /*
     * if row is active, add it to the maps container so it is available
     * for use. Do not add it to the table, since it will be added
     * during cache_load.
     */
    if (RS_ACTIVE == entry->rowStatus) {
        if (netsnmp_cert_map_add(map) != 0)
            netsnmp_cert_map_free(map);
    }
    else {
        netsnmp_cert_map_free(map);
        if (netsnmp_tdata_add_row(_table, row) != SNMPERR_SUCCESS)
            tlstmCertToTSNTable_removeEntry(NULL, row);
    }
}

static int
_save_entry(certToTSN_entry *entry, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType, *mapType, *data = NULL;

    if (NULL == entry)
        return SNMP_ERR_GENERR;

    hashType = se_find_label_in_slist("cert_hash_alg", entry->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 entry->hashType);
        return SNMP_ERR_GENERR;
    }
    mapType = se_find_label_in_slist("cert_map_type", entry->mapType);
    if (TSNM_tlstmCertSpecified == entry->mapType)
        data = entry->data;
    snprintf(buf, sizeof(buf), "%s %ld --%s %s --%s %s %d",
             MAP_MIB_CONFIG_TOKEN, entry->tlstmCertToTSNID, hashType,
             entry->fingerprint, mapType, data ? data : "", entry->rowStatus);

    DEBUGMSGTL(("tlstmCertToTSNTable:save", "saving '%s'\n", buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}

static int
_save_map(netsnmp_cert_map *map, int row_status, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType, *mapType, *data = NULL;

    if (NULL == map)
        return SNMP_ERR_GENERR;

    /** don't store values from conf files */
    if (! (map->flags & NSCM_NONVOLATILE)) {
        DEBUGMSGT(("tlstmCertToTSNTable:save", 
                   "skipping RO/permanent/volatile row\n"));
        return SNMP_ERR_NOERROR;
    }

    hashType = se_find_label_in_slist("cert_hash_alg", map->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 map->hashType);
        return SNMP_ERR_GENERR;
    }
    mapType = se_find_label_in_slist("cert_map_type", map->mapType);
    if (TSNM_tlstmCertSpecified == map->mapType)
        data = (char*)map->data;
    snprintf(buf, sizeof(buf), "%s %d --%s %s --%s %s %d",
             MAP_MIB_CONFIG_TOKEN, map->priority, hashType, map->fingerprint,
             mapType, data ? data : "", row_status);

    DEBUGMSGTL(("tlstmCertToTSNTable:save", "saving '%s'\n", buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}

static int
_save_maps(int majorID, int minorID, void *serverarg, void *clientarg)
{
    char            sep[] =
        "\n##############################################################";
    char            buf[] =
        "#\n" "# certificate secName mapping persistent data\n" "#";
    char           *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                                 NETSNMP_DS_LIB_APPTYPE);
    netsnmp_container *maps = netsnmp_cert_map_container();
    netsnmp_tdata_row *row;
    netsnmp_iterator  *tbl_itr, *map_itr;
    netsnmp_cert_map  *map;
    certToTSN_entry   *entry;

    if ((NULL == maps) || ((CONTAINER_SIZE(maps) == 0) &&
                           (CONTAINER_SIZE(_table->container) == 0)))
        return SNMPERR_SUCCESS;

    read_config_store((char *) type, sep);
    read_config_store((char *) type, buf);

    /*
     * save active rows from maps
     */
    if (NULL != maps) {
        map_itr = CONTAINER_ITERATOR(maps);
        if (NULL == map_itr) {
            DEBUGMSGTL(("tlstmCertToTSNTable:save",
                        "cant get map iterator\n"));
            map = NULL;
        }
        else
            map = ITERATOR_FIRST(map_itr);

        for( ; map; map = ITERATOR_NEXT(map_itr)) {
            /** don't store config rows */
            if (map->flags & NSCM_FROM_CONFIG)
                continue;
            _save_map(map, RS_ACTIVE, type);
        }
    }
    ITERATOR_RELEASE(map_itr);

    /*
     * save inactive rows from mib
     */
    tbl_itr = CONTAINER_ITERATOR(_table->container);
    if (NULL == tbl_itr)
        DEBUGMSGTL(("tlstmCertToTSNTable:save", "cant get table iterator\n"));
    else {
        row = ITERATOR_FIRST(tbl_itr);
        for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
            entry = row->data;

            /*
             * skip all active rows (should be in maps and thus saved
             * above) and volatile rows.
             */
            if ((entry->rowStatus == RS_ACTIVE) ||
                (entry->storageType != ST_NONVOLATILE))
                continue;

            _save_entry(entry, type);
        }
        ITERATOR_RELEASE(tbl_itr);
    }

    read_config_store((char *) type, sep);
    read_config_store((char *) type, "\n");

    /*
     * never fails 
     */
    return SNMPERR_SUCCESS;
}


static const oid _tsnm_base[] = { SNMP_TLS_TM_BASE, 1, 1 };
static const int _tsnm_base_len = sizeof(_tsnm_base);

static oid
_oid2type(oid *val, int val_len)
{
    netsnmp_assert(val);

    if (val_len != (_tsnm_base_len + sizeof(oid)))
        return -1;

    if (memcmp(_tsnm_base,val,_tsnm_base_len) != 0)
        return -2;

    if ((val[OID_LENGTH(_tsnm_base)] > TSNM_tlstmCert_MAX) ||
        (0 == val[OID_LENGTH(_tsnm_base)]))
        return -3;

    return val[OID_LENGTH(_tsnm_base)];
}

#if 0
static int
_type2oid(int type, oid *val, int *val_len)
{
    netsnmp_assert( val && val_len );

    if (*val_len < _tsnm_base_len + sizeof(oid))
        return -1;

    memcpy(val, _tsnm_base, _tsnm_base_len + sizeof(oid));
    val[_tsnm_base_len + sizeof(oid)] = type;

    return 0;
}
#endif
