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

#include <net-snmp/net-snmp-config.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"

/** 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_scalar(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
