vacm.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:13k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /*
  2.  * vacm.c
  3.  *
  4.  * SNMPv3 View-based Access Control Model
  5.  */
  6. #include <config.h>
  7. #if HAVE_STDLIB_H
  8. #include <stdlib.h>
  9. #endif
  10. #if HAVE_STRING_H
  11. #include <string.h>
  12. #else
  13. #include <strings.h>
  14. #endif
  15. #if HAVE_UNISTD_H
  16. #include <unistd.h>
  17. #endif
  18. #include <sys/types.h>
  19. #include <stdio.h>
  20. #if TIME_WITH_SYS_TIME
  21. # ifdef WIN32
  22. #  include <sys/timeb.h>
  23. # else
  24. #  include <time.h>
  25. # endif
  26. # include <time.h>
  27. #else
  28. # if HAVE_SYS_TIME_H
  29. #  include <sys/time.h>
  30. # else
  31. #  include <time.h>
  32. # endif
  33. #endif
  34. #if HAVE_WINSOCK_H
  35. #include <ip/socket.h>
  36. #endif
  37. #if HAVE_NETINET_IN_H
  38. #include <netinet/in.h>
  39. #endif
  40. #if HAVE_DMALLOC_H
  41. #include <dmalloc.h>
  42. #endif
  43. #include "asn1.h"
  44. #include "snmp.h"
  45. #include "snmp_api.h"
  46. #include "vacm.h"
  47. #include "snmp_debug.h"
  48. static struct vacm_viewEntry *viewList = NULL, *viewScanPtr = NULL;
  49. static struct vacm_accessEntry *accessList = NULL, *accessScanPtr = NULL;
  50. static struct vacm_groupEntry *groupList = NULL, *groupScanPtr = NULL;
  51. struct vacm_viewEntry *
  52. vacm_getViewEntry(const char *viewName,
  53.   oid *viewSubtree,
  54.   size_t viewSubtreeLen)
  55. {
  56.     struct vacm_viewEntry *vp, *vpret = NULL;
  57.     char view[VACMSTRINGLEN];
  58.     int found, glen;
  59.     glen = (int)strlen(viewName);
  60.     if (glen < 0 || glen >= VACM_MAX_STRING)
  61.         return NULL;
  62.     view[0] = (u_char)glen;
  63.     strcpy(view+1, viewName);
  64.     for(vp = viewList; vp; vp = vp->next){
  65.         if (!memcmp(view, vp->viewName,glen+1)
  66.     && viewSubtreeLen >= vp->viewSubtreeLen) {
  67.     int mask = 0x80, maskpos = 0;
  68.     int oidpos;
  69.             found = 1;
  70.     for (oidpos = 0; found && oidpos < (int)vp->viewSubtreeLen; oidpos++) {
  71. if ((vp->viewMask[maskpos] & mask) != 0) {
  72.     if (viewSubtree[oidpos] != vp->viewSubtree[oidpos])
  73.                         found = 0;
  74. }
  75. if (mask == 1) {
  76.     mask = 0x80;
  77.     maskpos++;
  78. }
  79. else mask >>= 1;
  80.     }
  81.             if (found) {
  82.               /* match successful, keep this node if its longer than
  83.                  the previous or (equal and lexicographically greater
  84.                  than the previous). */
  85.               if (vpret == NULL || vp->viewSubtreeLen > vpret->viewSubtreeLen ||
  86.                   (vp->viewSubtreeLen == vpret->viewSubtreeLen &&
  87.                    snmp_oid_compare(vp->viewSubtree, vp->viewSubtreeLen,
  88.                                     vpret->viewSubtree,
  89.                                     vpret->viewSubtreeLen) > 0))
  90.                 vpret = vp;
  91.             }
  92. }
  93.     }
  94.     DEBUGMSGTL(("vacm:getView", ", %s", (vpret)?"found":"none"));
  95.     return vpret;
  96. }
  97. void
  98. vacm_scanViewInit (void)
  99. {
  100.     viewScanPtr = viewList;
  101. }
  102. struct vacm_viewEntry *
  103. vacm_scanViewNext (void)
  104. {
  105.     struct vacm_viewEntry *returnval = viewScanPtr;
  106.     if (viewScanPtr) viewScanPtr = viewScanPtr->next;
  107.     return returnval;
  108. }
  109. struct vacm_viewEntry *
  110. vacm_createViewEntry(const char *viewName,
  111.      oid *viewSubtree,
  112.      size_t viewSubtreeLen)
  113. {
  114.     struct vacm_viewEntry *vp, *lp, *op = NULL;
  115.     int cmp, glen;
  116.     glen = (int)strlen(viewName);
  117.     if (glen < 0 || glen >= VACM_MAX_STRING)
  118.         return NULL;
  119.     vp = (struct vacm_viewEntry *)calloc(1, sizeof(struct vacm_viewEntry));
  120.     if (vp == NULL)
  121.         return NULL;
  122.     vp->reserved = (struct vacm_viewEntry *)calloc(1, sizeof(struct vacm_viewEntry));
  123.     if (vp->reserved == NULL) {
  124.         free(vp);
  125.         return NULL;
  126.     }
  127.     vp->viewName[0] = (u_char)glen;
  128.     strcpy(vp->viewName+1, viewName);
  129.     memcpy(vp->viewSubtree, viewSubtree, viewSubtreeLen * sizeof(oid));
  130.     vp->viewSubtreeLen = viewSubtreeLen;
  131. vp->viewStatus = SNMP_ROW_NOTINSERVICE;
  132. vp->viewStorageType = SNMP_STORAGE_NONVOLATILE;
  133. vp->viewType = 1;
  134.     lp = viewList;
  135.     while (lp) {
  136. cmp = memcmp(lp->viewName, vp->viewName, glen+1);
  137. if (cmp > 0) break;
  138. if (cmp < 0) goto next;
  139. next:
  140. op = lp;
  141. lp = lp->next;
  142.     }
  143.     vp->next = lp;
  144.     if (op) op->next = vp;
  145.     else viewList = vp;
  146.     return vp;
  147. }
  148. struct vacm_viewEntry *
  149. vacm_findViewEntryByName (const char *viewName)
  150. {
  151.     struct vacm_viewEntry *vp;
  152.     char view[VACMSTRINGLEN];
  153. int glen;
  154.     glen = (int)strlen(viewName);
  155.     if (glen < 0 || glen >= VACM_MAX_STRING)
  156.         return NULL;
  157.     view[0] = (u_char)glen;
  158.     strcpy(view+1, viewName);
  159. for (vp = viewList; vp; vp = vp->next)
  160. {
  161. if (!memcmp(view, vp->viewName,glen+1))
  162. return vp;
  163. }
  164. return NULL;
  165. }
  166. BOOL vacm_walkThrViewEntry (void (*thrMethod)(struct vacm_viewEntry*))
  167. {
  168. struct vacm_viewEntry *vp;
  169. if (viewList == NULL)
  170. return FALSE;
  171. for (vp = viewList; vp != NULL; vp = vp->next)
  172. {
  173. if (strstr (vp->viewName, "__vn") == NULL)
  174. thrMethod (vp);
  175. }
  176. return TRUE;
  177. }
  178. void
  179. vacm_destroyViewEntry(const char *viewName,
  180.       oid *viewSubtree,
  181.       size_t viewSubtreeLen)
  182. {
  183.     struct vacm_viewEntry *vp, *lastvp = NULL;
  184.     if (viewList && !strcmp(viewList->viewName+1, viewName)
  185. && viewList->viewSubtreeLen == viewSubtreeLen
  186. && !memcmp((char *)viewList->viewSubtree, (char *)viewSubtree,
  187.  viewSubtreeLen * sizeof(oid))){
  188. vp = viewList;
  189. viewList = viewList->next;
  190.     } else {
  191. for (vp = viewList; vp; vp = vp->next){
  192.     if (!strcmp(vp->viewName+1, viewName)
  193. && vp->viewSubtreeLen  == viewSubtreeLen 
  194. && !memcmp((char *)vp->viewSubtree, (char *)viewSubtree,
  195.  viewSubtreeLen * sizeof(oid)))
  196. break;
  197.     lastvp = vp;
  198. }
  199. if (!vp)
  200.     return;
  201. lastvp->next = vp->next;
  202.     }
  203.     if (vp->reserved)
  204. free(vp->reserved);
  205.     free(vp);
  206.     return;
  207. }
  208. void vacm_destroyAllViewEntries (void)
  209. {
  210.     struct vacm_viewEntry *vp;
  211.     while ((vp = viewList)) {
  212. viewList = vp->next;
  213. if (vp->reserved) free(vp->reserved);
  214. free(vp);
  215.     }
  216. }
  217. struct vacm_groupEntry *
  218. vacm_getGroupEntry(int securityModel,
  219.    const char *securityName)
  220. {
  221.     struct vacm_groupEntry *vp;
  222.     char secname[VACMSTRINGLEN];
  223.     int glen;
  224.     glen = (int)strlen(securityName);
  225.     if (glen < 0 || glen >= VACM_MAX_STRING)
  226.         return NULL;
  227.     secname[0] = (u_char)glen;
  228.     strcpy(secname+1, securityName);
  229.     for (vp = groupList; vp; vp = vp->next) {
  230. if ((securityModel == vp->securityModel || vp->securityModel == SNMP_SEC_MODEL_ANY)
  231.     && !memcmp(vp->securityName, secname,glen+1))
  232. return vp;
  233.     }
  234.     return NULL;
  235. }
  236. void
  237. vacm_scanGroupInit (void)
  238. {
  239.     groupScanPtr = groupList;
  240. }
  241. struct vacm_groupEntry *
  242. vacm_scanGroupNext (void)
  243. {
  244.     struct vacm_groupEntry *returnval = groupScanPtr;
  245.     if (groupScanPtr) groupScanPtr = groupScanPtr->next;
  246.     return returnval;
  247. }
  248. struct vacm_groupEntry *
  249. vacm_createGroupEntry(int securityModel,
  250.       const char *securityName)
  251. {
  252.     struct vacm_groupEntry *gp, *lg, *og;
  253.     int cmp, glen;
  254.     glen = (int)strlen(securityName);
  255.     if (glen < 0 || glen >= VACM_MAX_STRING)
  256.         return NULL;
  257.     gp = (struct vacm_groupEntry *)calloc(1, sizeof(struct vacm_groupEntry));
  258.     if (gp == NULL)
  259.         return NULL;
  260.     gp->reserved = (struct vacm_groupEntry *)calloc(1, sizeof(struct vacm_groupEntry));
  261.     if (gp->reserved == NULL) {
  262.         free(gp);
  263.         return NULL;
  264.     }
  265.     gp->securityModel = securityModel;
  266.     gp->securityName[0] = (u_char)glen;
  267. gp->status = SNMP_ROW_NOTREADY;
  268. gp->storageType = SNMP_STORAGE_OTHER;
  269.     strcpy(gp->securityName+1, securityName);
  270.     lg = groupList;
  271.     og = NULL;
  272.     while (lg) {
  273. if (lg->securityModel > securityModel) break;
  274. if (lg->securityModel == securityModel && 
  275.     (cmp = memcmp(lg->securityName, gp->securityName, glen+1)) > 0) break;
  276. /* if (lg->securityModel == securityModel && cmp == 0) abort(); */
  277. og = lg; lg = lg->next;
  278.     }
  279.     gp->next = lg;
  280.     if (og == NULL) groupList = gp;
  281.     else og->next = gp;
  282.     return gp;
  283. }
  284. void
  285. vacm_destroyGroupEntry(int securityModel,
  286.        const char *securityName)
  287. {
  288.     struct vacm_groupEntry *vp, *lastvp = NULL;
  289.     if (groupList && groupList->securityModel == securityModel
  290. && !strcmp(groupList->securityName+1, securityName)) {
  291. vp = groupList;
  292. groupList = groupList->next;
  293.     } else {
  294. for (vp = groupList; vp; vp = vp->next){
  295.     if (vp->securityModel == securityModel
  296. && !strcmp(vp->securityName+1, securityName))
  297. break;
  298.     lastvp = vp;
  299. }
  300. if (!vp)
  301.     return;
  302. lastvp->next = vp->next;
  303.     }
  304.     if (vp->reserved)
  305. free(vp->reserved);
  306.     free(vp);
  307.     return;
  308. }
  309. void vacm_destroyAllGroupEntries (void)
  310. {
  311.     struct vacm_groupEntry *gp;
  312.     while ((gp = groupList)) {
  313. groupList = gp->next;
  314. if (gp->reserved) free(gp->reserved);
  315. free(gp);
  316.     }
  317. }
  318. BOOL vacm_walkThrAccessEntry (void (*thrMethod)(struct vacm_accessEntry*))
  319. {
  320. struct vacm_accessEntry *va;
  321. if (accessList == NULL)
  322. return FALSE;
  323. for (va = accessList; va != NULL; va = va->next)
  324. {
  325. if (strstr (va->groupName, "__gn") == NULL)
  326.      thrMethod (va);
  327. }
  328. return TRUE;
  329. }
  330. struct vacm_accessEntry *
  331. vacm_getAccessEntry(const char *groupName, 
  332.     const char *contextPrefix,
  333.     int securityModel, 
  334.     int securityLevel)
  335. {
  336.     struct vacm_accessEntry *vp;
  337.     char group[VACMSTRINGLEN];
  338.     char context[VACMSTRINGLEN];
  339.     int glen, clen;
  340.     glen = (int)strlen(groupName);
  341.     if (glen < 0 || glen >= VACM_MAX_STRING)
  342.         return NULL;
  343.     clen = (int)strlen(contextPrefix);
  344.     if (clen < 0 || clen >= VACM_MAX_STRING)
  345.         return NULL;
  346.     group[0] = (u_char)glen;
  347.     strcpy(group+1, groupName);
  348.     context[0] = (u_char)clen;
  349.     strcpy(context+1, contextPrefix);
  350.     for(vp = accessList; vp; vp = vp->next){
  351.         if ((securityModel == vp->securityModel || vp->securityModel == SNMP_SEC_MODEL_ANY)
  352.     && securityLevel >= vp->securityLevel
  353.     && !memcmp(vp->groupName, group, glen+1)
  354.     && !memcmp(vp->contextPrefix, context, clen+1))
  355.   return vp;
  356.     }
  357.     return NULL;
  358. }
  359. void
  360. vacm_scanAccessInit (void)
  361. {
  362.     accessScanPtr = accessList;
  363. }
  364. struct vacm_accessEntry *
  365. vacm_scanAccessNext (void)
  366. {
  367.     struct vacm_accessEntry *returnval = accessScanPtr;
  368.     if (accessScanPtr) accessScanPtr = accessScanPtr->next;
  369.     return returnval;
  370. }
  371. struct vacm_accessEntry *
  372. vacm_createAccessEntry(const char *groupName, 
  373.        const char *contextPrefix,
  374.        int securityModel, 
  375.        int securityLevel)
  376. {
  377.     struct vacm_accessEntry *vp, *lp, *op = NULL;
  378.     int cmp, glen, clen;
  379.     glen = (int)strlen(groupName);
  380.     if (glen < 0 || glen >= VACM_MAX_STRING)
  381.         return NULL;
  382.     clen = (int)strlen(contextPrefix);
  383.     if (clen < 0 || clen >= VACM_MAX_STRING)
  384.         return NULL;
  385.     vp = (struct vacm_accessEntry *)calloc(1, sizeof(struct vacm_accessEntry));
  386.     if (vp == NULL)
  387.         return NULL;
  388.     vp->reserved = (struct vacm_accessEntry *)calloc(1, sizeof(struct vacm_accessEntry));
  389.     if (vp->reserved == NULL) {
  390.         free(vp);
  391.         return NULL;
  392.     }
  393.     vp->securityModel = securityModel;
  394.     vp->securityLevel = securityLevel;
  395.     vp->groupName[0] = (u_char)glen;
  396.     strcpy(vp->groupName+1, groupName);
  397.     vp->contextPrefix[0] = (u_char)clen;
  398.     strcpy(vp->contextPrefix+1, contextPrefix);
  399. vp->status = SNMP_ROW_NOTREADY;
  400. vp->storageType = SNMP_STORAGE_OTHER;
  401.     lp = accessList;
  402.     while (lp) {
  403. cmp = memcmp(lp->groupName, vp->groupName, glen+1);
  404. if (cmp > 0) break;
  405. if (cmp < 0) goto next;
  406. cmp = memcmp(lp->contextPrefix, vp->contextPrefix, clen+1);
  407. if (cmp > 0) break;
  408. if (cmp < 0) goto next;
  409. if (lp->securityModel > securityModel) break;
  410. if (lp->securityModel < securityModel) goto next;
  411. if (lp->securityLevel > securityLevel) break;
  412. next:
  413. op = lp;
  414. lp = lp->next;
  415.     }
  416.     vp->next = lp;
  417.     if (op == NULL) accessList = vp;
  418.     else op->next = vp;
  419.     return vp;
  420. }
  421. void
  422. vacm_destroyAccessEntry(const char *groupName, 
  423. const char *contextPrefix,
  424. int securityModel,
  425. int securityLevel)
  426. {
  427.     struct vacm_accessEntry *vp, *lastvp = NULL;
  428.     if (accessList && accessList->securityModel == securityModel
  429. && accessList->securityModel == securityModel
  430. && !strcmp(accessList->groupName+1, groupName)
  431. && !strcmp(accessList->contextPrefix+1, contextPrefix)) {
  432. vp = accessList;
  433. accessList = accessList->next;
  434.     } else {
  435. for (vp = accessList; vp; vp = vp->next){
  436.     if (vp->securityModel == securityModel
  437. && vp->securityLevel == securityLevel
  438. && !strcmp(vp->groupName+1, groupName)
  439. && !strcmp(vp->contextPrefix+1, contextPrefix))
  440. break;
  441.     lastvp = vp;
  442. }
  443. if (!vp)
  444.     return;
  445. lastvp->next = vp->next;
  446.     }
  447.     if (vp->reserved)
  448. free(vp->reserved);
  449.     free(vp);
  450.     return;
  451. }
  452. void vacm_destroyAllAccessEntries (void)
  453. {
  454.     struct vacm_accessEntry *ap;
  455.     while ((ap = accessList)) {
  456. accessList = ap->next;
  457. if (ap->reserved) free(ap->reserved);
  458. free(ap);
  459.     }
  460. }
  461. /* returns 1 if vacm has *any* configuration entries in it (regardless
  462.    of weather or not there is enough to make a decision based on it),
  463.    else return 0 */
  464. int vacm_is_configured(void) {
  465.     if (viewList == NULL && accessList == NULL && groupList == NULL)
  466.         return 0;
  467.     return 1;
  468. }