1 // This file is part of eCos, the Embedded Configurable Operating System.
2 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
4 // eCos is free software; you can redistribute it and/or modify it under
5 // the terms of the GNU General Public License as published by the Free
6 // Software Foundation; either version 2 or (at your option) any later version.
8 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
9 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // You should have received a copy of the GNU General Public License along
14 // with eCos; if not, write to the Free Software Foundation, Inc.,
15 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 // As a special exception, if other files instantiate templates or use macros
18 // or inline functions from this file, or you compile this file and link it
19 // with other works to produce a work based on this file, this file does not
20 // by itself cause the resulting work to be covered by the GNU General Public
21 // License. However the source code for this file must still be made available
22 // in accordance with section (3) of the GNU General Public License.
24 // This exception does not invalidate any other reasons why a work based on
25 // this file might be covered by the GNU General Public License.
27 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
28 // at http://sources.redhat.com/ecos/ecos-license/
29 // -------------------------------------------
30 //####ECOSGPLCOPYRIGHTEND####
31 //####UCDSNMPCOPYRIGHTBEGIN####
33 // -------------------------------------------
35 // Portions of this software may have been derived from the UCD-SNMP
36 // project, <http://ucd-snmp.ucdavis.edu/> from the University of
37 // California at Davis, which was originally based on the Carnegie Mellon
38 // University SNMP implementation. Portions of this software are therefore
39 // covered by the appropriate copyright disclaimers included herein.
41 // The release used was version 4.1.2 of May 2000. "ucd-snmp-4.1.2"
42 // -------------------------------------------
44 //####UCDSNMPCOPYRIGHTEND####
45 //==========================================================================
46 //#####DESCRIPTIONBEGIN####
48 // Author(s): Manu Sharma
51 // Purpose: Port of UCD-SNMP distribution to eCos.
55 //####DESCRIPTIONEND####
57 //==========================================================================
58 /********************************************************************
59 Copyright 1989, 1991, 1992 by Carnegie Mellon University
62 Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
66 Permission to use, copy, modify and distribute this software and its
67 documentation for any purpose and without fee is hereby granted,
68 provided that the above copyright notice appears in all copies and
69 that both that copyright notice and this permission notice appear in
70 supporting documentation, and that the name of CMU and The Regents of
71 the University of California not be used in advertising or publicity
72 pertaining to distribution of the software without specific written
75 CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
76 WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
77 WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CMU OR
78 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
79 INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
80 FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
81 CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
82 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
83 *********************************************************************/
87 * SNMPv3 View-based Access Control Model
89 /***********************************************************
90 Copyright 1988, 1989 by Carnegie Mellon University
94 Permission to use, copy, modify, and distribute this software and its
95 documentation for any purpose and without fee is hereby granted,
96 provided that the above copyright notice appear in all copies and that
97 both that copyright notice and this permission notice appear in
98 supporting documentation, and that the name of CMU not be
99 used in advertising or publicity pertaining to distribution of the
100 software without specific, written prior permission.
102 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
103 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
104 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
105 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
106 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
107 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
109 ******************************************************************/
113 #ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
114 #ifdef CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT
131 #include <sys/types.h>
132 #if HAVE_NETINET_IN_H
133 #include <netinet/in.h>
136 #include <arpa/inet.h>
151 #include "read_config.h"
152 #include "agent_read_config.h"
155 #include "callback.h"
156 #include "agent_registry.h"
157 #include "agent_callbacks.h"
158 #include "vacm_vars.h"
160 #ifdef USING_MIBII_SYSORTABLE_MODULE
161 #if TIME_WITH_SYS_TIME
163 # include <sys/timeb.h>
165 # include <sys/time.h>
170 # include <sys/time.h>
175 #include <mibgroup/mibII/sysORTable.h>
179 init_vacm_vars (void)
182 #ifdef USING_MIBII_SYSORTABLE_MODULE
183 static oid reg[] = {SNMP_OID_SNMPMODULES,16,2,2,1};
186 #define PRIVRW (SNMPV2ANY | 0x5000)
188 struct variable2 vacm_sec2group[] = {
189 {SECURITYGROUP, ASN_OCTET_STR, PRIVRW, var_vacm_sec2group, 1, {3}},
190 {SECURITYSTORAGE, ASN_INTEGER, PRIVRW, var_vacm_sec2group, 1, {4}},
191 {SECURITYSTATUS, ASN_INTEGER, PRIVRW, var_vacm_sec2group, 1, {5}},
194 struct variable2 vacm_access[] = {
195 {ACCESSMATCH, ASN_INTEGER, PRIVRW, var_vacm_access, 1, {4}},
196 {ACCESSREAD, ASN_OCTET_STR, PRIVRW, var_vacm_access, 1, {5}},
197 {ACCESSWRITE, ASN_OCTET_STR, PRIVRW, var_vacm_access, 1, {6}},
198 {ACCESSNOTIFY, ASN_OCTET_STR, PRIVRW, var_vacm_access, 1, {7}},
199 {ACCESSSTORAGE, ASN_INTEGER, PRIVRW, var_vacm_access, 1, {8}},
200 {ACCESSSTATUS, ASN_INTEGER, PRIVRW, var_vacm_access, 1, {9}},
203 struct variable2 vacm_view[] = {
204 {VIEWMASK, ASN_OCTET_STR, PRIVRW, var_vacm_view, 1, {3}},
205 {VIEWTYPE, ASN_INTEGER, PRIVRW, var_vacm_view, 1, {4}},
206 {VIEWSTORAGE, ASN_INTEGER, PRIVRW, var_vacm_view, 1, {5}},
207 {VIEWSTATUS, ASN_INTEGER, PRIVRW, var_vacm_view, 1, {6}},
210 /* Define the OID pointer to the top of the mib tree that we're
211 registering underneath */
212 oid vacm_sec2group_oid[] = { OID_VACMGROUPENTRY };
213 oid vacm_access_oid[] = { OID_VACMACCESSENTRY};
214 oid vacm_view_oid[] = { OID_VACMVIEWENTRY };
216 /* register ourselves with the agent to handle our mib tree */
217 REGISTER_MIB("mibII/vacm:sec2group", vacm_sec2group, variable2, \
219 REGISTER_MIB("mibII/vacm:access", vacm_access, variable2, vacm_access_oid);
220 REGISTER_MIB("mibII/vacm:view", vacm_view, variable2, vacm_view_oid);
222 snmpd_register_config_handler("com2sec", vacm_parse_security,
223 vacm_free_security,"name source community");
224 snmpd_register_config_handler("group", vacm_parse_group, vacm_free_group,
225 "name v1|v2c|usm security");
226 snmpd_register_config_handler("access", vacm_parse_access, vacm_free_access,
227 "name context model level prefx read write notify");
228 snmpd_register_config_handler("view", vacm_parse_view, vacm_free_view,
229 "name type subtree [mask]");
230 snmpd_register_config_handler("rwcommunity", vacm_parse_simple,
231 NULL,"community [default|hostname|network/bits] [oid]");
232 snmpd_register_config_handler("rocommunity", vacm_parse_simple,
233 NULL,"community [default|hostname|network/bits] [oid]");
234 snmpd_register_config_handler("rwuser", vacm_parse_simple,
235 NULL,"user [noauth|auth|priv] [oid]");
236 snmpd_register_config_handler("rouser", vacm_parse_simple,
237 NULL,"user [noauth|auth|priv] [oid]");
239 #ifdef USING_MIBII_SYSORTABLE_MODULE
240 register_sysORTable(reg,10,"View-based Access Control Model for SNMP.");
243 /* register ourselves to handle access control */
244 snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
245 vacm_in_view_callback, NULL);
246 snmp_register_callback(SNMP_CALLBACK_APPLICATION,
247 SNMPD_CALLBACK_ACM_CHECK_INITIAL,
248 vacm_in_view_callback, NULL);
251 static struct vacm_securityEntry *securityFirst =0, *securityLast =0;
253 #define EXAMPLE_NETWORK "NETWORK"
254 #define EXAMPLE_COMMUNITY "COMMUNITY"
256 void vacm_parse_security (const char *token,
259 char *name, *source, *community;
262 struct vacm_securityEntry *sp, se;
263 int maskLength, maskBit;
264 struct sockaddr_in *srcIp, *srcMask;
267 memset (&se, 0 , sizeof se);
268 name = strtok(param, "\t\n ");
270 config_perror("missing NAME parameter");
273 source = strtok(NULL, "\t\n ");
275 config_perror("missing SOURCE parameter");
278 if ( !strncmp( source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) ) {
279 config_perror("Example config NETWORK not properly configured");
280 return; /* or exit(1); */
282 community = strtok(NULL, "\t\n ");
284 config_perror("missing COMMUNITY parameter");
287 if ( !strncmp( community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY)) ) {
288 config_perror("Example config COMMUNITY not properly configured");
289 return; /* or exit(1); */
291 srcIp = (struct sockaddr_in*)&(se.sourceIp);
292 srcMask = (struct sockaddr_in*)&(se.sourceMask);
293 cp = strchr(source, '/');
294 if (cp == NULL) cp = null;
297 if (strcmp("default", source) == 0 || strcmp("0.0.0.0", source) == 0) {
298 memset(&(srcIp->sin_addr), 0, sizeof(struct in_addr));
301 else if ((srcIp->sin_addr.s_addr = inet_addr (source)) == (unsigned) -1) {
302 struct hostent *hp = gethostbyname(source);
304 memcpy(&(srcIp->sin_addr), hp->h_addr, 4);
307 config_perror ("bad source address");
311 if (*mask == 0) memset (&(srcMask->sin_addr), 0xff, sizeof(struct in_addr));
313 if (strchr(mask, '.')) {
314 if ((srcMask->sin_addr.s_addr = inet_addr(mask)) == (unsigned)-1) {
315 config_perror("bad mask");
320 maskLength = atoi(mask);
321 if (maskLength <= 0 || maskLength > 32) {
322 config_perror("bad mask length");
325 maskBit = 0x80000000L;
326 srcMask->sin_addr.s_addr = 0;
327 while (maskLength--) {
328 srcMask->sin_addr.s_addr |= maskBit;
331 srcMask->sin_addr.s_addr = htonl(srcMask->sin_addr.s_addr);
334 if ((srcIp->sin_addr.s_addr & ~srcMask->sin_addr.s_addr) != 0) {
335 config_perror("source/mask mismatch");
338 if (strlen(name)+1 > sizeof(se.securityName)) {
339 config_perror("security name too long");
342 if (strlen(community)+1 > sizeof(se.community)) {
343 config_perror("community name too long");
346 strcpy(se.securityName, name);
347 strcpy(se.community, community);
348 sp = (struct vacm_securityEntry *)malloc (sizeof *sp);
350 config_perror("memory error");
354 if (securityFirst != NULL) {
355 securityLast->next = sp;
359 securityFirst = securityLast = sp;
363 void vacm_free_security (void)
365 struct vacm_securityEntry *sp;
366 while ((sp = securityFirst)) {
367 securityFirst = sp->next;
372 void vacm_parse_group (const char *token,
375 char *group, *model, *security;
377 struct vacm_groupEntry *gp = NULL;
379 group = strtok (param, " \t\n");
380 model = strtok (NULL, " \t\n");
381 security = strtok (NULL, " \t\n");
383 if (group == NULL || *group == 0) {
384 config_perror("missing GROUP parameter");
387 if (model == NULL || *model == 0) {
388 config_perror("missing MODEL parameter");
391 if (security == NULL || *security == 0) {
392 config_perror("missing SECURITY parameter");
395 if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1;
396 else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c;
397 else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM;
398 else if (strcasecmp(model, "any") == 0) {
399 config_perror("bad security model \"any\" should be: v1, v2c or usm - installing anyway");
400 imodel = SNMP_SEC_MODEL_ANY;
403 config_perror("bad security model, should be: v1, v2c or usm");
406 if (strlen(security)+1 > sizeof(gp->groupName)) {
407 config_perror("security name too long");
410 gp = vacm_createGroupEntry(imodel, security);
412 config_perror("failed to create group entry");
415 strcpy (gp->groupName, group);
416 gp->storageType = SNMP_STORAGE_PERMANENT;
417 gp->status = SNMP_ROW_ACTIVE;
422 void vacm_free_group (void)
424 vacm_destroyAllGroupEntries();
427 void vacm_parse_access (const char *token, char *param)
429 char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify;
430 int imodel, ilevel, iprefix;
431 struct vacm_accessEntry *ap;
433 name = strtok(param, " \t\n");
435 config_perror("missing NAME parameter");
438 context = strtok(NULL, " \t\n");
440 config_perror("missing CONTEXT parameter");
443 model = strtok(NULL, " \t\n");
445 config_perror("missing MODEL parameter");
448 level = strtok(NULL, " \t\n");
450 config_perror("missing LEVEL parameter");
453 prefix = strtok(NULL, " \t\n");
455 config_perror("missing PREFIX parameter");
458 readView = strtok(NULL, " \t\n");
460 config_perror("missing readView parameter");
463 writeView = strtok(NULL, " \t\n");
465 config_perror("missing writeView parameter");
468 notify = strtok(NULL, " \t\n");
470 config_perror("missing notifyView parameter");
473 if (strcmp(context, "\"\"") == 0) *context = 0;
474 if (strcasecmp(model, "any") == 0) imodel = SNMP_SEC_MODEL_ANY;
475 else if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1;
476 else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c;
477 else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM;
479 config_perror("bad security model (any, v1, v2c, usm)");
482 if (strcasecmp(level, "noauth") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH;
483 else if (strcasecmp(level, "noauthnopriv") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH;
484 else if (strcasecmp(level, "auth") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
485 else if (strcasecmp(level, "authnopriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
486 else if (strcasecmp(level, "priv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV;
487 else if (strcasecmp(level, "authpriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV;
489 config_perror("bad security level (noauthnopriv, authnopriv, authpriv)");
492 if (strcmp(prefix,"exact") == 0) iprefix = 1;
493 else if (strcmp(prefix,"prefix") == 0) iprefix = 2;
494 else if (strcmp(prefix,"0") == 0) {
495 config_perror("bad prefix match parameter \"0\", should be: exact or prefix - installing anyway");
499 config_perror("bad prefix match parameter, should be: exact or prefix");
502 if (strlen(readView)+1 > sizeof(ap->readView)) {
503 config_perror("readView too long");
506 if (strlen(writeView)+1 > sizeof(ap->writeView)) {
507 config_perror("writeView too long");
510 if (strlen(notify)+1 > sizeof(ap->notifyView)) {
511 config_perror("notifyView too long");
514 ap = vacm_createAccessEntry (name, context, imodel, ilevel);
516 config_perror("failed to create access entry");
519 strcpy(ap->readView, readView);
520 strcpy(ap->writeView, writeView);
521 strcpy(ap->notifyView, notify);
522 ap->contextMatch = iprefix;
523 ap->storageType = SNMP_STORAGE_PERMANENT;
524 ap->status = SNMP_ROW_ACTIVE;
529 void vacm_free_access (void)
531 vacm_destroyAllAccessEntries();
534 void vacm_parse_view (const char *token,
537 char *name, *type, *subtree, *mask;
539 struct vacm_viewEntry *vp;
540 oid suboid[MAX_OID_LEN];
541 size_t suboid_len = 0;
542 u_char viewMask[sizeof (vp->viewMask)];
545 name = strtok (param, " \t\n");
547 config_perror("missing NAME parameter");
550 type = strtok (NULL, " \n\t");
552 config_perror("missing TYPE parameter");
555 subtree = strtok(NULL, " \t\n");
557 config_perror("missing SUBTREE parameter");
560 mask = strtok(NULL, " \t\n");
562 if (strcmp(type, "included") == 0) inclexcl = SNMP_VIEW_INCLUDED;
563 else if (strcmp(type, "excluded") == 0) inclexcl = SNMP_VIEW_EXCLUDED;
565 config_perror("TYPE must be included/excluded?");
568 suboid_len = MAX_OID_LEN;
569 if (!read_objid(subtree, suboid, &suboid_len)) {
570 config_perror("bad SUBTREE object id");
576 for (mask = strtok(mask, ".:"); mask; mask = strtok(NULL, ".:")) {
577 if (i >= sizeof(viewMask)) {
578 config_perror("MASK too long");
581 if (sscanf(mask, "%x", &val) == 0) {
582 config_perror("invalid MASK");
590 for (i = 0; i < sizeof(viewMask); i++)
593 vp = vacm_createViewEntry(name, suboid, suboid_len);
595 config_perror("failed to create view entry");
598 memcpy(vp->viewMask, viewMask, sizeof(viewMask));
599 vp->viewType = inclexcl;
600 vp->viewStorageType = SNMP_STORAGE_PERMANENT;
601 vp->viewStatus = SNMP_ROW_ACTIVE;
606 void vacm_free_view (void)
608 vacm_destroyAllViewEntries();
611 void vacm_parse_simple(const char *token, char *confline) {
612 char line[SPRINT_MAX_LEN];
613 char community[COMMUNITY_MAX_LEN];
614 char theoid[SPRINT_MAX_LEN];
615 char viewname[SPRINT_MAX_LEN];
616 char addressname[SPRINT_MAX_LEN];
617 const char *rw = "none";
618 const char *model = "any";
621 char secname[SPRINT_MAX_LEN];
622 char authtype[SPRINT_MAX_LEN];
624 /* community name or user name */
625 cp = copy_word(confline, community);
627 if (strcmp(token,"rouser") == 0 || strcmp(token,"rwuser") == 0) {
628 /* authentication type */
630 cp = copy_word(cp, authtype);
632 strcpy(authtype, "auth");
633 DEBUGMSGTL((token, "setting auth type: \"%s\"\n",authtype));
638 cp = copy_word(cp, addressname);
640 strcpy(addressname, "default");
642 /* authtype has to be noauth */
643 strcpy(authtype, "noauth");
646 /* oid they can touch */
648 cp = copy_word(cp, theoid);
650 strcpy(theoid, ".1");
653 if (strcmp(token,"rwcommunity") == 0 || strcmp(token,"rwuser") == 0)
656 if (strcmp(token,"rwcommunity") == 0 || strcmp(token,"rocommunity") == 0) {
657 /* com2sec mapping */
658 /* com2sec anonymousSecNameNUM ADDRESS COMMUNITY */
659 sprintf(secname, "anonymousSecName%03d", num);
660 sprintf(line,"%s %s %s", secname, addressname, community);
661 DEBUGMSGTL((token,"passing: %s %s\n", "com2sec", line));
662 vacm_parse_security("com2sec",line);
664 /* sec->group mapping */
665 /* group anonymousGroupNameNUM any anonymousSecNameNUM */
666 sprintf(line,"anonymousGroupName%03d v1 %s", num, secname);
667 DEBUGMSGTL((token,"passing: %s %s\n", "group", line));
668 vacm_parse_group("group",line);
669 sprintf(line,"anonymousGroupName%03d v2c %s", num, secname);
670 DEBUGMSGTL((token,"passing: %s %s\n", "group", line));
671 vacm_parse_group("group",line);
673 strcpy(secname, community);
675 /* sec->group mapping */
676 /* group anonymousGroupNameNUM any anonymousSecNameNUM */
677 sprintf(line,"anonymousGroupName%03d usm %s", num, secname);
678 DEBUGMSGTL((token,"passing: %s %s\n", "group", line));
679 vacm_parse_group("group",line);
683 /* view definition */
684 /* view anonymousViewNUM included OID */
685 sprintf(viewname,"anonymousView%03d",num);
686 sprintf(line,"%s included %s", viewname, theoid);
687 DEBUGMSGTL((token,"passing: %s %s\n", "view", line));
688 vacm_parse_view("view",line);
690 /* map everything together */
691 /* access anonymousGroupNameNUM "" MODEL AUTHTYPE exact anonymousViewNUM [none/anonymousViewNUM] [none/anonymousViewNUM] */
692 sprintf(line, "anonymousGroupName%03d \"\" %s %s exact %s %s %s", num,
693 model, authtype, viewname, rw, rw);
694 DEBUGMSGTL((token,"passing: %s %s\n", "access", line));
695 vacm_parse_access("access",line);
700 vacm_in_view_callback(int majorID, int minorID, void *serverarg,
702 struct view_parameters *view_parms = (struct view_parameters *) serverarg;
705 if (view_parms == NULL)
707 retval = vacm_in_view(view_parms->pdu, view_parms->name,
708 view_parms->namelen);
710 view_parms->errorcode = retval;
715 /*******************************************************************-o-******
725 * 1 Missing security name.
731 * Debug output listed as follows:
732 * <securityName> <groupName> <viewName> <viewType>
734 int vacm_in_view (struct snmp_pdu *pdu,
738 struct vacm_securityEntry *sp = securityFirst;
739 struct vacm_accessEntry *ap;
740 struct vacm_groupEntry *gp;
741 struct vacm_viewEntry *vp;
742 struct sockaddr_in *pduIp = (struct sockaddr_in*)&(pdu->address);
743 struct sockaddr_in *srcIp, *srcMask;
747 if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) {
748 if (snmp_get_do_debugging()) {
750 if (pdu->community) {
751 buf = malloc(1+ pdu->community_len);
752 memcpy(buf, pdu->community, pdu->community_len);
753 buf[pdu->community_len] = '\0';
755 DEBUGMSGTL(("mibII/vacm_vars", "NULL community"));
756 buf = strdup("NULL");
759 DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: ver=%d, source=%.8x, community=%s\n", pdu->version, pduIp->sin_addr.s_addr, buf));
763 /* allow running without snmpd.conf */
764 if (sp == NULL && !vacm_is_configured()) {
765 DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: accepted with no com2sec entries\n"));
766 switch (pdu->command) {
768 case SNMP_MSG_GETNEXT:
769 case SNMP_MSG_GETBULK:
776 srcIp = (struct sockaddr_in *)&(sp->sourceIp);
777 srcMask = (struct sockaddr_in *)&(sp->sourceMask);
778 if ((pduIp->sin_addr.s_addr & srcMask->sin_addr.s_addr)
779 == srcIp->sin_addr.s_addr
780 && strlen(sp->community) == pdu->community_len
781 && !strncmp(sp->community, (char *)pdu->community, pdu->community_len))
785 if (sp == NULL) return 1;
786 sn = sp->securityName;
787 } else if (pdu->securityModel == SNMP_SEC_MODEL_USM) {
788 DEBUGMSG (("mibII/vacm_vars",
789 "vacm_in_view: ver=%d, model=%d, secName=%s\n",
790 pdu->version, pdu->securityModel, pdu->securityName));
791 sn = pdu->securityName;
796 if (sn == NULL) return 1;
797 DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn));
799 gp = vacm_getGroupEntry(pdu->securityModel, sn);
800 if (gp == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 2; }
801 DEBUGMSG (("mibII/vacm_vars", ", gn=%s", gp->groupName));
803 ap = vacm_getAccessEntry(gp->groupName, "", pdu->securityModel,
805 if (ap == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 3; }
807 if (name == 0) { /* only check the setup of the vacm for the request */
808 DEBUGMSG(("mibII/vacm_vars", ", Done checking setup\n"));
812 switch (pdu->command) {
814 case SNMP_MSG_GETNEXT:
815 case SNMP_MSG_GETBULK:
823 case SNMP_MSG_INFORM:
827 snmp_log(LOG_ERR, "bad msg type in vacm_in_view: %d\n", pdu->command);
830 DEBUGMSG (("mibII/vacm_vars", ", vn=%s", vn));
832 vp = vacm_getViewEntry (vn, name, namelen);
833 if (vp == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 4; }
834 DEBUGMSG(("mibII/vacm_vars", ", vt=%d\n", vp->viewType));
835 if (vp->viewType == SNMP_VIEW_EXCLUDED) return 5;
839 } /* end vacm_in_view() */
842 u_char *var_vacm_sec2group(struct variable *vp,
847 WriteMethod **write_method)
849 struct vacm_groupEntry *gp;
853 char secname[32], *cp;
856 if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
857 memcpy(name, vp->name, sizeof(oid)*vp->namelen);
858 *length = vp->namelen;
861 if (*length < 13) return NULL;
864 groupSubtree = name+13;
865 groupSubtreeLen = *length - 13;
867 while (groupSubtreeLen-- > 0) {
868 if (*groupSubtree > 255)
869 return 0; /* illegal value */
870 *cp++ = (char) *groupSubtree++;
874 gp = vacm_getGroupEntry(secmodel, secname);
877 secmodel = *length > 11 ? name[11] : 0;
878 groupSubtree = name+12;
879 groupSubtreeLen = *length - 12;
881 while (groupSubtreeLen-- > 0) {
882 if (*groupSubtree > 255)
883 return 0; /* illegal value */
884 *cp++ = (char) *groupSubtree++;
887 vacm_scanGroupInit();
888 while ((gp = vacm_scanGroupNext()) != NULL) {
889 if (gp->securityModel > secmodel ||
890 (gp->securityModel == secmodel && strcmp(gp->securityName, secname) > 0))
894 name[11] = gp->securityModel;
896 cp = gp->securityName;
898 name[(*length)++] = *cp++;
903 if (!gp) return NULL;
905 *var_len =sizeof(long_return);
908 long_return = gp->securityModel;
909 return (u_char *)&long_return;
911 *var_len = gp->securityName[0];
912 return (u_char *)&gp->securityName[1];
914 *var_len = strlen(gp->groupName);
915 return (u_char *)gp->groupName;
916 case SECURITYSTORAGE:
917 long_return = gp->storageType;
918 return (u_char *)&long_return;
920 long_return = gp->status;
921 return (u_char *)&long_return;
926 u_char *var_vacm_access(struct variable *vp,
931 WriteMethod **write_method)
933 struct vacm_accessEntry *gp;
937 char contextPrefix[32];
944 if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
945 memcpy(name, vp->name, sizeof(oid)*vp->namelen);
946 *length = vp->namelen;
949 if (*length < 15) return NULL;
956 return 0; /* illegal value */
957 *cp++ = (char) *op++;
964 return 0; /* illegal value */
965 *cp++ = (char) *op++;
970 if (op != name + *length) {
974 gp = vacm_getAccessEntry(groupName, contextPrefix, secmodel, seclevel);
977 secmodel = seclevel = 0;
979 contextPrefix[0] = 0;
981 if (op >= name + *length) {
988 return 0; /* illegal value */
989 *cp++ = (char) *op++;
993 if (op >= name + *length) {
1000 return 0; /* illegal value */
1001 *cp++ = (char) *op++;
1005 if (op >= name + *length) {
1010 if (op >= name + *length) {
1015 vacm_scanAccessInit();
1016 while ((gp = vacm_scanAccessNext()) != NULL) {
1017 cmp = strcmp(gp->groupName, groupName);
1019 if (cmp < 0) continue;
1020 cmp = strcmp(gp->contextPrefix, contextPrefix);
1022 if (cmp < 0) continue;
1023 if (gp->securityModel > secmodel) break;
1024 if (gp->securityModel < secmodel) continue;
1025 if (gp->securityLevel > seclevel) break;
1031 name[(*length)++] = *cp++;
1033 cp = gp->contextPrefix;
1035 name[(*length)++] = *cp++;
1037 name[(*length)++] = gp->securityModel;
1038 name[(*length)++] = gp->securityLevel;
1042 if (!gp) return NULL;
1044 *var_len =sizeof(long_return);
1045 switch (vp->magic) {
1047 long_return = gp->contextMatch;
1048 return (u_char *)&long_return;
1050 long_return = gp->securityLevel;
1051 return (u_char *)&long_return;
1053 long_return = gp->securityModel;
1054 return (u_char *)&long_return;
1056 *var_len = *gp->contextPrefix;
1057 return (u_char *)&gp->contextPrefix[1];
1059 *var_len = strlen(gp->readView);
1060 return (u_char *)gp->readView;
1062 *var_len = strlen(gp->writeView);
1063 return (u_char *)gp->writeView;
1065 *var_len = strlen(gp->notifyView);
1066 return (u_char *)gp->notifyView;
1068 long_return = gp->storageType;
1069 return (u_char *)&long_return;
1071 long_return = gp->status;
1072 return (u_char *)&long_return;
1077 u_char *var_vacm_view(struct variable *vp,
1082 WriteMethod **write_method)
1084 struct vacm_viewEntry *gp;
1086 oid subtree[MAX_OID_LEN];
1087 size_t subtreeLen = 0;
1093 write_method = NULL;
1094 if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
1095 memcpy(name, vp->name, sizeof(oid)*vp->namelen);
1096 *length = vp->namelen;
1099 if (*length < 15) return NULL;
1106 return 0; /* illegal value */
1107 *cp++ = (char) *op++;
1110 len = *length - (op - name);
1116 if (op != name + *length) {
1120 gp = vacm_getViewEntry(viewName, subtree, subtreeLen);
1125 if (op >= name + *length) {
1130 while (len-- >= 0) {
1132 return 0; /* illegal value */
1133 *cp++ = (char) *op++;
1137 if (op >= name + *length) {
1140 len = *length - (op - name);
1142 while (len-- >= 0) {
1147 vacm_scanViewInit();
1148 while ((gp = vacm_scanViewNext()) != NULL) {
1149 cmp = strcmp(gp->viewName, viewName);
1151 if (cmp < 0) continue;
1157 name[(*length)++] = *cp++;
1159 op1 = gp->viewSubtree;
1160 len = gp->viewSubtreeLen;
1162 name[(*length)++] = *op1++;
1163 } while (len-- > 0);
1167 if (!gp) return NULL;
1169 *var_len =sizeof(long_return);
1170 switch (vp->magic) {
1172 *var_len = gp->viewName[0];
1173 return (u_char *)&gp->viewName[1];
1175 *var_len = gp->viewSubtreeLen*sizeof(oid);
1176 return (u_char *)gp->viewSubtree;
1178 *var_len = (gp->viewSubtreeLen + 7) / 8;
1179 return (u_char *)gp->viewMask;
1181 long_return = gp->viewType;
1182 return (u_char *)&long_return;
1184 long_return = gp->viewStorageType;
1185 return (u_char *)&long_return;
1187 long_return = gp->viewStatus;
1188 return (u_char *)&long_return;
1193 #endif /* CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT */
1194 #endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */