📄 snmpusm.c
字号:
/* * snmpusm.c * * Routines to manipulate a information about a "user" as * defined by the SNMP-USER-BASED-SM-MIB MIB. * * All functions usm_set_usmStateReference_*() return 0 on success, -1 * otherwise. * * !! Tab stops set to 4 in some parts of this file. !! * (Designated on a per function.) */#include <net-snmp/net-snmp-config.h>#include <sys/types.h>#if HAVE_WINSOCK_H#include <winsock.h>#endif#include <stdio.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include <net-snmp/types.h>#include <net-snmp/output_api.h>#include <net-snmp/config_api.h>#include <net-snmp/utilities.h>#include <net-snmp/library/asn1.h>#include <net-snmp/library/snmp_api.h>#include <net-snmp/library/callback.h>#include <net-snmp/library/keytools.h>#include <net-snmp/library/snmpv3.h>#include <net-snmp/library/lcd_time.h>#include <net-snmp/library/scapi.h>#include <net-snmp/library/callback.h>#include <net-snmp/library/snmp_secmod.h>#include <net-snmp/library/snmpusm.h>oid usmNoAuthProtocol[10] = { 1, 3, 6, 1, 6, 3, 10, 1, 1, 1 };oid usmHMACMD5AuthProtocol[10] = { 1, 3, 6, 1, 6, 3, 10, 1, 1, 2 };oid usmHMACSHA1AuthProtocol[10] = { 1, 3, 6, 1, 6, 3, 10, 1, 1, 3 };oid usmNoPrivProtocol[10] = { 1, 3, 6, 1, 6, 3, 10, 1, 2, 1 };oid usmDESPrivProtocol[10] = { 1, 3, 6, 1, 6, 3, 10, 1, 2, 2 };oid usmAES128PrivProtocol[10] = { 1, 3, 6, 1, 4, 1, 8072, 876,876,128 };oid usmAES192PrivProtocol[10] = { 1, 3, 6, 1, 4, 1, 8072, 876,876,192 };oid usmAES256PrivProtocol[10] = { 1, 3, 6, 1, 4, 1, 8072, 876,876,256 };static u_int dummy_etime, dummy_eboot; /* For ISENGINEKNOWN(). *//* * Globals. */static u_int salt_integer;#ifdef HAVE_AESstatic u_int salt_integer64_1, salt_integer64_2;#endif /* * 1/2 of seed for the salt. Cf. RFC2274, Sect 8.1.1.1. */static struct usmUser *noNameUser = NULL;/* * Local storage (LCD) of the default user list. */static struct usmUser *userList = NULL;/* * Prototypes */int usm_check_secLevel_vs_protocols(int level, const oid * authProtocol, u_int authProtocolLen, const oid * privProtocol, u_int privProtocolLen);int usm_calc_offsets(size_t globalDataLen, int secLevel, size_t secEngineIDLen, size_t secNameLen, size_t scopedPduLen, u_long engineboots, long engine_time, size_t * theTotalLength, size_t * authParamsOffset, size_t * privParamsOffset, size_t * dataOffset, size_t * datalen, size_t * msgAuthParmLen, size_t * msgPrivParmLen, size_t * otstlen, size_t * seq_len, size_t * msgSecParmLen);/* * Set a given field of the secStateRef. * * Allocate <len> bytes for type <type> pointed to by ref-><field>. * Then copy in <item> and record its length in ref-><field_len>. * * Return 0 on success, -1 otherwise. */#define MAKE_ENTRY( type, item, len, field, field_len ) \{ \ if (ref == NULL) \ return -1; \ if (ref->field != NULL) { \ SNMP_ZERO(ref->field, ref->field_len); \ SNMP_FREE(ref->field); \ } \ ref->field_len = 0; \ if (len == 0 || item == NULL) { \ return 0; \ } \ if ((ref->field = (type*) malloc (len * sizeof(type))) == NULL) \ { \ return -1; \ } \ \ memcpy (ref->field, item, len * sizeof(type)); \ ref->field_len = len; \ \ return 0; \}struct usmStateReference *usm_malloc_usmStateReference(void){ struct usmStateReference *retval = (struct usmStateReference *) calloc(1, sizeof(struct usmStateReference)); return retval;} /* end usm_malloc_usmStateReference() */voidusm_free_usmStateReference(void *old){ struct usmStateReference *old_ref = (struct usmStateReference *) old; if (old_ref) { SNMP_FREE(old_ref->usr_name); SNMP_FREE(old_ref->usr_engine_id); SNMP_FREE(old_ref->usr_auth_protocol); SNMP_FREE(old_ref->usr_priv_protocol); if (old_ref->usr_auth_key) { SNMP_ZERO(old_ref->usr_auth_key, old_ref->usr_auth_key_length); SNMP_FREE(old_ref->usr_auth_key); } if (old_ref->usr_priv_key) { SNMP_ZERO(old_ref->usr_priv_key, old_ref->usr_priv_key_length); SNMP_FREE(old_ref->usr_priv_key); } SNMP_ZERO(old_ref, sizeof(*old_ref)); SNMP_FREE(old_ref); }} /* end usm_free_usmStateReference() */struct usmUser *usm_get_userList(void){ return userList;}intusm_set_usmStateReference_name(struct usmStateReference *ref, char *name, size_t name_len){ MAKE_ENTRY(char, name, name_len, usr_name, usr_name_length);}intusm_set_usmStateReference_engine_id(struct usmStateReference *ref, u_char * engine_id, size_t engine_id_len){ MAKE_ENTRY(u_char, engine_id, engine_id_len, usr_engine_id, usr_engine_id_length);}intusm_set_usmStateReference_auth_protocol(struct usmStateReference *ref, oid * auth_protocol, size_t auth_protocol_len){ MAKE_ENTRY(oid, auth_protocol, auth_protocol_len, usr_auth_protocol, usr_auth_protocol_length);}intusm_set_usmStateReference_auth_key(struct usmStateReference *ref, u_char * auth_key, size_t auth_key_len){ MAKE_ENTRY(u_char, auth_key, auth_key_len, usr_auth_key, usr_auth_key_length);}intusm_set_usmStateReference_priv_protocol(struct usmStateReference *ref, oid * priv_protocol, size_t priv_protocol_len){ MAKE_ENTRY(oid, priv_protocol, priv_protocol_len, usr_priv_protocol, usr_priv_protocol_length);}intusm_set_usmStateReference_priv_key(struct usmStateReference *ref, u_char * priv_key, size_t priv_key_len){ MAKE_ENTRY(u_char, priv_key, priv_key_len, usr_priv_key, usr_priv_key_length);}intusm_set_usmStateReference_sec_level(struct usmStateReference *ref, int sec_level){ if (ref == NULL) return -1; ref->usr_sec_level = sec_level; return 0;}#ifdef SNMP_TESTING_CODE/*******************************************************************-o-****** * emergency_print * * Parameters: * *field * length * * This is a print routine that is solely included so that it can be * used in gdb. Don't use it as a function, it will be pulled before * a real release of the code. * * tab stop 4 * * XXX fflush() only works on FreeBSD; core dumps on Sun OS's */voidemergency_print(u_char * field, u_int length){ int iindex; int start = 0; int stop = 25; while (start < stop) { for (iindex = start; iindex < stop; iindex++) printf("%02X ", field[iindex]); printf("\n"); start = stop; stop = stop + 25 < length ? stop + 25 : length; } fflush(0);} /* end emergency_print() */#endif /* SNMP_TESTING_CODE *//*******************************************************************-o-****** * asn_predict_int_length * * Parameters: * type (UNUSED) * number * len * * Returns: * Number of bytes necessary to store the ASN.1 encoded value of 'number'. * * * This gives the number of bytes that the ASN.1 encoder (in asn1.c) will * use to encode a particular integer value. * * Returns the length of the integer -- NOT THE HEADER! * * Do this the same way as asn_build_int()... */intasn_predict_int_length(int type, long number, size_t len){ register u_long mask; if (len != sizeof(long)) return -1; mask = ((u_long) 0x1FF) << ((8 * (sizeof(long) - 1)) - 1); /* * mask is 0xFF800000 on a big-endian machine */ while ((((number & mask) == 0) || ((number & mask) == mask)) && len > 1) { len--; number <<= 8; } return len;} /* end asn_predict_length() *//*******************************************************************-o-****** * asn_predict_length * * Parameters: * type * *ptr * u_char_len * * Returns: * Length in bytes: 1 + <n> + <u_char_len>, where * * 1 For the ASN.1 type. * <n> # of bytes to store length of data. * <u_char_len> Length of data associated with ASN.1 type. * * This gives the number of bytes that the ASN.1 encoder (in asn1.c) will * use to encode a particular integer value. This is as broken as the * currently used encoder. * * XXX How is <n> chosen, exactly?? */intasn_predict_length(int type, u_char * ptr, size_t u_char_len){ if (type & ASN_SEQUENCE) return 1 + 3 + u_char_len; if (type & ASN_INTEGER) { u_long value; memcpy(&value, ptr, u_char_len); u_char_len = asn_predict_int_length(type, value, u_char_len); } if (u_char_len < 0x80) return 1 + 1 + u_char_len; else if (u_char_len < 0xFF) return 1 + 2 + u_char_len; else return 1 + 3 + u_char_len;} /* end asn_predict_length() *//*******************************************************************-o-****** * usm_calc_offsets * * Parameters:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -