📄 vacm_vars.c
字号:
/* * SNMPv3 View-based Access Control Model */#include <config.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_MALLOC_H#include <malloc.h>#endif#include <ctype.h>#include <sys/types.h>#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#if HAVE_NETDB_H#include <netdb.h>#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#include "snmp-tc.h"#include "mibincl.h"#include "read_config.h"#include "agent_read_config.h"#include "system.h"#include "vacm.h"#include "callback.h"#include "agent_registry.h"#include "agent_callbacks.h"#include "vacm_vars.h"#include "util_funcs.h"#ifdef USING_MIBII_SYSORTABLE_MODULE#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#include "sysORTable.h"#endifstatic unsigned int vacmViewSpinLock=0;voidinit_vacm_vars (void) {#ifdef USING_MIBII_SYSORTABLE_MODULE static oid reg[] = {SNMP_OID_SNMPMODULES,16,2,2,1};#endif #define PRIVRW (SNMPV2ANY | 0x5000) struct variable2 vacm_sec2group[] = { {SECURITYGROUP, ASN_OCTET_STR, RWRITE, var_vacm_sec2group, 1, {3}}, {SECURITYSTORAGE, ASN_INTEGER, RWRITE, var_vacm_sec2group, 1, {4}}, {SECURITYSTATUS, ASN_INTEGER, RWRITE, var_vacm_sec2group, 1, {5}}, }; struct variable2 vacm_access[] = { {ACCESSMATCH, ASN_INTEGER, RWRITE, var_vacm_access, 1, {4}}, {ACCESSREAD, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {5}}, {ACCESSWRITE, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {6}}, {ACCESSNOTIFY, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {7}}, {ACCESSSTORAGE, ASN_INTEGER, RWRITE, var_vacm_access, 1, {8}}, {ACCESSSTATUS, ASN_INTEGER, RWRITE, var_vacm_access, 1, {9}}, }; struct variable4 vacm_view[] = { {VACMVIEWSPINLOCK, ASN_INTEGER, RWRITE, var_vacm_view, 1, {1}}, {VIEWMASK, ASN_OCTET_STR, RWRITE, var_vacm_view, 3, {2,1,3}}, {VIEWTYPE, ASN_INTEGER, RWRITE, var_vacm_view, 3, {2,1,4}}, {VIEWSTORAGE, ASN_INTEGER, RWRITE, var_vacm_view, 3, {2,1,5}}, {VIEWSTATUS, ASN_INTEGER, RWRITE, var_vacm_view, 3, {2,1,6}}, };/* Define the OID pointer to the top of the mib tree that we're registering underneath */ oid vacm_sec2group_oid[] = { OID_VACMGROUPENTRY }; oid vacm_access_oid[] = { OID_VACMACCESSENTRY}; oid vacm_view_oid[] = { OID_VACMMIBVIEWS }; /* we need to be called back later */ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, store_vacm, NULL); /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("mibII/vacm:sec2group", vacm_sec2group, variable2, vacm_sec2group_oid); REGISTER_MIB("mibII/vacm:access", vacm_access, variable2, vacm_access_oid); REGISTER_MIB("mibII/vacm:view", vacm_view, variable4, vacm_view_oid); snmpd_register_config_handler("com2sec", vacm_parse_security, vacm_free_security,"name source community"); snmpd_register_config_handler("group", vacm_parse_group, vacm_free_group, "name v1|v2c|usm security"); snmpd_register_config_handler("access", vacm_parse_access, vacm_free_access, "name context model level prefx read write notify"); snmpd_register_config_handler("view", vacm_parse_view, vacm_free_view, "name type subtree [mask]"); snmpd_register_config_handler("rwcommunity", vacm_parse_simple, NULL,"community [default|hostname|network/bits] [oid]"); snmpd_register_config_handler("rocommunity", vacm_parse_simple, NULL,"community [default|hostname|network/bits] [oid]"); snmpd_register_config_handler("rwuser", vacm_parse_simple, NULL,"user [noauth|auth|priv] [oid]"); snmpd_register_config_handler("rouser", vacm_parse_simple, NULL,"user [noauth|auth|priv] [oid]"); snmpd_register_config_handler("vacmView", vacm_parse_config_view, NULL, NULL); snmpd_register_config_handler("vacmGroup", vacm_parse_config_group, NULL, NULL); snmpd_register_config_handler("vacmAccess", vacm_parse_config_access, NULL, NULL); #ifdef USING_MIBII_SYSORTABLE_MODULE register_sysORTable(reg,10,"View-based Access Control Model for SNMP.");#endif /* register ourselves to handle access control */ snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK, vacm_in_view_callback, NULL); snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_INITIAL, vacm_in_view_callback, NULL);}static struct vacm_securityEntry *securityFirst =0, *securityLast =0;#define EXAMPLE_NETWORK "NETWORK"#define EXAMPLE_COMMUNITY "COMMUNITY"void vacm_parse_security (const char *token, char *param){ char *name, *source, *community; const char *mask; char *cp; struct vacm_securityEntry *sp, se; int maskLength, maskBit; struct sockaddr_in *srcIp, *srcMask; char null[] = ""; memset (&se, 0 , sizeof se); name = strtok(param, "\t\n "); if (!name) { config_perror("missing NAME parameter"); return; } source = strtok(NULL, "\t\n "); if (!source) { config_perror("missing SOURCE parameter"); return; } if ( !strncmp( source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) ) { config_perror("Example config NETWORK not properly configured"); return; /* or exit(1); */ } community = strtok(NULL, "\t\n "); if (!community) { config_perror("missing COMMUNITY parameter"); return; } if ( !strncmp( community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY)) ) { config_perror("Example config COMMUNITY not properly configured"); return; /* or exit(1); */ } srcIp = (struct sockaddr_in*)&(se.sourceIp); srcMask = (struct sockaddr_in*)&(se.sourceMask); cp = strchr(source, '/'); if (cp == NULL) cp = null; else *cp++ = 0; mask = cp; if (strcmp("default", source) == 0 || strcmp("0.0.0.0", source) == 0) { memset(&(srcIp->sin_addr), 0, sizeof(struct in_addr)); mask = "0.0.0.0"; } else if ((srcIp->sin_addr.s_addr = inet_addr (source)) == (unsigned) -1) { struct hostent *hp = gethostbyname(source); if (hp != NULL) { memcpy(&(srcIp->sin_addr), hp->h_addr, 4); } else { config_perror ("bad source address"); return; } } if (*mask == 0) memset (&(srcMask->sin_addr), 0xff, sizeof(struct in_addr)); else { if (strchr(mask, '.')) { if ((srcMask->sin_addr.s_addr = inet_addr(mask)) == (unsigned)-1) { config_perror("bad mask"); return; } } else { maskLength = atoi(mask); if (maskLength <= 0 || maskLength > 32) { config_perror("bad mask length"); return; } maskBit = 0x80000000L; srcMask->sin_addr.s_addr = 0; while (maskLength--) { srcMask->sin_addr.s_addr |= maskBit; maskBit >>= 1; } srcMask->sin_addr.s_addr = htonl(srcMask->sin_addr.s_addr); } } if ((srcIp->sin_addr.s_addr & ~srcMask->sin_addr.s_addr) != 0) { config_perror("source/mask mismatch"); return; } if (strlen(name)+1 > sizeof(se.securityName)) { config_perror("security name too long"); return; } if (strlen(community)+1 > sizeof(se.community)) { config_perror("community name too long"); return; } strcpy(se.securityName, name); strcpy(se.community, community); sp = (struct vacm_securityEntry *)malloc (sizeof *sp); if (sp == NULL) { config_perror("memory error"); return; } *sp = se; if (securityFirst != NULL) { securityLast->next = sp; securityLast = sp; } else { securityFirst = securityLast = sp; }}void vacm_free_security (void){ struct vacm_securityEntry *sp; while ((sp = securityFirst)) { securityFirst = sp->next; free(sp); }}void vacm_parse_group (const char *token, char *param){ char *group, *model, *security; int imodel; struct vacm_groupEntry *gp = NULL; group = strtok (param, " \t\n"); model = strtok (NULL, " \t\n"); security = strtok (NULL, " \t\n"); if (group == NULL || *group == 0) { config_perror("missing GROUP parameter"); return; } if (model == NULL || *model == 0) { config_perror("missing MODEL parameter"); return; } if (security == NULL || *security == 0) { config_perror("missing SECURITY parameter"); return; } if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1; else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c; else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM; else if (strcasecmp(model, "any") == 0) { config_perror("bad security model \"any\" should be: v1, v2c or usm - installing anyway"); imodel = SNMP_SEC_MODEL_ANY; } else { config_perror("bad security model, should be: v1, v2c or usm"); return; } if (strlen(security)+1 > sizeof(gp->groupName)) { config_perror("security name too long"); return; } gp = vacm_createGroupEntry(imodel, security); if (!gp) { config_perror("failed to create group entry"); return; } strcpy (gp->groupName, group); gp->storageType = SNMP_STORAGE_PERMANENT; gp->status = SNMP_ROW_ACTIVE; free (gp->reserved); gp->reserved = NULL;}void vacm_free_group (void){ vacm_destroyAllGroupEntries();}void vacm_parse_access (const char *token, char *param){ char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify; int imodel, ilevel, iprefix; struct vacm_accessEntry *ap; name = strtok(param, " \t\n"); if (!name) { config_perror("missing NAME parameter"); return; } context = strtok(NULL, " \t\n"); if (!context) { config_perror("missing CONTEXT parameter"); return; } model = strtok(NULL, " \t\n"); if (!model) { config_perror("missing MODEL parameter"); return; } level = strtok(NULL, " \t\n"); if (!level) { config_perror("missing LEVEL parameter"); return; } prefix = strtok(NULL, " \t\n"); if (!prefix) { config_perror("missing PREFIX parameter"); return; } readView = strtok(NULL, " \t\n"); if (!readView) { config_perror("missing readView parameter"); return; } writeView = strtok(NULL, " \t\n"); if (!writeView) { config_perror("missing writeView parameter"); return; } notify = strtok(NULL, " \t\n"); if (!notify) { config_perror("missing notifyView parameter"); return; } if (strcmp(context, "\"\"") == 0) *context = 0; if (strcasecmp(model, "any") == 0) imodel = SNMP_SEC_MODEL_ANY; else if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1; else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c; else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM; else { config_perror("bad security model (any, v1, v2c, usm)"); return; } if (strcasecmp(level, "noauth") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(level, "noauthnopriv") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(level, "auth") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(level, "authnopriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(level, "priv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else if (strcasecmp(level, "authpriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else { config_perror("bad security level (noauthnopriv, authnopriv, authpriv)"); return; } if (strcmp(prefix,"exact") == 0) iprefix = 1; else if (strcmp(prefix,"prefix") == 0) iprefix = 2; else if (strcmp(prefix,"0") == 0) { config_perror("bad prefix match parameter \"0\", should be: exact or prefix - installing anyway"); iprefix = 1; } else { config_perror("bad prefix match parameter, should be: exact or prefix"); return; } if (strlen(readView)+1 > sizeof(ap->readView)) { config_perror("readView too long"); return; } if (strlen(writeView)+1 > sizeof(ap->writeView)) { config_perror("writeView too long"); return; } if (strlen(notify)+1 > sizeof(ap->notifyView)) { config_perror("notifyView too long"); return; } ap = vacm_createAccessEntry (name, context, imodel, ilevel); if (!ap) { config_perror("failed to create access entry"); return; } strcpy(ap->readView, readView); strcpy(ap->writeView, writeView); strcpy(ap->notifyView, notify); ap->contextMatch = iprefix; ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; free (ap->reserved); ap->reserved = NULL;}void vacm_free_access (void){ vacm_destroyAllAccessEntries();}void vacm_parse_view (const char *token, char *param){ char *name, *type, *subtree, *mask; int inclexcl; struct vacm_viewEntry *vp; oid suboid[MAX_OID_LEN]; size_t suboid_len = 0; u_char viewMask[sizeof (vp->viewMask)]; int i; name = strtok (param, " \t\n"); if (!name) { config_perror("missing NAME parameter"); return; } type = strtok (NULL, " \n\t"); if (!type) { config_perror("missing TYPE parameter"); return; } subtree = strtok(NULL, " \t\n"); if (!subtree) { config_perror("missing SUBTREE parameter"); return; } mask = strtok(NULL, " \t\n"); if (strcmp(type, "included") == 0) inclexcl = SNMP_VIEW_INCLUDED; else if (strcmp(type, "excluded") == 0) inclexcl = SNMP_VIEW_EXCLUDED; else { config_perror("TYPE must be included/excluded?"); return; } suboid_len = MAX_OID_LEN; if (!read_objid(subtree, suboid, &suboid_len)) { config_perror("bad SUBTREE object id");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -