| /* |
| * 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 "snmpTlstmParamsTable.h" |
| |
| netsnmp_feature_require(table_tdata) |
| netsnmp_feature_require(tlstmparams_find) |
| netsnmp_feature_require(tlstmparams_external) |
| 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) |
| #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 |
| |
| /** ************************************************************************** |
| * |
| * table structures |
| * |
| */ |
| /* |
| * structure for undo storage and other vars for set processing |
| */ |
| typedef struct snmpTlstmParamsTable_undo_s { |
| char fate; |
| char copied; |
| char is_consistent; |
| netsnmp_request_info *req[SNMPTLSTMPARAMSTABLE_MAX_COLUMN + 1]; |
| /* undo Column space */ |
| char snmpTlstmParamsClientFingerprint[SNMPTLSTMPARAMSCLIENTFINGERPRINT_MAX_SIZE]; |
| size_t snmpTlstmParamsClientFingerprint_len; |
| char snmpTlstmParamsStorageType; |
| char snmpTlstmParamsRowStatus; |
| } snmpTlstmParamsTable_undo; |
| |
| /* |
| * Typical data structure for a row entry |
| */ |
| typedef struct snmpTlstmParamsTable_entry_s { |
| /* Index values */ |
| char snmpTargetParamsName[SNMPTARGETPARAMSNAME_MAX_SIZE]; |
| size_t snmpTargetParamsName_len; |
| |
| /* Column values */ |
| char snmpTlstmParamsClientFingerprint[SNMPTLSTMPARAMSCLIENTFINGERPRINT_MAX_SIZE]; |
| size_t snmpTlstmParamsClientFingerprint_len; |
| char snmpTlstmParamsStorageType; |
| char snmpTlstmParamsRowStatus; |
| |
| char hashType; |
| char params_flags; |
| |
| /* used during set processing */ |
| snmpTlstmParamsTable_undo *undo; |
| } snmpTlstmParamsTable_entry; |
| |
| static Netsnmp_Node_Handler snmpTlstmParamsTable_handler; |
| static NetsnmpCacheLoad snmpTlstmParamsTable_load; |
| static NetsnmpCacheFree snmpTlstmParamsTable_free; |
| |
| static int _count_handler(netsnmp_mib_handler *handler, |
| netsnmp_handler_registration *reginfo, |
| netsnmp_agent_request_info *reqinfo, |
| netsnmp_request_info *requests); |
| static void _tlstmParams_init_persistence(void); |
| static void _params_add(snmpTlstmParamsTable_entry *entry); |
| static void _params_remove(snmpTlstmParamsTable_entry *entry); |
| static void _params_tweak_storage(snmpTlstmParamsTable_entry *entry); |
| |
| static uint32_t _last_changed = 0; |
| static netsnmp_tdata *_table_data = NULL; |
| |
| /* |
| * Initialize the snmpTlstmParamsTable table by defining its contents |
| * and how it's structured |
| */ |
| void |
| init_snmpTlstmParamsTable(void) |
| { |
| oid reg_oid[] = {SNMP_TLS_TM_BASE,2,2,1,6}; |
| const size_t reg_oid_len = OID_LENGTH(reg_oid); |
| netsnmp_handler_registration *reg; |
| netsnmp_table_registration_info *table_info; |
| netsnmp_cache *cache; |
| netsnmp_watcher_info *watcher; |
| |
| DEBUGMSGTL(("tlstmParamsTable:init", "initializing table snmpTlstmParamsTable\n")); |
| |
| reg = netsnmp_create_handler_registration |
| ("snmpTlstmParamsTable", snmpTlstmParamsTable_handler, reg_oid, |
| reg_oid_len, HANDLER_CAN_RWRITE); |
| |
| _table_data = netsnmp_tdata_create_table( "snmpTlstmParamsTable", 0 ); |
| if (NULL == _table_data) { |
| snmp_log(LOG_ERR,"error creating tdata table for snmpTlstmParamsTable\n"); |
| return; |
| } |
| cache = netsnmp_cache_create(SNMPTLSTMPARAMSTABLE_TIMEOUT, |
| snmpTlstmParamsTable_load, |
| snmpTlstmParamsTable_free, |
| reg_oid, reg_oid_len); |
| if (NULL == cache) { |
| snmp_log(LOG_ERR,"error creating cache for snmpTlstmParamsTable\n"); |
| netsnmp_tdata_delete_table(_table_data); |
| _table_data = NULL; |
| return; |
| } |
| cache->magic = (void *)_table_data; |
| cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET; |
| |
| table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); |
| if (NULL == table_info) { |
| snmp_log(LOG_ERR,"error creating table info for snmpTlstmParamsTable\n"); |
| netsnmp_tdata_delete_table(_table_data); |
| _table_data = NULL; |
| netsnmp_cache_free(cache); |
| return; |
| } |
| /* |
| * populate index types |
| */ |
| netsnmp_table_helper_add_indexes(table_info, |
| /* index: snmpTargetParamsName */ |
| ASN_PRIV_IMPLIED_OCTET_STR, 0); |
| |
| table_info->min_column = SNMPTLSTMPARAMSTABLE_MIN_COLUMN; |
| table_info->max_column = SNMPTLSTMPARAMSTABLE_MAX_COLUMN; |
| |
| netsnmp_tdata_register( reg, _table_data, table_info ); |
| netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get(cache), |
| "table_container"); |
| |
| /* |
| * register scalars |
| */ |
| reg_oid[10] = 4; |
| reg = netsnmp_create_handler_registration("snmpTlstmParamsCount", |
| _count_handler, reg_oid, |
| OID_LENGTH(reg_oid), |
| HANDLER_CAN_RONLY); |
| if (NULL == reg) |
| snmp_log(LOG_ERR, |
| "could not create handler for snmpTlstmParamsCount\n"); |
| else { |
| netsnmp_register_scalar(reg); |
| if (cache) |
| netsnmp_inject_handler_before(reg, |
| netsnmp_cache_handler_get(cache), |
| "snmpTlstmParamsCount"); |
| } |
| |
| reg_oid[10] = 5; |
| reg = netsnmp_create_handler_registration( |
| "snmpTlstmParamsTableLastChanged", 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 snmpTlstmParamsTableLastChanged\n"); |
| else |
| netsnmp_register_watched_scalar2(reg, watcher); |
| |
| /* |
| * Initialise the contents of the table here |
| */ |
| _tlstmParams_init_persistence(); |
| } |
| |
| /** ************************************************************************** |
| * |
| * utility functions for table structures |
| * |
| */ |
| /* create a new row in the table */ |
| netsnmp_tdata_row * |
| snmpTlstmParamsTable_createEntry(netsnmp_tdata *table_data, |
| char* snmpTargetParamsName, |
| size_t snmpTargetParamsName_len ) { |
| snmpTlstmParamsTable_entry *entry; |
| netsnmp_tdata_row *row; |
| |
| if ((NULL == snmpTargetParamsName) || (snmpTargetParamsName_len > |
| sizeof(entry->snmpTargetParamsName))) |
| return NULL; |
| |
| entry = SNMP_MALLOC_TYPEDEF(snmpTlstmParamsTable_entry); |
| if (!entry) |
| return NULL; |
| |
| row = netsnmp_tdata_create_row(); |
| if (!row) { |
| SNMP_FREE(entry); |
| return NULL; |
| } |
| row->data = entry; |
| |
| DEBUGMSGT(("tlstmParamsTable:entry:create", "entry %p / row %p\n", |
| entry, row)); |
| |
| DEBUGIF("snmpTlstmParamTable:entry:create") { |
| char name[sizeof(entry->snmpTargetParamsName)+1]; |
| snprintf(name, sizeof(name), "%s", snmpTargetParamsName); |
| DEBUGMSGT(("tlstmParamsTable:entry:create", |
| "entry %s %p / row %p\n", |
| name, entry, row)); |
| } |
| |
| /* |
| * populate index |
| */ |
| memcpy(entry->snmpTargetParamsName, snmpTargetParamsName, |
| snmpTargetParamsName_len); |
| entry->snmpTargetParamsName_len = snmpTargetParamsName_len; |
| netsnmp_tdata_row_add_index( row, ASN_PRIV_IMPLIED_OCTET_STR, |
| entry->snmpTargetParamsName, |
| snmpTargetParamsName_len); |
| |
| entry->snmpTlstmParamsClientFingerprint[0] = '\0'; |
| entry->snmpTlstmParamsClientFingerprint_len = 0; |
| entry->snmpTlstmParamsRowStatus = RS_NOTREADY; |
| entry->snmpTlstmParamsStorageType = ST_NONVOLATILE; |
| |
| if (table_data) { |
| DEBUGMSGTL(("tlstmParamsTable:row:insert", "row %p\n", |
| row)); |
| netsnmp_tdata_add_row( table_data, row ); |
| } |
| return row; |
| } |
| |
| /* allocate undo resources */ |
| static snmpTlstmParamsTable_undo * |
| _allocUndo(snmpTlstmParamsTable_entry *entry) |
| { |
| if (!entry) |
| return NULL; |
| |
| entry->undo = SNMP_MALLOC_TYPEDEF(snmpTlstmParamsTable_undo); |
| if (!entry->undo) |
| return NULL; |
| |
| entry->undo->is_consistent = -1; /* don't know */ |
| |
| /* TODO: allocated any other resources needed */ |
| |
| return entry->undo; |
| } |
| |
| /* free undo resources */ |
| static void |
| _freeUndo(snmpTlstmParamsTable_entry *entry) |
| { |
| if (!entry || !entry->undo) |
| return; |
| |
| /* TODO: release any allocated resources */ |
| SNMP_FREE(entry->undo); |
| } |
| |
| /* remove a row from the table */ |
| void |
| snmpTlstmParamsTable_removeEntry(netsnmp_tdata *table_data, |
| netsnmp_tdata_row *row) |
| { |
| snmpTlstmParamsTable_entry *entry; |
| |
| if (!row) |
| return; /* Nothing to remove */ |
| |
| entry = (snmpTlstmParamsTable_entry *)row->data; |
| |
| DEBUGMSGT(("tlstmParamsTable:entry:delete", "entry %p / row %p\n", |
| entry, row)); |
| |
| if (table_data) { |
| DEBUGMSGTL(("tlstmParamsTable:row:remove", "row %p\n", row)); |
| netsnmp_tdata_remove_and_delete_row( table_data, row ); |
| } |
| else |
| netsnmp_tdata_delete_row( row ); |
| |
| if (entry && entry->undo) |
| _freeUndo(entry); |
| SNMP_FREE( entry ); /* TODO - release any other internal resources */ |
| } |
| |
| /** ************************************************************************** |
| * |
| * handle cache / interactions with snmpTlstmParams container in snmplib |
| * |
| */ |
| static void |
| _params_add(snmpTlstmParamsTable_entry *entry) |
| { |
| snmpTlstmParams *params; |
| |
| if (NULL == entry) |
| return; |
| |
| DEBUGMSGTL(("tlstmParamsTable:params:add", "name %s, fp %s\n", |
| entry->snmpTargetParamsName, entry->snmpTlstmParamsClientFingerprint)); |
| |
| params = |
| netsnmp_tlstmParams_create(entry->snmpTargetParamsName, |
| entry->hashType, |
| entry->snmpTlstmParamsClientFingerprint, |
| entry->snmpTlstmParamsClientFingerprint_len); |
| if (NULL == params) |
| return; |
| |
| params->flags = TLSTM_PARAMS_FROM_MIB; |
| if (entry->snmpTlstmParamsStorageType == ST_NONVOLATILE) |
| params->flags |= TLSTM_PARAMS_NONVOLATILE; |
| |
| if (netsnmp_tlstmParams_add(params) != 0) { |
| netsnmp_tlstmParams_free(params); |
| } |
| } |
| |
| static void |
| _params_remove(snmpTlstmParamsTable_entry *entry) |
| { |
| snmpTlstmParams index, *found; |
| |
| if (NULL == entry) |
| return; |
| |
| DEBUGMSGTL(("tlstmParamsTable:params:remove", "name %s\n", |
| entry->snmpTargetParamsName)); |
| |
| index.name = entry->snmpTargetParamsName; |
| found = netsnmp_tlstmParams_find(&index); |
| if (found) { |
| netsnmp_tlstmParams_remove(found); |
| netsnmp_tlstmParams_free(found); |
| } |
| entry->params_flags = 0; |
| } |
| |
| static void |
| _params_tweak_storage(snmpTlstmParamsTable_entry *entry) |
| { |
| snmpTlstmParams *params, index; |
| |
| if (NULL == entry) |
| return; |
| |
| DEBUGMSGTL(("tlstmParamsTable:params:tweak", "name %s, st %d\n", |
| entry->snmpTargetParamsName, entry->snmpTlstmParamsStorageType)); |
| |
| index.name = entry->snmpTargetParamsName; |
| params = netsnmp_tlstmParams_find(&index); |
| if (NULL == params) { |
| DEBUGMSGTL(("tlstmParamsTable:params:tweak", |
| "couldn't find params!\n")); |
| return; |
| } |
| |
| if (entry->snmpTlstmParamsStorageType == ST_NONVOLATILE) |
| params->flags |= TLSTM_PARAMS_NONVOLATILE; |
| else |
| params->flags &= ~TLSTM_PARAMS_NONVOLATILE; |
| } |
| |
| static netsnmp_tdata_row * |
| _entry_from_params(snmpTlstmParams *params) |
| { |
| netsnmp_tdata_row *row; |
| snmpTlstmParamsTable_entry *entry; |
| |
| row = snmpTlstmParamsTable_createEntry(NULL, params->name, |
| strlen(params->name)); |
| if (NULL == row) { |
| snmp_log(LOG_ERR, "can create snmpTlstmParams row entry\n"); |
| return NULL; |
| } |
| entry = row->data; |
| |
| if (params->flags & TLSTM_PARAMS_FROM_CONFIG) |
| entry->snmpTlstmParamsStorageType = ST_PERMANENT; |
| else if (! (params->flags & TLSTM_PARAMS_NONVOLATILE)) |
| entry->snmpTlstmParamsStorageType = ST_VOLATILE; |
| |
| entry->snmpTlstmParamsRowStatus = RS_ACTIVE; |
| |
| if (params->fingerprint) { |
| entry->snmpTlstmParamsClientFingerprint_len = |
| strlen(params->fingerprint); |
| if (entry->snmpTlstmParamsClientFingerprint_len > |
| sizeof(entry->snmpTlstmParamsClientFingerprint)) |
| entry->snmpTlstmParamsClientFingerprint_len = |
| sizeof(entry->snmpTlstmParamsClientFingerprint) - 1; |
| memcpy(entry->snmpTlstmParamsClientFingerprint, params->fingerprint, |
| entry->snmpTlstmParamsClientFingerprint_len); |
| entry->snmpTlstmParamsClientFingerprint[sizeof(entry->snmpTlstmParamsClientFingerprint) - 1] = 0; |
| } |
| entry->hashType = params->hashType; |
| entry->params_flags = params->flags; |
| |
| return row; |
| } |
| |
| static int |
| snmpTlstmParamsTable_load( netsnmp_cache *cache, void *vmagic ) |
| { |
| netsnmp_tdata *table = (netsnmp_tdata *)vmagic; |
| netsnmp_tdata_row *row; |
| netsnmp_container *active_params; |
| netsnmp_iterator *itr; |
| snmpTlstmParams *params; |
| int rc = 0; |
| |
| active_params = netsnmp_tlstmParams_container(); |
| if (NULL == active_params) |
| return 0; |
| |
| DEBUGMSGTL(("tlstmParamsTable:cache:load", "snmpTlstmParams %" NETSNMP_PRIz "d rows\n", |
| CONTAINER_SIZE(active_params))); |
| itr = CONTAINER_ITERATOR(active_params); |
| if (NULL == itr) { |
| DEBUGMSGTL(("tlstmParamsTable:cache:load", |
| "cant get iterator\n")); |
| return -1; |
| } |
| |
| /* |
| * insert rows for active params into tbl container |
| */ |
| params = ITERATOR_FIRST(itr); |
| for( ; params; params = ITERATOR_NEXT(itr)) { |
| |
| row = _entry_from_params(params); |
| if (NULL == row) { |
| rc =-1; |
| break; |
| } |
| if (netsnmp_tdata_add_row(table, row) != SNMPERR_SUCCESS) { |
| snmpTlstmParamsTable_removeEntry(NULL, row); |
| rc = -1; |
| break; |
| } |
| } |
| ITERATOR_RELEASE(itr); |
| |
| DEBUGMSGTL(("tlstmParamsTable:cache:load", "done, %" NETSNMP_PRIz "d rows\n", |
| CONTAINER_SIZE(table->container))); |
| |
| return rc; |
| } |
| |
| static void |
| snmpTlstmParamsTable_free( netsnmp_cache *cache, void *vmagic ) |
| { |
| netsnmp_tdata *table = (netsnmp_tdata *)vmagic; |
| netsnmp_tdata_row *row; |
| netsnmp_iterator *tbl_itr; |
| snmpTlstmParamsTable_entry *entry; |
| |
| DEBUGMSGTL(("tlstmParamsTable:cache:free", "called, %" NETSNMP_PRIz "d rows\n", |
| CONTAINER_SIZE(table->container))); |
| |
| tbl_itr = CONTAINER_ITERATOR(table->container); |
| if (NULL == tbl_itr) { |
| DEBUGMSGTL(("tlstmParamsTable:cache:free", |
| "cant get entry 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 params container kept |
| * by the library). Keep inactive ones for next time. |
| */ |
| if (entry->snmpTlstmParamsRowStatus == RS_ACTIVE) { |
| snmpTlstmParamsTable_removeEntry(NULL, row); |
| ITERATOR_REMOVE(tbl_itr); |
| continue; |
| } |
| } |
| ITERATOR_RELEASE(tbl_itr); |
| |
| DEBUGMSGTL(("tlstmParamsTable:cache:free", "done, %" NETSNMP_PRIz "d rows\n", |
| CONTAINER_SIZE(table->container))); |
| } |
| |
| /** ************************************************************************** |
| * |
| * handles requests for the snmpTlstmParamsTable table |
| * |
| */ |
| static int |
| snmpTlstmParamsTable_handler( |
| netsnmp_mib_handler *handler, |
| netsnmp_handler_registration *reginfo, |
| netsnmp_agent_request_info *reqinfo, |
| netsnmp_request_info *requests) { |
| |
| netsnmp_request_info *request = NULL; |
| netsnmp_table_request_info *table_info; |
| netsnmp_tdata *table_data; |
| netsnmp_tdata_row *table_row; |
| snmpTlstmParamsTable_entry *table_entry; |
| int ret = SNMP_ERR_NOERROR; |
| |
| DEBUGMSGTL(("tlstmParamsTable:handler", "Processing %s mode (%d) request\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; |
| |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_info = netsnmp_extract_table_info( request); |
| switch (table_info->colnum) { |
| case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: |
| { |
| u_char bin[42], *ptr = bin; |
| size_t len = sizeof(bin), offset = 1; |
| int rc; |
| bin[0] = table_entry->hashType; |
| netsnmp_assert(table_entry->hashType != 0); |
| rc = netsnmp_hex_to_binary( |
| &ptr, &len, &offset, 0, |
| table_entry->snmpTlstmParamsClientFingerprint, NULL); |
| if (1 != rc) |
| netsnmp_set_request_error(reqinfo, request, |
| SNMP_ERR_GENERR); |
| else |
| snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, |
| bin, offset); |
| } |
| break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */ |
| case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE: |
| snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, |
| table_entry->snmpTlstmParamsStorageType); |
| break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */ |
| case COLUMN_SNMPTLSTMPARAMSROWSTATUS: |
| snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, |
| table_entry->snmpTlstmParamsRowStatus); |
| break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */ |
| 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) { |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_info = netsnmp_extract_table_info( request); |
| |
| if ((NULL != table_entry) && |
| (ST_READONLY == table_entry->snmpTlstmParamsStorageType)) { |
| ret = SNMP_ERR_NOTWRITABLE; |
| break; |
| } |
| |
| /* |
| * for each column, allocate any additional resources needed |
| * beyond what is in the undo structure. |
| */ |
| switch (table_info->colnum) { |
| case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: |
| ret = netsnmp_check_vb_type_and_max_size( |
| request->requestvb, ASN_OCTET_STR, sizeof(table_entry->snmpTlstmParamsClientFingerprint)); |
| /** check len/algorithm MIB requirements */ |
| if (SNMP_ERR_NOERROR == ret) |
| ret = netsnmp_cert_check_vb_fingerprint(request->requestvb); |
| |
| break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */ |
| |
| case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE: |
| ret = netsnmp_check_vb_storagetype(request->requestvb, |
| (table_entry ? table_entry->snmpTlstmParamsStorageType : ST_NONE )); |
| break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */ |
| |
| case COLUMN_SNMPTLSTMPARAMSROWSTATUS: |
| ret = netsnmp_check_vb_rowstatus_with_storagetype(request->requestvb, |
| (table_entry ? table_entry->snmpTlstmParamsRowStatus : RS_NONEXISTENT ), |
| (table_entry ? table_entry->snmpTlstmParamsStorageType : ST_NONE)); |
| break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */ |
| 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) { |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_data = netsnmp_tdata_extract_table(request); |
| table_info = netsnmp_extract_table_info( request); |
| /* |
| * if no table_row, create one |
| */ |
| if ( !table_entry ) { |
| table_row = snmpTlstmParamsTable_createEntry |
| (table_data, (char*)table_info->indexes->val.string, |
| table_info->indexes->val_len); |
| if (!table_row) { |
| ret = SNMP_ERR_RESOURCEUNAVAILABLE; |
| break; |
| } |
| table_entry = table_row->data; |
| _allocUndo(table_entry); |
| if (table_entry && !table_entry->undo) { |
| snmpTlstmParamsTable_removeEntry(table_data, table_row); |
| table_row = NULL; |
| ret = SNMP_ERR_RESOURCEUNAVAILABLE; |
| break; |
| } |
| table_entry->undo->fate = FATE_NEWLY_CREATED; |
| /** associate row with requests */ |
| netsnmp_insert_tdata_row( request, table_row ); |
| } |
| |
| /** allocate undo structure, if needed */ |
| if(!table_entry->undo) { |
| _allocUndo(table_entry); |
| if (!table_entry->undo) { |
| ret = SNMP_ERR_RESOURCEUNAVAILABLE; |
| break; |
| } |
| } |
| |
| /** don't allow multiple sets of same column */ |
| if (table_entry->undo->req[table_info->colnum]) { |
| DEBUGMSGT(("tlstmParamsTable:reserve2", |
| "multiple sets to col %d in request\n", |
| table_info->colnum)); |
| ret = SNMP_ERR_INCONSISTENTNAME; |
| break; |
| } |
| table_entry->undo->req[table_info->colnum] = request; |
| |
| if ( ret != SNMP_ERR_NOERROR ) |
| break; |
| } /* for requests */ |
| |
| /** make sure rowstatus is used to create rows */ |
| if ( ret == SNMP_ERR_NOERROR ) { |
| for (request = requests; request; request = request->next) { |
| if (request->processed) |
| continue; |
| |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| if ((table_entry->undo->fate != FATE_NEWLY_CREATED) || |
| (table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS])) |
| continue; |
| ret = SNMP_ERR_INCONSISTENTNAME; |
| break; |
| } /* for requests / creation */ |
| } /* if 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_row = netsnmp_tdata_extract_row( request); |
| table_data = netsnmp_tdata_extract_table(request); |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| |
| if ( !table_entry || !table_entry->undo ) |
| continue; |
| |
| /** disassociate row with requests */ |
| netsnmp_remove_tdata_row( request, table_row ); |
| |
| if (FATE_NEWLY_CREATED == table_entry->undo->fate ) |
| snmpTlstmParamsTable_removeEntry( table_data, table_row ); |
| else |
| _freeUndo(table_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) { |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_info = netsnmp_extract_table_info( request); |
| |
| switch (table_info->colnum) { |
| case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: |
| { |
| u_char *tmp = (u_char*)table_entry->snmpTlstmParamsClientFingerprint; |
| |
| memcpy( table_entry->undo->snmpTlstmParamsClientFingerprint, |
| table_entry->snmpTlstmParamsClientFingerprint, |
| sizeof(table_entry->snmpTlstmParamsClientFingerprint)); |
| table_entry->undo->snmpTlstmParamsClientFingerprint_len = |
| table_entry->snmpTlstmParamsClientFingerprint_len; |
| |
| table_entry->hashType = request->requestvb->val.string[0]; |
| memset( table_entry->snmpTlstmParamsClientFingerprint, 0, |
| sizeof(table_entry->snmpTlstmParamsClientFingerprint)); |
| table_entry->snmpTlstmParamsClientFingerprint_len = |
| sizeof(table_entry->snmpTlstmParamsClientFingerprint); |
| table_entry->snmpTlstmParamsClientFingerprint_len = |
| netsnmp_binary_to_hex(&tmp, &table_entry->snmpTlstmParamsClientFingerprint_len, |
| 0, &request->requestvb->val.string[1], |
| request->requestvb->val_len - 1); |
| if (0 == table_entry->snmpTlstmParamsClientFingerprint_len) |
| ret = SNMP_ERR_GENERR; |
| } |
| break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */ |
| |
| case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE: |
| /* save snmpTlstmParamsStorageType value */ |
| table_entry->undo->snmpTlstmParamsStorageType = table_entry->snmpTlstmParamsStorageType; |
| /* get value from varbind */ |
| table_entry->snmpTlstmParamsStorageType = *request->requestvb->val.integer; |
| break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */ |
| |
| case COLUMN_SNMPTLSTMPARAMSROWSTATUS: |
| /* save snmpTlstmParamsRowStatus value */ |
| table_entry->undo->snmpTlstmParamsRowStatus = table_entry->snmpTlstmParamsRowStatus; |
| /* get value from varbind */ |
| table_entry->snmpTlstmParamsRowStatus = *request->requestvb->val.integer; |
| break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */ |
| } /* switch colnum */ |
| if ( ret != SNMP_ERR_NOERROR ) |
| break; |
| } /* set values for requests */ |
| |
| if ( ret == SNMP_ERR_NOERROR ) { |
| |
| /* |
| * All columns now have their final values set. check the |
| * internal consistency of each row. |
| */ |
| for (request=requests; request; request=request->next) { |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_info = netsnmp_extract_table_info( request); |
| |
| if (table_entry->undo->is_consistent != -1) |
| continue; /* already checked */ |
| |
| /** assume consistency */ |
| table_entry->undo->is_consistent = 1; |
| |
| if ((RS_IS_ACTIVE(table_entry->snmpTlstmParamsRowStatus)) && |
| ((!table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS]) || |
| (RS_IS_ACTIVE(table_entry->undo->snmpTlstmParamsRowStatus)))) { |
| /* |
| * check mib restrictions on active rows. |
| */ |
| if (table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT]) { |
| table_entry->undo->is_consistent = 0; |
| request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT]; |
| ret = SNMP_ERR_INCONSISTENTVALUE; /* per mib */ |
| } |
| } /* active row */ |
| else if (RS_IS_GOING_ACTIVE(table_entry->snmpTlstmParamsRowStatus)) { |
| /* |
| * check restrictions for activating a row |
| */ |
| /** if going active, inconsistency is fatal */ |
| if (!table_entry->undo->is_consistent) { |
| if (FATE_NEWLY_CREATED == table_entry->undo->fate) |
| ret = SNMP_ERR_INCONSISTENTNAME; |
| else |
| ret = SNMP_ERR_INCONSISTENTVALUE; |
| request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS]; |
| } |
| } /* going active */ |
| else if (RS_DESTROY == table_entry->snmpTlstmParamsRowStatus) { |
| /* |
| * TODO: check restrictions for deleting a row |
| */ |
| /** can't delete active row */ |
| if (RS_IS_ACTIVE(table_entry->undo->snmpTlstmParamsRowStatus)) { |
| ret = SNMP_ERR_INCONSISTENTVALUE; |
| request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS]; |
| } |
| } /* destroy */ |
| if ( ret != SNMP_ERR_NOERROR ) |
| break; |
| } /* consistency for requests */ |
| } /* if no error */ |
| 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) { |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| table_row = netsnmp_tdata_extract_row( request); |
| table_data = netsnmp_tdata_extract_table(request); |
| table_info = netsnmp_extract_table_info( request); |
| |
| switch (table_info->colnum) { |
| case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: |
| /* restore snmpTlstmParamsClientFingerprint value */ |
| memcpy( table_entry->snmpTlstmParamsClientFingerprint, |
| table_entry->undo->snmpTlstmParamsClientFingerprint, |
| sizeof(table_entry->snmpTlstmParamsClientFingerprint)); |
| table_entry->snmpTlstmParamsClientFingerprint_len = |
| table_entry->undo->snmpTlstmParamsClientFingerprint_len; |
| break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */ |
| |
| case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE: |
| /* restore snmpTlstmParamsStorageType value */ |
| table_entry->snmpTlstmParamsStorageType = |
| table_entry->undo->snmpTlstmParamsStorageType; |
| break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */ |
| |
| case COLUMN_SNMPTLSTMPARAMSROWSTATUS: |
| /* restore snmpTlstmParamsRowStatus value */ |
| table_entry->snmpTlstmParamsRowStatus = table_entry->undo->snmpTlstmParamsRowStatus; |
| break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */ |
| } /* switch colnum */ |
| } /* for requests */ |
| |
| /* |
| * release undo data |
| * or remove any newly created rows |
| */ |
| for (request=requests; request; request=request->next) { |
| table_row = netsnmp_tdata_extract_row( request); |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| |
| if ( !table_entry || !table_entry->undo ) |
| continue; |
| |
| /** disassociate row with requests */ |
| netsnmp_remove_tdata_row( request, table_row ); |
| |
| if (FATE_NEWLY_CREATED == table_entry->undo->fate ) |
| snmpTlstmParamsTable_removeEntry( table_data, table_row ); |
| else |
| _freeUndo(table_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) { |
| table_row = netsnmp_tdata_extract_row( request); |
| table_data = netsnmp_tdata_extract_table(request); |
| table_info = netsnmp_extract_table_info( request); |
| table_entry = (snmpTlstmParamsTable_entry *) |
| netsnmp_tdata_extract_entry(request); |
| |
| if (!table_entry || !table_entry->undo) |
| continue; |
| |
| if ((RS_NOTREADY == table_entry->snmpTlstmParamsRowStatus) && |
| table_entry->undo->is_consistent) |
| table_entry->snmpTlstmParamsRowStatus = RS_NOTINSERVICE; |
| else if ((RS_NOTINSERVICE == table_entry->snmpTlstmParamsRowStatus) && |
| (0 == table_entry->undo->is_consistent)) |
| table_entry->snmpTlstmParamsRowStatus = RS_NOTREADY; |
| |
| /** release undo data for requests with no rowstatus */ |
| if (table_entry->undo && |
| !table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS] != 0) { |
| _freeUndo(table_entry); |
| |
| /** update active addrs */ |
| if ((0 == table_entry->params_flags) && |
| (table_entry->snmpTlstmParamsRowStatus == RS_ACTIVE)) |
| _params_add(table_entry); |
| else if ((0 != table_entry->params_flags) && |
| (table_entry->snmpTlstmParamsRowStatus == RS_DESTROY)) |
| _params_remove(table_entry); |
| } |
| |
| switch (table_info->colnum) { |
| |
| case COLUMN_SNMPTLSTMPARAMSROWSTATUS: |
| switch (table_entry->snmpTlstmParamsRowStatus) { |
| case RS_CREATEANDGO: |
| /** Fall-through */ |
| case RS_ACTIVE: |
| table_entry->snmpTlstmParamsRowStatus = RS_ACTIVE; |
| if (0 == table_entry->params_flags) |
| _params_add(table_entry); |
| break; |
| |
| case RS_CREATEANDWAIT: |
| /** Fall-through */ |
| case RS_NOTINSERVICE: |
| /** simply set status based on consistency */ |
| if (table_entry->undo->is_consistent) |
| table_entry->snmpTlstmParamsRowStatus = RS_NOTINSERVICE; |
| else |
| table_entry->snmpTlstmParamsRowStatus = RS_NOTREADY; |
| if (0 != table_entry->params_flags) |
| _params_remove(table_entry); |
| break; |
| |
| case RS_DESTROY: |
| if (0 != table_entry->params_flags) |
| _params_remove(table_entry); |
| /** disassociate row with requests */ |
| netsnmp_remove_tdata_row( request, table_row ); |
| snmpTlstmParamsTable_removeEntry(table_data, table_row ); |
| table_row = NULL; |
| table_entry = NULL; |
| } |
| /** release undo data */ |
| _freeUndo(table_entry); |
| break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */ |
| |
| case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE: |
| if (RS_ACTIVE == table_entry->snmpTlstmParamsRowStatus) |
| _params_tweak_storage(table_entry); |
| break; |
| |
| case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: |
| 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_data->container) |
| val = 0; |
| else |
| val = CONTAINER_SIZE(_table_data->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; |
| } |
| |
| /*********************************************************************** |
| * |
| * PERSISTENCE |
| * |
| ***********************************************************************/ |
| |
| static int _tlstmParamsTable_save(int majorID, int minorID, |
| void *serverarg, void *clientarg); |
| static int _save_params(snmpTlstmParams *params, void *app_type); |
| static int _save_entry(snmpTlstmParamsTable_entry *entry, void *type); |
| static void _tlstmParamsTable_row_restore_mib(const char *token, char *buf); |
| |
| static const char mib_token[] = "snmpTlstmParamsEntry"; |
| |
| /************************************************************ |
| * *_init_persistence should be called from the main table |
| * init routine. |
| * |
| * If your table depends on rows in another table, |
| * you should register your callback after the other table, |
| * which should ensure the rows on which you depend are saved |
| * (and re-created) before the dependent rows. |
| */ |
| void |
| _tlstmParams_init_persistence(void) |
| { |
| int rc; |
| |
| register_config_handler(NULL, mib_token, _tlstmParamsTable_row_restore_mib, |
| NULL, NULL); |
| rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY, |
| SNMP_CALLBACK_STORE_DATA, |
| _tlstmParamsTable_save, |
| _table_data->container); |
| |
| if (rc != SNMP_ERR_NOERROR) |
| snmp_log(LOG_ERR, "error registering for STORE_DATA callback " |
| "in _tlstmParams_init_persistence\n"); |
| } |
| |
| static int |
| _tlstmParamsTable_save(int majorID, int minorID, void *serverarg, |
| void *clientarg) |
| { |
| char sep[] = |
| "##############################################################"; |
| char buf[] = "#\n" "# tlstmParams persistent data\n" "#"; |
| char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, |
| NETSNMP_DS_LIB_APPTYPE); |
| |
| netsnmp_container *active_params = netsnmp_tlstmParams_container(); |
| netsnmp_tdata_row *row; |
| netsnmp_iterator *tbl_itr, *params_itr; |
| snmpTlstmParams *params; |
| snmpTlstmParamsTable_entry *entry; |
| |
| if ((CONTAINER_SIZE(active_params) == 0) && |
| (CONTAINER_SIZE(_table_data->container) == 0)) |
| return SNMPERR_SUCCESS; |
| |
| read_config_store((char *) type, sep); |
| read_config_store((char *) type, buf); |
| |
| /* |
| * save active rows from params container |
| */ |
| if (NULL != active_params) { |
| params_itr = CONTAINER_ITERATOR(active_params); |
| if (NULL == params_itr) { |
| DEBUGMSGTL(("tlstmParamsTable:save", |
| "cant get params iterator\n")); |
| params = NULL; |
| } |
| else |
| params = ITERATOR_FIRST(params_itr); |
| |
| for( ; params; params = ITERATOR_NEXT(params_itr)) { |
| /** don't store config rows */ |
| if ((params->flags & TLSTM_PARAMS_FROM_CONFIG) || |
| ! (params->flags & TLSTM_PARAMS_NONVOLATILE)) |
| continue; |
| _save_params(params, type); |
| } |
| } |
| ITERATOR_RELEASE(params_itr); |
| |
| /* |
| * save inactive rows from mib |
| */ |
| tbl_itr = CONTAINER_ITERATOR(_table_data->container); |
| if (NULL == tbl_itr) |
| DEBUGMSGTL(("tlstmParamsTable: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 active_params and thus saved |
| * above) and volatile rows. |
| */ |
| if ((entry->snmpTlstmParamsRowStatus == RS_ACTIVE) || |
| (entry->snmpTlstmParamsStorageType != 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; |
| } |
| |
| /************************************************************ |
| * _tlstmParamsTable_container_row_save |
| */ |
| static int |
| _save_entry(snmpTlstmParamsTable_entry *entry, void *type) |
| { |
| char buf[SNMP_MAXBUF_SMALL], *hashType; |
| |
| 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; |
| } |
| |
| /* |
| * build the line |
| */ |
| netsnmp_assert(0 == entry->snmpTargetParamsName[ |
| entry->snmpTargetParamsName_len]); |
| netsnmp_assert(0 == entry->snmpTlstmParamsClientFingerprint[ |
| entry->snmpTlstmParamsClientFingerprint_len]); |
| snprintf(buf, sizeof(buf), "%s %s %s %s %d", mib_token, |
| entry->snmpTargetParamsName, hashType, |
| entry->snmpTlstmParamsClientFingerprint, |
| entry->snmpTlstmParamsRowStatus); |
| buf[sizeof(buf)-1] = 0; |
| |
| read_config_store(type, buf); |
| DEBUGMSGTL(("tlstmParamsTable:row:save", "saving entry '%s'\n", buf)); |
| |
| return SNMP_ERR_NOERROR; |
| } |
| |
| static int |
| _save_params(snmpTlstmParams *params, void *app_type) |
| { |
| char buf[SNMP_MAXBUF_SMALL], *hashType; |
| |
| if (NULL == params) |
| return SNMP_ERR_GENERR; |
| |
| hashType = se_find_label_in_slist("cert_hash_alg", params->hashType); |
| if (NULL == hashType) { |
| snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n", |
| params->hashType); |
| return SNMP_ERR_GENERR; |
| } |
| snprintf(buf, sizeof(buf), "%s %s --%s %s %d", mib_token, params->name, |
| hashType, params->fingerprint, RS_ACTIVE); |
| |
| DEBUGMSGTL(("tlstmParamsTable:params:save", "saving params '%s'\n", |
| buf)); |
| read_config_store(app_type, buf); |
| |
| return SNMP_ERR_NOERROR; |
| } |
| |
| static void |
| _tlstmParamsTable_row_restore_mib(const char *token, char *buf) |
| { |
| u_char rowStatus; |
| snmpTlstmParams *params; |
| |
| /** need somewhere to save rows */ |
| netsnmp_assert(_table_data && _table_data->container); |
| |
| params = netsnmp_tlstmParams_restore_common(&buf); |
| if (NULL == params) |
| return; |
| |
| if (NULL == buf) { |
| config_perror("incomplete line"); |
| return; |
| } |
| rowStatus = atoi(buf); |
| |
| /* |
| * if row is active, add it to the params 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 == rowStatus) { |
| params->flags = TLSTM_PARAMS_FROM_MIB | TLSTM_PARAMS_NONVOLATILE; |
| |
| if (netsnmp_tlstmParams_add(params) != 0) |
| netsnmp_tlstmParams_free(params); |
| } |
| else { |
| netsnmp_tdata_row *row; |
| snmpTlstmParamsTable_entry *entry; |
| |
| row = snmpTlstmParamsTable_createEntry(_table_data, params->name, |
| strlen(params->name)); |
| if (!row) |
| return; |
| |
| entry = row->data; |
| |
| entry->hashType = params->hashType; |
| strlcpy(entry->snmpTlstmParamsClientFingerprint, params->fingerprint, |
| sizeof(entry->snmpTlstmParamsClientFingerprint)); |
| entry->snmpTlstmParamsClientFingerprint_len = |
| strlen(entry->snmpTlstmParamsClientFingerprint); |
| entry->snmpTlstmParamsStorageType = ST_NONVOLATILE; |
| entry->snmpTlstmParamsRowStatus = rowStatus; |
| netsnmp_tlstmParams_free(params); |
| } |
| } |