OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [agent/] [v2_0/] [src/] [mibgroup/] [mibII/] [vacm_vars.c] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
// This file is part of eCos, the Embedded Configurable Operating System.
2
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
3
//
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.
7
//
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
11
// for more details.
12
//
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.
16
//
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.
23
//
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.
26
//
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####
32
//
33
// -------------------------------------------
34
//
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.
40
//
41
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
42
// -------------------------------------------
43
//
44
//####UCDSNMPCOPYRIGHTEND####
45
//==========================================================================
46
//#####DESCRIPTIONBEGIN####
47
//
48
// Author(s):    Manu Sharma
49
// Contributors: 
50
// Date:         2002-11-01
51
// Purpose:      Port of UCD-SNMP distribution to eCos.
52
// Description:  
53
//              
54
//
55
//####DESCRIPTIONEND####
56
//
57
//==========================================================================
58
/********************************************************************
59
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
60
 
61
                          Derivative Work -
62
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
63
 
64
                         All Rights Reserved
65
 
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
73
permission.
74
 
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
*********************************************************************/
84
/*
85
 * vacm_vars.c
86
 *
87
 * SNMPv3 View-based Access Control Model
88
 */
89
/***********************************************************
90
        Copyright 1988, 1989 by Carnegie Mellon University
91
 
92
                      All Rights Reserved
93
 
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.
101
 
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
108
SOFTWARE.
109
******************************************************************/
110
 
111
#include <config.h>
112
 
113
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
114
#ifdef CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT
115
 
116
#if HAVE_STDLIB_H
117
#include <stdlib.h>
118
#endif
119
#if HAVE_UNISTD_H
120
#include <unistd.h>
121
#endif
122
#if HAVE_STRING_H
123
#include <string.h>
124
#else
125
#include <strings.h>
126
#endif
127
#if HAVE_MALLOC_H
128
#include <malloc.h>
129
#endif
130
#include <ctype.h>
131
#include <sys/types.h>
132
#if HAVE_NETINET_IN_H
133
#include <netinet/in.h>
134
#endif
135
#if HAVE_ARPA_INET_H
136
#include <arpa/inet.h>
137
#endif
138
 
139
#if HAVE_DMALLOC_H
140
#include <dmalloc.h>
141
#endif
142
 
143
#if HAVE_NETDB_H
144
#include <netdb.h>
145
#endif
146
#if HAVE_WINSOCK_H
147
#include <winsock.h>
148
#endif
149
 
150
#include "mibincl.h"
151
#include "read_config.h"
152
#include "agent_read_config.h"
153
#include "system.h"
154
#include "vacm.h"
155
#include "callback.h"
156
#include "agent_registry.h"
157
#include "agent_callbacks.h"
158
#include "vacm_vars.h"
159
 
160
#ifdef USING_MIBII_SYSORTABLE_MODULE
161
#if TIME_WITH_SYS_TIME
162
# ifdef WIN32
163
#  include <sys/timeb.h>
164
# else
165
#  include <sys/time.h>
166
# endif
167
# include <time.h>
168
#else
169
# if HAVE_SYS_TIME_H
170
#  include <sys/time.h>
171
# else
172
#  include <time.h>
173
# endif
174
#endif
175
#include <mibgroup/mibII/sysORTable.h>
176
#endif
177
 
178
void
179
init_vacm_vars (void)
180
{
181
 
182
#ifdef USING_MIBII_SYSORTABLE_MODULE
183
  static oid reg[] = {SNMP_OID_SNMPMODULES,16,2,2,1};
184
#endif
185
 
186
#define PRIVRW  (SNMPV2ANY | 0x5000)
187
 
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}},
192
  };
193
 
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}},
201
  };
202
 
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}},
208
  };
209
 
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 };
215
 
216
  /* register ourselves with the agent to handle our mib tree */
217
  REGISTER_MIB("mibII/vacm:sec2group", vacm_sec2group, variable2, \
218
               vacm_sec2group_oid);
219
  REGISTER_MIB("mibII/vacm:access", vacm_access, variable2, vacm_access_oid);
220
  REGISTER_MIB("mibII/vacm:view", vacm_view, variable2, vacm_view_oid);
221
 
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]");
238
 
239
#ifdef USING_MIBII_SYSORTABLE_MODULE
240
  register_sysORTable(reg,10,"View-based Access Control Model for SNMP.");
241
#endif
242
 
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);
249
}
250
 
251
static struct vacm_securityEntry *securityFirst =0, *securityLast =0;
252
 
253
#define EXAMPLE_NETWORK         "NETWORK"
254
#define EXAMPLE_COMMUNITY       "COMMUNITY"
255
 
256
void vacm_parse_security (const char *token,
257
                          char *param)
258
{
259
    char *name, *source, *community;
260
    const char *mask;
261
    char *cp;
262
    struct vacm_securityEntry *sp, se;
263
    int maskLength, maskBit;
264
    struct sockaddr_in *srcIp, *srcMask;
265
    char null[] = "";
266
 
267
    memset (&se, 0 , sizeof se);
268
    name = strtok(param, "\t\n ");
269
    if (!name) {
270
        config_perror("missing NAME parameter");
271
        return;
272
    }
273
    source = strtok(NULL, "\t\n ");
274
    if (!source) {
275
        config_perror("missing SOURCE parameter");
276
        return;
277
    }
278
    if ( !strncmp( source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) ) {
279
        config_perror("Example config NETWORK not properly configured");
280
        return;         /* or exit(1); */
281
    }
282
    community = strtok(NULL, "\t\n ");
283
    if (!community) {
284
        config_perror("missing COMMUNITY parameter");
285
        return;
286
    }
287
    if ( !strncmp( community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY)) ) {
288
        config_perror("Example config COMMUNITY not properly configured");
289
        return;         /* or exit(1); */
290
    }
291
    srcIp   = (struct sockaddr_in*)&(se.sourceIp);
292
    srcMask = (struct sockaddr_in*)&(se.sourceMask);
293
    cp = strchr(source, '/');
294
    if (cp == NULL) cp = null;
295
    else *cp++ = 0;
296
    mask = cp;
297
    if (strcmp("default", source) == 0 || strcmp("0.0.0.0", source) == 0) {
298
        memset(&(srcIp->sin_addr), 0, sizeof(struct in_addr));
299
        mask = "0.0.0.0";
300
    }
301
    else if ((srcIp->sin_addr.s_addr = inet_addr (source)) == (unsigned) -1) {
302
        struct hostent *hp = gethostbyname(source);
303
        if (hp != NULL) {
304
            memcpy(&(srcIp->sin_addr), hp->h_addr, 4);
305
        }
306
        else {
307
            config_perror ("bad source address");
308
            return;
309
        }
310
    }
311
    if (*mask == 0) memset (&(srcMask->sin_addr), 0xff, sizeof(struct in_addr));
312
    else {
313
        if (strchr(mask, '.')) {
314
            if ((srcMask->sin_addr.s_addr = inet_addr(mask)) == (unsigned)-1) {
315
                config_perror("bad mask");
316
                return;
317
            }
318
        }
319
        else {
320
            maskLength = atoi(mask);
321
            if (maskLength <= 0 || maskLength > 32) {
322
                config_perror("bad mask length");
323
                return;
324
            }
325
            maskBit = 0x80000000L;
326
            srcMask->sin_addr.s_addr = 0;
327
            while (maskLength--) {
328
                srcMask->sin_addr.s_addr |= maskBit;
329
                maskBit >>= 1;
330
            }
331
            srcMask->sin_addr.s_addr = htonl(srcMask->sin_addr.s_addr);
332
        }
333
    }
334
    if ((srcIp->sin_addr.s_addr & ~srcMask->sin_addr.s_addr) != 0) {
335
        config_perror("source/mask mismatch");
336
        return;
337
    }
338
    if (strlen(name)+1 > sizeof(se.securityName)) {
339
        config_perror("security name too long");
340
        return;
341
    }
342
    if (strlen(community)+1 > sizeof(se.community)) {
343
        config_perror("community name too long");
344
        return;
345
    }
346
    strcpy(se.securityName, name);
347
    strcpy(se.community, community);
348
    sp = (struct vacm_securityEntry *)malloc (sizeof *sp);
349
    if (sp == NULL) {
350
        config_perror("memory error");
351
        return;
352
    }
353
    *sp = se;
354
    if (securityFirst != NULL) {
355
        securityLast->next = sp;
356
        securityLast = sp;
357
    }
358
    else {
359
        securityFirst = securityLast = sp;
360
    }
361
}
362
 
363
void vacm_free_security (void)
364
{
365
    struct vacm_securityEntry *sp;
366
    while ((sp = securityFirst)) {
367
        securityFirst = sp->next;
368
        free(sp);
369
    }
370
}
371
 
372
void vacm_parse_group (const char *token,
373
                       char *param)
374
{
375
    char *group, *model, *security;
376
    int imodel;
377
    struct vacm_groupEntry *gp = NULL;
378
 
379
    group = strtok (param, " \t\n");
380
    model = strtok (NULL, " \t\n");
381
    security = strtok (NULL, " \t\n");
382
 
383
    if (group == NULL || *group == 0) {
384
        config_perror("missing GROUP parameter");
385
        return;
386
    }
387
    if (model == NULL || *model == 0) {
388
        config_perror("missing MODEL parameter");
389
        return;
390
    }
391
    if (security == NULL || *security == 0) {
392
        config_perror("missing SECURITY parameter");
393
        return;
394
    }
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;
401
    }
402
    else {
403
        config_perror("bad security model, should be: v1, v2c or usm");
404
        return;
405
    }
406
    if (strlen(security)+1 > sizeof(gp->groupName)) {
407
        config_perror("security name too long");
408
        return;
409
    }
410
    gp = vacm_createGroupEntry(imodel, security);
411
    if (!gp) {
412
        config_perror("failed to create group entry");
413
        return;
414
    }
415
    strcpy (gp->groupName, group);
416
    gp->storageType = SNMP_STORAGE_PERMANENT;
417
    gp->status = SNMP_ROW_ACTIVE;
418
    free (gp->reserved);
419
    gp->reserved = NULL;
420
}
421
 
422
void vacm_free_group (void)
423
{
424
    vacm_destroyAllGroupEntries();
425
}
426
 
427
void vacm_parse_access (const char *token, char *param)
428
{
429
    char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify;
430
    int imodel, ilevel, iprefix;
431
    struct vacm_accessEntry *ap;
432
 
433
    name = strtok(param, " \t\n");
434
    if (!name) {
435
        config_perror("missing NAME parameter");
436
        return;
437
    }
438
    context = strtok(NULL, " \t\n");
439
    if (!context) {
440
        config_perror("missing CONTEXT parameter");
441
        return;
442
    }
443
    model = strtok(NULL, " \t\n");
444
    if (!model) {
445
        config_perror("missing MODEL parameter");
446
        return;
447
    }
448
    level = strtok(NULL, " \t\n");
449
    if (!level) {
450
        config_perror("missing LEVEL parameter");
451
        return;
452
    }
453
    prefix = strtok(NULL, " \t\n");
454
    if (!prefix) {
455
        config_perror("missing PREFIX parameter");
456
        return;
457
    }
458
    readView = strtok(NULL, " \t\n");
459
    if (!readView) {
460
        config_perror("missing readView parameter");
461
        return;
462
    }
463
    writeView = strtok(NULL, " \t\n");
464
    if (!writeView) {
465
        config_perror("missing writeView parameter");
466
        return;
467
    }
468
    notify = strtok(NULL, " \t\n");
469
    if (!notify) {
470
        config_perror("missing notifyView parameter");
471
        return;
472
    }
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;
478
    else {
479
        config_perror("bad security model (any, v1, v2c, usm)");
480
        return;
481
    }
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;
488
    else {
489
        config_perror("bad security level (noauthnopriv, authnopriv, authpriv)");
490
        return;
491
    }
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");
496
        iprefix = 1;
497
    }
498
    else {
499
        config_perror("bad prefix match parameter, should be: exact or prefix");
500
        return;
501
    }
502
    if (strlen(readView)+1 > sizeof(ap->readView)) {
503
        config_perror("readView too long");
504
        return;
505
    }
506
    if (strlen(writeView)+1 > sizeof(ap->writeView)) {
507
        config_perror("writeView too long");
508
        return;
509
    }
510
    if (strlen(notify)+1 > sizeof(ap->notifyView)) {
511
        config_perror("notifyView too long");
512
        return;
513
    }
514
    ap = vacm_createAccessEntry (name, context, imodel, ilevel);
515
    if (!ap) {
516
        config_perror("failed to create access entry");
517
        return;
518
    }
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;
525
    free (ap->reserved);
526
    ap->reserved = NULL;
527
}
528
 
529
void vacm_free_access (void)
530
{
531
    vacm_destroyAllAccessEntries();
532
}
533
 
534
void vacm_parse_view (const char *token,
535
                      char *param)
536
{
537
    char *name, *type, *subtree, *mask;
538
    int inclexcl;
539
    struct vacm_viewEntry *vp;
540
    oid suboid[MAX_OID_LEN];
541
    size_t suboid_len = 0;
542
    u_char viewMask[sizeof (vp->viewMask)];
543
    int i;
544
 
545
    name = strtok (param, " \t\n");
546
    if (!name) {
547
        config_perror("missing NAME parameter");
548
        return;
549
    }
550
    type = strtok (NULL, " \n\t");
551
    if (!type) {
552
        config_perror("missing TYPE parameter");
553
        return;
554
    }
555
    subtree = strtok(NULL, " \t\n");
556
    if (!subtree) {
557
        config_perror("missing SUBTREE parameter");
558
        return;
559
    }
560
    mask = strtok(NULL, " \t\n");
561
 
562
    if (strcmp(type, "included") == 0) inclexcl = SNMP_VIEW_INCLUDED;
563
    else if (strcmp(type, "excluded") == 0) inclexcl = SNMP_VIEW_EXCLUDED;
564
    else {
565
        config_perror("TYPE must be included/excluded?");
566
        return;
567
    }
568
    suboid_len = MAX_OID_LEN;
569
    if (!read_objid(subtree, suboid, &suboid_len)) {
570
        config_perror("bad SUBTREE object id");
571
        return;
572
    }
573
    if (mask) {
574
        int val;
575
        i = 0;
576
        for (mask = strtok(mask, ".:"); mask; mask = strtok(NULL, ".:")) {
577
            if (i >= sizeof(viewMask)) {
578
                config_perror("MASK too long");
579
                return;
580
            }
581
            if (sscanf(mask, "%x", &val) == 0) {
582
                config_perror("invalid MASK");
583
                return;
584
            }
585
            viewMask[i] = val;
586
            i++;
587
        }
588
    }
589
    else {
590
        for (i = 0; i < sizeof(viewMask); i++)
591
            viewMask[i] = 0xff;
592
    }
593
    vp = vacm_createViewEntry(name, suboid, suboid_len);
594
    if (!vp) {
595
        config_perror("failed to create view entry");
596
        return;
597
    }
598
    memcpy(vp->viewMask, viewMask, sizeof(viewMask));
599
    vp->viewType = inclexcl;
600
    vp->viewStorageType = SNMP_STORAGE_PERMANENT;
601
    vp->viewStatus = SNMP_ROW_ACTIVE;
602
    free (vp->reserved);
603
    vp->reserved = NULL;
604
}
605
 
606
void vacm_free_view (void)
607
{
608
    vacm_destroyAllViewEntries();
609
}
610
 
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";
619
  char *cp;
620
  static int num = 0;
621
  char secname[SPRINT_MAX_LEN];
622
  char authtype[SPRINT_MAX_LEN];
623
 
624
  /* community name or user name */
625
  cp = copy_word(confline, community);
626
 
627
  if (strcmp(token,"rouser") == 0 || strcmp(token,"rwuser") == 0) {
628
    /* authentication type */
629
    if (cp && *cp)
630
      cp = copy_word(cp, authtype);
631
    else
632
      strcpy(authtype, "auth");
633
    DEBUGMSGTL((token, "setting auth type: \"%s\"\n",authtype));
634
    model = "usm";
635
  } else {
636
    /* source address */
637
    if (cp && *cp) {
638
      cp = copy_word(cp, addressname);
639
    } else {
640
      strcpy(addressname, "default");
641
    }
642
    /* authtype has to be noauth */
643
    strcpy(authtype, "noauth");
644
  }
645
 
646
  /* oid they can touch */
647
  if (cp && *cp) {
648
    cp = copy_word(cp, theoid);
649
  } else {
650
    strcpy(theoid, ".1");
651
  }
652
 
653
  if (strcmp(token,"rwcommunity") == 0 || strcmp(token,"rwuser") == 0)
654
    rw = viewname;
655
 
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);
663
 
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);
672
  } else {
673
    strcpy(secname, community);
674
 
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);
680
  }
681
 
682
 
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);
689
 
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);
696
  num++;
697
}
698
 
699
int
700
vacm_in_view_callback(int majorID, int minorID, void *serverarg,
701
                      void *clientarg) {
702
  struct view_parameters *view_parms = (struct view_parameters *) serverarg;
703
  int retval;
704
 
705
  if (view_parms == NULL)
706
    return 1;
707
  retval = vacm_in_view(view_parms->pdu, view_parms->name,
708
                        view_parms->namelen);
709
  if (retval != 0)
710
    view_parms->errorcode = retval;
711
  return retval;
712
}
713
 
714
 
715
/*******************************************************************-o-******
716
 * vacm_in_view
717
 *
718
 * Parameters:
719
 *      *pdu
720
 *      *name
721
 *       namelen
722
 *
723
 * Returns:
724
 *      0        On success.
725
 *      1       Missing security name.
726
 *      2       Missing group
727
 *      3       Missing access
728
 *      4       Missing view
729
 *      5       Not in view
730
 *
731
 * Debug output listed as follows:
732
 *      <securityName> <groupName> <viewName> <viewType>
733
 */
734
int vacm_in_view (struct snmp_pdu *pdu,
735
                  oid *name,
736
                  size_t namelen)
737
{
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;
744
    char *vn;
745
    char *sn;
746
 
747
    if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) {
748
        if (snmp_get_do_debugging()) {
749
            char *buf;
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';
754
            } else {
755
                DEBUGMSGTL(("mibII/vacm_vars", "NULL community"));
756
                buf = strdup("NULL");
757
            }
758
 
759
            DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: ver=%d, source=%.8x, community=%s\n", pdu->version, pduIp->sin_addr.s_addr, buf));
760
            free (buf);
761
        }
762
 
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) {
767
            case SNMP_MSG_GET:
768
            case SNMP_MSG_GETNEXT:
769
            case SNMP_MSG_GETBULK:
770
                return 0;
771
            default:
772
                return 1;
773
            }
774
        }
775
        while (sp) {
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))
782
                break;
783
            sp = sp->next;
784
        }
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;
792
    } else {
793
        sn = NULL;
794
    }
795
 
796
    if (sn == NULL) return 1;
797
    DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn));
798
 
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));
802
 
803
    ap = vacm_getAccessEntry(gp->groupName, "", pdu->securityModel,
804
                             pdu->securityLevel);
805
    if (ap == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 3; }
806
 
807
    if (name == 0) { /* only check the setup of the vacm for the request */
808
        DEBUGMSG(("mibII/vacm_vars", ", Done checking setup\n"));
809
        return 0;
810
    }
811
 
812
    switch (pdu->command) {
813
      case SNMP_MSG_GET:
814
      case SNMP_MSG_GETNEXT:
815
      case SNMP_MSG_GETBULK:
816
        vn = ap->readView;
817
        break;
818
      case SNMP_MSG_SET:
819
        vn = ap->writeView;
820
        break;
821
      case SNMP_MSG_TRAP:
822
      case SNMP_MSG_TRAP2:
823
      case SNMP_MSG_INFORM:
824
        vn = ap->notifyView;
825
        break;
826
      default:
827
        snmp_log(LOG_ERR, "bad msg type in vacm_in_view: %d\n", pdu->command);
828
        vn = ap->readView;
829
    }
830
    DEBUGMSG (("mibII/vacm_vars", ", vn=%s", vn));
831
 
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;
836
 
837
    return 0;
838
 
839
}  /* end vacm_in_view() */
840
 
841
 
842
u_char *var_vacm_sec2group(struct variable *vp,
843
                           oid *name,
844
                           size_t *length,
845
                           int exact,
846
                           size_t *var_len,
847
                           WriteMethod **write_method)
848
{
849
    struct vacm_groupEntry *gp;
850
    oid *groupSubtree;
851
    int groupSubtreeLen;
852
    int secmodel;
853
    char secname[32], *cp;
854
 
855
    write_method = NULL;
856
    if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
857
        memcpy(name, vp->name, sizeof(oid)*vp->namelen);
858
        *length = vp->namelen;
859
    }
860
    if (exact) {
861
        if (*length < 13) return NULL;
862
 
863
        secmodel = name[11];
864
        groupSubtree = name+13;
865
        groupSubtreeLen = *length - 13;
866
        cp = secname;
867
        while (groupSubtreeLen-- > 0) {
868
            if (*groupSubtree > 255)
869
              return 0; /* illegal value */
870
            *cp++ = (char) *groupSubtree++;
871
        }
872
        *cp = 0;
873
 
874
        gp = vacm_getGroupEntry(secmodel, secname);
875
    }
876
    else {
877
        secmodel = *length > 11 ? name[11] : 0;
878
        groupSubtree = name+12;
879
        groupSubtreeLen = *length - 12;
880
        cp = secname;
881
        while (groupSubtreeLen-- > 0) {
882
            if (*groupSubtree > 255)
883
              return 0; /* illegal value */
884
            *cp++ = (char) *groupSubtree++;
885
        }
886
        *cp = 0;
887
        vacm_scanGroupInit();
888
        while ((gp = vacm_scanGroupNext()) != NULL) {
889
            if (gp->securityModel > secmodel ||
890
                (gp->securityModel == secmodel && strcmp(gp->securityName, secname) > 0))
891
                break;
892
        }
893
        if (gp) {
894
            name[11] = gp->securityModel;
895
            *length = 12;
896
            cp = gp->securityName;
897
            while (*cp) {
898
                name[(*length)++] = *cp++;
899
            }
900
        }
901
    }
902
 
903
    if (!gp) return NULL;
904
 
905
    *var_len =sizeof(long_return);
906
    switch (vp->magic) {
907
    case SECURITYMODEL:
908
        long_return = gp->securityModel;
909
        return (u_char *)&long_return;
910
    case SECURITYNAME:
911
        *var_len = gp->securityName[0];
912
        return (u_char *)&gp->securityName[1];
913
    case SECURITYGROUP:
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;
919
    case SECURITYSTATUS:
920
        long_return = gp->status;
921
        return (u_char *)&long_return;
922
    }
923
    return NULL;
924
}
925
 
926
u_char *var_vacm_access(struct variable *vp,
927
                        oid *name,
928
                        size_t *length,
929
                        int exact,
930
                        size_t *var_len,
931
                        WriteMethod **write_method)
932
{
933
    struct vacm_accessEntry *gp;
934
    int secmodel;
935
    int seclevel;
936
    char groupName[32];
937
    char contextPrefix[32];
938
    oid *op;
939
    int len;
940
    char *cp;
941
    int cmp;
942
 
943
    write_method = NULL;
944
    if (memcmp(name, vp->name, sizeof(oid)*vp->namelen) != 0) {
945
        memcpy(name, vp->name, sizeof(oid)*vp->namelen);
946
        *length = vp->namelen;
947
    }
948
    if (exact) {
949
        if (*length < 15) return NULL;
950
 
951
        op = name+11;
952
        len = *op++;
953
        cp = groupName;
954
        while (len-- > 0) {
955
            if (*op > 255)
956
              return 0; /* illegal value */
957
            *cp++ = (char) *op++;
958
        }
959
        *cp = 0;
960
        len = *op++;
961
        cp = contextPrefix;
962
        while (len-- > 0) {
963
            if (*op > 255)
964
              return 0; /* illegal value */
965
            *cp++ = (char) *op++;
966
        }
967
        *cp = 0;
968
        secmodel = *op++;
969
        seclevel = *op++;
970
        if (op != name + *length) {
971
            return NULL;
972
        }
973
 
974
        gp = vacm_getAccessEntry(groupName, contextPrefix, secmodel, seclevel);
975
    }
976
    else {
977
        secmodel = seclevel = 0;
978
        groupName[0] = 0;
979
        contextPrefix[0] = 0;
980
        op = name+11;
981
        if (op >= name + *length) {
982
        }
983
        else {
984
            len = *op;
985
            cp = groupName;
986
            while (len-- >= 0) {
987
                if (*op > 255)
988
                  return 0; /* illegal value */
989
                *cp++ = (char) *op++;
990
            }
991
            *cp = 0;
992
        }
993
        if (op >= name + *length) {
994
        }
995
        else {
996
            len = *op;
997
            cp = contextPrefix;
998
            while (len-- >= 0) {
999
                if (*op > 255)
1000
                  return 0; /* illegal value */
1001
                *cp++ = (char) *op++;
1002
            }
1003
            *cp = 0;
1004
        }
1005
        if (op >= name + *length) {
1006
        }
1007
        else {
1008
            secmodel = *op++;
1009
        }
1010
        if (op >= name + *length) {
1011
        }
1012
        else {
1013
            seclevel = *op++;
1014
        }
1015
        vacm_scanAccessInit();
1016
        while ((gp = vacm_scanAccessNext()) != NULL) {
1017
            cmp = strcmp(gp->groupName, groupName);
1018
            if (cmp > 0) break;
1019
            if (cmp < 0) continue;
1020
            cmp = strcmp(gp->contextPrefix, contextPrefix);
1021
            if (cmp > 0) break;
1022
            if (cmp < 0) continue;
1023
            if (gp->securityModel > secmodel) break;
1024
            if (gp->securityModel < secmodel) continue;
1025
            if (gp->securityLevel > seclevel) break;
1026
        }
1027
        if (gp) {
1028
            *length = 11;
1029
            cp = gp->groupName;
1030
            do {
1031
                name[(*length)++] = *cp++;
1032
            } while (*cp);
1033
            cp = gp->contextPrefix;
1034
            do {
1035
                name[(*length)++] = *cp++;
1036
            } while (*cp);
1037
            name[(*length)++] = gp->securityModel;
1038
            name[(*length)++] = gp->securityLevel;
1039
        }
1040
    }
1041
 
1042
    if (!gp) return NULL;
1043
 
1044
    *var_len =sizeof(long_return);
1045
    switch (vp->magic) {
1046
    case ACCESSMATCH:
1047
        long_return = gp->contextMatch;
1048
        return (u_char *)&long_return;
1049
    case ACCESSLEVEL:
1050
        long_return = gp->securityLevel;
1051
        return (u_char *)&long_return;
1052
    case ACCESSMODEL:
1053
        long_return = gp->securityModel;
1054
        return (u_char *)&long_return;
1055
    case ACCESSPREFIX:
1056
        *var_len = *gp->contextPrefix;
1057
        return (u_char *)&gp->contextPrefix[1];
1058
    case ACCESSREAD:
1059
        *var_len = strlen(gp->readView);
1060
        return (u_char *)gp->readView;
1061
    case ACCESSWRITE:
1062
        *var_len = strlen(gp->writeView);
1063
        return (u_char *)gp->writeView;
1064
    case ACCESSNOTIFY:
1065
        *var_len = strlen(gp->notifyView);
1066
        return (u_char *)gp->notifyView;
1067
    case ACCESSSTORAGE:
1068
        long_return = gp->storageType;
1069
        return (u_char *)&long_return;
1070
    case ACCESSSTATUS:
1071
        long_return = gp->status;
1072
        return (u_char *)&long_return;
1073
    }
1074
    return NULL;
1075
}
1076
 
1077
u_char *var_vacm_view(struct variable *vp,
1078
                      oid *name,
1079
                      size_t *length,
1080
                      int exact,
1081
                      size_t *var_len,
1082
                      WriteMethod **write_method)
1083
{
1084
    struct vacm_viewEntry *gp;
1085
    char viewName[32];
1086
    oid subtree[MAX_OID_LEN];
1087
    size_t subtreeLen = 0;
1088
    oid *op, *op1;
1089
    int len;
1090
    char *cp;
1091
    int cmp;
1092
 
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;
1097
    }
1098
    if (exact) {
1099
        if (*length < 15) return NULL;
1100
 
1101
        op = name+12;
1102
        len = *op++;
1103
        cp = viewName;
1104
        while (len-- > 0) {
1105
            if (*op > 255)
1106
              return 0; /* illegal value */
1107
            *cp++ = (char) *op++;
1108
        }
1109
        *cp = 0;
1110
        len = *length - (op - name);
1111
        op1 = subtree;
1112
        while (len-- > 0) {
1113
            *op1++ = *op++;
1114
            subtreeLen++;
1115
        }
1116
        if (op != name + *length) {
1117
            return NULL;
1118
        }
1119
 
1120
        gp = vacm_getViewEntry(viewName, subtree, subtreeLen);
1121
    }
1122
    else {
1123
        viewName[0] = 0;
1124
        op = name+12;
1125
        if (op >= name + *length) {
1126
        }
1127
        else {
1128
            len = *op;
1129
            cp = viewName;
1130
            while (len-- >= 0) {
1131
                if (*op > 255)
1132
                  return 0; /* illegal value */
1133
                *cp++ = (char) *op++;
1134
            }
1135
            *cp = 0;
1136
        }
1137
        if (op >= name + *length) {
1138
        }
1139
        else {
1140
            len = *length - (op - name);
1141
            op1 = subtree;
1142
            while (len-- >= 0) {
1143
                *op1++ = *op++;
1144
                subtreeLen++;
1145
            }
1146
        }
1147
        vacm_scanViewInit();
1148
        while ((gp = vacm_scanViewNext()) != NULL) {
1149
            cmp = strcmp(gp->viewName, viewName);
1150
            if (cmp > 0) break;
1151
            if (cmp < 0) continue;
1152
        }
1153
        if (gp) {
1154
            *length = 12;
1155
            cp = gp->viewName;
1156
            do {
1157
                name[(*length)++] = *cp++;
1158
            } while (*cp);
1159
            op1 = gp->viewSubtree;
1160
            len = gp->viewSubtreeLen;
1161
            do {
1162
                name[(*length)++] = *op1++;
1163
            } while (len-- > 0);
1164
        }
1165
    }
1166
 
1167
    if (!gp) return NULL;
1168
 
1169
    *var_len =sizeof(long_return);
1170
    switch (vp->magic) {
1171
    case VIEWNAME:
1172
        *var_len = gp->viewName[0];
1173
        return (u_char *)&gp->viewName[1];
1174
    case VIEWSUBTREE:
1175
        *var_len = gp->viewSubtreeLen*sizeof(oid);
1176
        return (u_char *)gp->viewSubtree;
1177
    case VIEWMASK:
1178
        *var_len = (gp->viewSubtreeLen + 7) / 8;
1179
        return (u_char *)gp->viewMask;
1180
    case VIEWTYPE:
1181
        long_return = gp->viewType;
1182
        return (u_char *)&long_return;
1183
    case VIEWSTORAGE:
1184
        long_return = gp->viewStorageType;
1185
        return (u_char *)&long_return;
1186
    case VIEWSTATUS:
1187
        long_return = gp->viewStatus;
1188
        return (u_char *)&long_return;
1189
    }
1190
    return NULL;
1191
}
1192
 
1193
#endif /* CYGPKG_SNMPLIB_FILESYSTEM_SUPPORT */
1194
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.