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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./agent/current/src/mibgroup/snmpv3/usmUser.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    Andrew.Lunn@ascom.ch, Manu.Sharma@ascom.com
57
// Contributors: hmt
58
// Date:         2001-05-29
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/*
93
 * usmUser.c
94
 */
95
 
96
#include <config.h>
97
 
98
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
99
#include <stdlib.h>
100
 
101
#if HAVE_STRING_H
102
#include <string.h>
103
#else
104
#include <strings.h>
105
#endif
106
 
107
#if HAVE_WINSOCK_H
108
#include <winsock.h>
109
#endif
110
 
111
#include "mibincl.h"
112
#include "snmpusm.h"
113
#include "snmpv3.h"
114
#include "snmp-tc.h"
115
#include "read_config.h"
116
#include "agent_read_config.h"
117
//#include "util_funcs.h"
118
#include "keytools.h"
119
#include "tools.h"
120
#include "scapi.h"
121
 
122
#include "usmUser.h"
123
#include "transform_oids.h"
124
 
125
struct variable4 usmUser_variables[] = {
126
  { USMUSERSPINLOCK     , ASN_INTEGER   , RWRITE, var_usmUser, 1, { 1 } },
127
  { USMUSERSECURITYNAME , ASN_OCTET_STR , RONLY , var_usmUser, 3, { 2,1,3 } },
128
  { USMUSERCLONEFROM    , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,4 } },
129
  { USMUSERAUTHPROTOCOL , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,5 } },
130
  { USMUSERAUTHKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,6 } },
131
  { USMUSEROWNAUTHKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,7 } },
132
  { USMUSERPRIVPROTOCOL , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,8 } },
133
  { USMUSERPRIVKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,9 } },
134
  { USMUSEROWNPRIVKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,10 } },
135
  { USMUSERPUBLIC       , ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,11 } },
136
  { USMUSERSTORAGETYPE  , ASN_INTEGER   , RWRITE, var_usmUser, 3, { 2,1,12 } },
137
  { USMUSERSTATUS       , ASN_INTEGER   , RWRITE, var_usmUser, 3, { 2,1,13 } },
138
 
139
};
140
 
141
oid usmUser_variables_oid[] = {1,3,6,1,6,3,15,1,2};
142
 
143
 
144
/* needed for the write_ functions to find the start of the index */
145
#define USM_MIB_LENGTH 12
146
 
147
static unsigned int usmUserSpinLock=0;
148
 
149
void
150
init_usmUser(void)
151
{
152
  snmpd_register_config_handler("usmUser",
153
                                usm_parse_config_usmUser, NULL, NULL);
154
  snmpd_register_config_handler("createUser",
155
                                usm_parse_create_usmUser, NULL,
156
                                "username (MD5|SHA) passphrase [DES] [passphrase]");
157
 
158
  /* we need to be called back later */
159
  snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
160
                         usm_store_users, NULL);
161
 
162
  REGISTER_MIB("snmpv3/usmUser", usmUser_variables, variable4,
163
                                 usmUser_variables_oid);
164
 
165
}
166
 
167
/*******************************************************************-o-******
168
 * usm_generate_OID
169
 *
170
 * Parameters:
171
 *      *prefix         (I) OID prefix to the usmUser table entry.
172
 *       prefixLen      (I)
173
 *      *uptr           (I) Pointer to a user in the user list.
174
 *      *length         (O) Length of generated index OID.
175
 *
176
 * Returns:
177
 *      Pointer to the OID index for the user (uptr)  -OR-
178
 *      NULL on failure.
179
 *
180
 *
181
 * Generate the index OID for a given usmUser name.  'length' is set to
182
 * the length of the index OID.
183
 *
184
 * Index OID format is:
185
 *
186
 *    <...prefix>.<engineID_length>.<engineID>.<user_name_length>.<user_name>
187
 */
188
oid *
189
usm_generate_OID(oid *prefix, size_t prefixLen, struct usmUser *uptr,
190
                       size_t *length)
191
{
192
  oid *indexOid;
193
  int i;
194
 
195
  *length = 2 + uptr->engineIDLen + strlen(uptr->name) + prefixLen;
196
  indexOid = (oid *) malloc(*length * sizeof(oid));
197
  if (indexOid) {
198
    memmove(indexOid, prefix, prefixLen * sizeof (oid));
199
 
200
    indexOid[prefixLen] = uptr->engineIDLen;
201
    for(i = 0; i < (int)uptr->engineIDLen; i++)
202
      indexOid[prefixLen+1+i] = (oid) uptr->engineID[i];
203
 
204
    indexOid[prefixLen + uptr->engineIDLen + 1] = strlen(uptr->name);
205
    for(i = 0; i < (int)strlen(uptr->name); i++)
206
      indexOid[prefixLen + uptr->engineIDLen + 2 + i] = (oid) uptr->name[i];
207
  }
208
  return indexOid;
209
 
210
}  /* end usm_generate_OID() */
211
 
212
/* usm_parse_oid(): parses an index to the usmTable to break it down into
213
   a engineID component and a name component.  The results are stored in:
214
 
215
   **engineID:   a newly malloced string.
216
   *engineIDLen: The length of the malloced engineID string above.
217
   **name:       a newly malloced string.
218
   *nameLen:     The length of the malloced name string above.
219
 
220
   returns 1 if an error is encountered, or 0 if successful.
221
*/
222
int
223
usm_parse_oid(oid *oidIndex, size_t oidLen,
224
              unsigned char **engineID, size_t *engineIDLen,
225
              unsigned char **name, size_t *nameLen)
226
{
227
  int nameL;
228
  int engineIDL;
229
  int i;
230
 
231
  /* first check the validity of the oid */
232
  if ((oidLen <= 0) || (!oidIndex)) {
233
    DEBUGMSGTL(("usmUser","parse_oid: null oid or zero length oid passed in\n"));
234
    return 1;
235
  }
236
  engineIDL = *oidIndex;                /* initial engineID length */
237
  if ((int)oidLen < engineIDL + 2) {
238
    DEBUGMSGTL(("usmUser","parse_oid: invalid oid length: less than the engineIDLen\n"));
239
    return 1;
240
  }
241
  nameL = oidIndex[engineIDL+1];        /* the initial name length */
242
  if ((int)oidLen != engineIDL + nameL + 2) {
243
    DEBUGMSGTL(("usmUser","parse_oid: invalid oid length: length is not exact\n"));
244
    return 1;
245
  }
246
 
247
  /* its valid, malloc the space and store the results */
248
  if (engineID == NULL || name == NULL) {
249
    DEBUGMSGTL(("usmUser","parse_oid: null storage pointer passed in.\n"));
250
    return 1;
251
  }
252
 
253
  *engineID = (unsigned char *) malloc(engineIDL);
254
  if (*engineID == NULL) {
255
    DEBUGMSGTL(("usmUser","parse_oid: malloc of the engineID failed\n"));
256
    return 1;
257
  }
258
  *engineIDLen = engineIDL;
259
 
260
  *name = (unsigned char *) malloc(nameL+1);
261
  if (*name == NULL) {
262
    DEBUGMSGTL(("usmUser","parse_oid: malloc of the name failed\n"));
263
    free(*engineID);
264
    return 1;
265
  }
266
  *nameLen = nameL;
267
 
268
  for(i = 0; i < engineIDL; i++) {
269
    if (oidIndex[i+1] > 255) {
270
      goto UPO_parse_error;
271
    }
272
    engineID[0][i] = (unsigned char) oidIndex[i+1];
273
  }
274
 
275
  for(i = 0; i < nameL; i++) {
276
    if (oidIndex[i+2+engineIDL] > 255) {
277
      UPO_parse_error:
278
      free(*engineID);
279
      free(*name);
280
      return 1;
281
    }
282
    name[0][i] = (unsigned char) oidIndex[i+2+engineIDL];
283
  }
284
  name[0][nameL] = 0;
285
 
286
  return 0;
287
 
288
}  /* end usm_parse_oid() */
289
 
290
/*******************************************************************-o-******
291
 * usm_parse_user
292
 *
293
 * Parameters:
294
 *      *name           Complete OID indexing a given usmUser entry.
295
 *       name_length
296
 *
297
 * Returns:
298
 *      Pointer to a usmUser  -OR-
299
 *      NULL if name does not convert to a usmUser.
300
 *
301
 * Convert an (full) OID and return a pointer to a matching user in the
302
 * user list if one exists.
303
 */
304
struct usmUser *
305
usm_parse_user(oid *name, size_t name_len)
306
{
307
  struct usmUser *uptr;
308
 
309
  char *newName;
310
  u_char *engineID;
311
  size_t nameLen, engineIDLen;
312
 
313
  /* get the name and engineID out of the incoming oid */
314
  if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len-USM_MIB_LENGTH,
315
                    &engineID, &engineIDLen, (u_char **)&newName, &nameLen))
316
    return NULL;
317
 
318
  /* Now see if a user exists with these index values */
319
  uptr = usm_get_user(engineID, engineIDLen, newName);
320
  free(engineID);
321
  free(newName);
322
 
323
  return uptr;
324
 
325
}  /* end usm_parse_user() */
326
 
327
/*******************************************************************-o-******
328
 * var_usmUser
329
 *
330
 * Parameters:
331
 *        *vp      (I)     Variable-binding associated with this action.
332
 *        *name    (I/O)   Input name requested, output name found.
333
 *        *length  (I/O)   Length of input and output oid's.
334
 *         exact   (I)     TRUE if an exact match was requested.
335
 *        *var_len (O)     Length of variable or 0 if function returned.
336
 *      (**write_method)   Hook to name a write method (UNUSED).
337
 *
338
 * Returns:
339
 *      Pointer to (char *) containing related data of length 'length'
340
 *        (May be NULL.)
341
 *
342
 *
343
 * Call-back function passed to the agent in order to return information
344
 * for the USM MIB tree.
345
 *
346
 *
347
 * If this invocation is not for USMUSERSPINLOCK, lookup user name
348
 * in the usmUser list.
349
 *
350
 * If the name does not match any user and the request
351
 * is for an exact match, -or- if the usmUser list is empty, create a
352
 * new list entry.
353
 *
354
 * Finally, service the given USMUSER* var-bind.  A NULL user generally
355
 * results in a NULL return value.
356
 */
357
u_char *
358
var_usmUser(
359
    struct variable *vp,
360
    oid     *name,
361
    size_t  *length,
362
    int     exact,
363
    size_t  *var_len,
364
    WriteMethod **write_method)
365
{
366
  struct usmUser *uptr=NULL, *nptr, *pptr;
367
  int i, rtest, result;
368
  oid *indexOid;
369
  size_t len;
370
 
371
  /* variables we may use later */
372
  static long long_ret;
373
  static u_char string[1];
374
  static oid objid[2];                      /* for .0.0 */
375
 
376
  *write_method = 0;           /* assume it isnt writable for the time being */
377
  *var_len = sizeof(long_ret); /* assume an integer and change later if not */
378
 
379
  if (vp->magic != USMUSERSPINLOCK) {
380
    oid newname[MAX_OID_LEN];
381
    len = (*length < vp->namelen) ? *length : vp->namelen;
382
    rtest = snmp_oid_compare(name, len, vp->name, len);
383
    if (rtest > 0 ||
384
/*      (rtest == 0 && !exact && (int) vp->namelen+1 < (int) *length) || */
385
        (exact == 1 && rtest != 0)) {
386
      if (var_len)
387
        *var_len = 0;
388
      return 0;
389
    }
390
    memset(newname, 0, sizeof(newname));
391
    if (((int) *length) <= (int) vp->namelen || rtest == -1) {
392
      /* oid is not within our range yet */
393
      /* need to fail if not exact */
394
      uptr = usm_get_userList();
395
 
396
    } else {
397
      for(nptr = usm_get_userList(), pptr = NULL, uptr = NULL; nptr != NULL;
398
          pptr = nptr, nptr = nptr->next) {
399
        indexOid = usm_generate_OID(vp->name, vp->namelen, nptr, &len);
400
        result = snmp_oid_compare(name, *length, indexOid, len);
401
        DEBUGMSGTL(("usmUser", "Checking user: %s - ", nptr->name));
402
        for(i = 0; i < (int)nptr->engineIDLen; i++) {
403
          DEBUGMSG(("usmUser", " %x",nptr->engineID[i]));
404
        }
405
        DEBUGMSG(("usmUser"," - %d \n  -> OID: ", result));
406
        DEBUGMSGOID(("usmUser", indexOid, len));
407
        DEBUGMSG(("usmUser","\n"));
408
 
409
        free(indexOid);
410
 
411
        if (exact) {
412
          if (result == 0) {
413
            uptr = nptr;
414
          }
415
        } else {
416
          if (result == 0) {
417
            /* found an exact match.  Need the next one for !exact */
418
            uptr = nptr->next;
419
          } else if (result == 1) {
420
            uptr = nptr;
421
          }
422
        }
423
      }
424
    }  /* endif -- name <= vp->name */
425
 
426
    /* if uptr is NULL and exact we need to continue for creates */
427
    if (uptr == NULL && !exact)
428
      return(NULL);
429
 
430
    if (uptr) {
431
      indexOid = usm_generate_OID(vp->name, vp->namelen, uptr, &len);
432
      *length = len;
433
      memmove(name, indexOid, len*sizeof(oid));
434
      DEBUGMSGTL(("usmUser", "Found user: %s - ", uptr->name));
435
      for(i = 0; i < (int)uptr->engineIDLen; i++) {
436
        DEBUGMSG(("usmUser", " %x",uptr->engineID[i]));
437
      }
438
      DEBUGMSG(("usmUser","\n  -> OID: "));
439
      DEBUGMSGOID(("usmUser", indexOid, len));
440
      DEBUGMSG(("usmUser","\n"));
441
 
442
      free(indexOid);
443
    }
444
  } else {
445
    if (header_generic(vp,name,length,exact,var_len,write_method))
446
      return 0;
447
  }  /* endif -- vp->magic != USMUSERSPINLOCK */
448
 
449
  switch(vp->magic) {
450
    case USMUSERSPINLOCK:
451
      *write_method = write_usmUserSpinLock;
452
      long_ret = usmUserSpinLock;
453
      return (unsigned char *) &long_ret;
454
 
455
    case USMUSERSECURITYNAME:
456
      if (uptr) {
457
        *var_len = strlen(uptr->secName);
458
        return (unsigned char *) uptr->secName;
459
      }
460
      return NULL;
461
 
462
    case USMUSERCLONEFROM:
463
      *write_method = write_usmUserCloneFrom;
464
      if (uptr) {
465
        objid[0] = 0; /* "When this object is read, the ZeroDotZero OID */
466
        objid[1] = 0; /*  is returned." */
467
        *var_len = sizeof(oid)*2;
468
        return (unsigned char *) objid;
469
      }
470
      return NULL;
471
 
472
    case USMUSERAUTHPROTOCOL:
473
      *write_method = write_usmUserAuthProtocol;
474
      if (uptr) {
475
        *var_len = uptr->authProtocolLen*sizeof(oid);
476
        return (u_char *)uptr->authProtocol;
477
      }
478
      return NULL;
479
 
480
    case USMUSERAUTHKEYCHANGE:
481
    case USMUSEROWNAUTHKEYCHANGE:
482
 
483
      /* we treat these the same, and let the calling module
484
         distinguish between them */
485
      *write_method = write_usmUserAuthKeyChange;
486
      if (uptr) {
487
        *string = 0; /* always return a NULL string */
488
        *var_len = 0;
489
        return string;
490
      }
491
      return NULL;
492
 
493
    case USMUSERPRIVPROTOCOL:
494
      *write_method = write_usmUserPrivProtocol;
495
      if (uptr) {
496
        *var_len = uptr->privProtocolLen*sizeof(oid);
497
        return (u_char *)uptr->privProtocol;
498
      }
499
      return NULL;
500
 
501
    case USMUSERPRIVKEYCHANGE:
502
    case USMUSEROWNPRIVKEYCHANGE:
503
      /* we treat these the same, and let the calling module
504
         distinguish between them */
505
      *write_method = write_usmUserPrivKeyChange;
506
      if (uptr) {
507
        *string = 0; /* always return a NULL string */
508
        *var_len = 0;
509
        return string;
510
      }
511
      return NULL;
512
 
513
    case USMUSERPUBLIC:
514
      *write_method = write_usmUserPublic;
515
      if (uptr) {
516
        if (uptr->userPublicString) {
517
          *var_len = strlen((char *)uptr->userPublicString);
518
          return uptr->userPublicString;
519
        }
520
        *string = 0;
521
        *var_len = 0; /* return an empty string if the public
522
                                      string hasn't been defined yet */
523
        return string;
524
      }
525
      return NULL;
526
 
527
    case USMUSERSTORAGETYPE:
528
      *write_method = write_usmUserStorageType;
529
      if (uptr) {
530
        long_ret = uptr->userStorageType;
531
        return (unsigned char *) &long_ret;
532
      }
533
      return NULL;
534
 
535
    case USMUSERSTATUS:
536
      *write_method = write_usmUserStatus;
537
      if (uptr) {
538
        long_ret = uptr->userStatus;
539
        return (unsigned char *) &long_ret;
540
      }
541
      return NULL;
542
 
543
    default:
544
      DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_usmUser\n", vp->magic));
545
  }
546
  return 0;
547
 
548
}  /* end var_usmUser() */
549
 
550
/* write_usmUserSpinLock(): called when a set is performed on the
551
   usmUserSpinLock object */
552
int
553
write_usmUserSpinLock(
554
   int      action,
555
   u_char   *var_val,
556
   u_char   var_val_type,
557
   size_t   var_val_len,
558
   u_char   *statP,
559
   oid      *name,
560
   size_t   name_len)
561
{
562
  /* variables we may use later */
563
  static long long_ret;
564
 
565
  if (var_val_type != ASN_INTEGER){
566
      DEBUGMSGTL(("usmUser","write to usmUserSpinLock not ASN_INTEGER\n"));
567
      return SNMP_ERR_WRONGTYPE;
568
  }
569
  if (var_val_len > sizeof(long_ret)){
570
      DEBUGMSGTL(("usmUser","write to usmUserSpinLock: bad length\n"));
571
      return SNMP_ERR_WRONGLENGTH;
572
  }
573
  long_ret = *((long *) var_val);
574
 
575
  if (long_ret != (long)usmUserSpinLock)
576
    return SNMP_ERR_INCONSISTENTVALUE;
577
 
578
  if (action == COMMIT) {
579
    if (usmUserSpinLock == 2147483647) {
580
      usmUserSpinLock = 0;
581
    } else {
582
      usmUserSpinLock++;
583
    }
584
  }
585
  return SNMP_ERR_NOERROR;
586
}  /* end write_usmUserSpinLock() */
587
 
588
/*******************************************************************-o-******
589
 * write_usmUserCloneFrom
590
 *
591
 * Parameters:
592
 *       action
593
 *      *var_val
594
 *       var_val_type
595
 *       var_val_len
596
 *      *statP          (UNUSED)
597
 *      *name           OID of user to clone from.
598
 *       name_len
599
 *
600
 * Returns:
601
 *      SNMP_ERR_NOERROR                On success  -OR-  If user exists
602
 *                                        and has already been cloned.
603
 *      SNMP_ERR_GENERR                 Local function call failures.
604
 *      SNMP_ERR_INCONSISTENTNAME       'name' does not exist in user list
605
 *                                        -OR-  user to clone from != RS_ACTIVE.
606
 *      SNMP_ERR_WRONGLENGTH            OID length > than local buffer size.
607
 *      SNMP_ERR_WRONGTYPE              ASN_OBJECT_ID is wrong.
608
 *
609
 *
610
 * XXX:  should handle action=UNDO's.
611
 */
612
int
613
write_usmUserCloneFrom(
614
   int      action,
615
   u_char   *var_val,
616
   u_char   var_val_type,
617
   size_t   var_val_len,
618
   u_char   *statP,
619
   oid      *name,
620
   size_t   name_len)
621
{
622
  /* variables we may use later */
623
  static oid objid[USM_LENGTH_OID_MAX], *oidptr;
624
  struct usmUser *uptr, *cloneFrom;
625
  size_t size;
626
 
627
  if (var_val_type != ASN_OBJECT_ID){
628
      DEBUGMSGTL(("usmUser","write to usmUserCloneFrom not ASN_OBJECT_ID\n"));
629
      return SNMP_ERR_WRONGTYPE;
630
  }
631
  if (var_val_len > sizeof(objid)){
632
      DEBUGMSGTL(("usmUser","write to usmUserCloneFrom: bad length\n"));
633
      return SNMP_ERR_WRONGLENGTH;
634
  }
635
  if (action == COMMIT){
636
    /* parse the clonefrom objid */
637
    size = var_val_len/sizeof(oid);
638
    memcpy(objid, var_val, var_val_len);
639
 
640
    if ((uptr = usm_parse_user(name, name_len)) == NULL)
641
      /* We don't allow creations here */
642
      return SNMP_ERR_INCONSISTENTNAME;
643
 
644
    /* have the user already been cloned?  If so, second cloning is
645
       not allowed, but does not generate an error */
646
    if (uptr->cloneFrom)
647
      return SNMP_ERR_NOERROR;
648
 
649
    /* does the cloneFrom user exist? */
650
    if ((cloneFrom = usm_parse_user(objid, size)) == NULL)
651
      /* We don't allow creations here */
652
      return SNMP_ERR_INCONSISTENTNAME;
653
 
654
    /* is it active */
655
    if (cloneFrom->userStatus != RS_ACTIVE)
656
      return SNMP_ERR_INCONSISTENTNAME;
657
 
658
    /* set the cloneFrom OID */
659
    if ((oidptr = snmp_duplicate_objid(objid, size/sizeof(oid))) == NULL)
660
      return SNMP_ERR_GENERR;
661
 
662
    /* do the actual cloning */
663
 
664
    if (uptr->cloneFrom)
665
      free(uptr->cloneFrom);
666
    uptr->cloneFrom = oidptr;
667
 
668
    usm_cloneFrom_user(cloneFrom, uptr);
669
 
670
  }  /* endif: action == COMMIT */
671
 
672
  return SNMP_ERR_NOERROR;
673
 
674
 
675
}  /* end write_usmUserCloneFrom() */
676
 
677
/*******************************************************************-o-******
678
 * write_usmUserAuthProtocol
679
 *
680
 * Parameters:
681
 *       action
682
 *      *var_val        OID of auth transform to set.
683
 *       var_val_type
684
 *       var_val_len
685
 *      *statP
686
 *      *name           OID of user upon which to perform set operation.
687
 *       name_len
688
 *
689
 * Returns:
690
 *      SNMP_ERR_NOERROR                On success.
691
 *      SNMP_ERR_GENERR
692
 *      SNMP_ERR_INCONSISTENTVALUE
693
 *      SNMP_ERR_NOSUCHNAME
694
 *      SNMP_ERR_WRONGLENGTH
695
 *      SNMP_ERR_WRONGTYPE
696
 */
697
int
698
write_usmUserAuthProtocol(
699
   int      action,
700
   u_char   *var_val,
701
   u_char   var_val_type,
702
   size_t   var_val_len,
703
   u_char   *statP,
704
   oid      *name,
705
   size_t   name_len)
706
{
707
  /* variables we may use later */
708
  static oid objid[USM_LENGTH_OID_MAX];
709
  static oid *optr;
710
  struct usmUser *uptr;
711
  size_t size;
712
 
713
  if (var_val_type != ASN_OBJECT_ID){
714
      DEBUGMSGTL(("usmUser","write to usmUserAuthProtocol not ASN_OBJECT_ID\n"));
715
      return SNMP_ERR_WRONGTYPE;
716
  }
717
  if (var_val_len > sizeof(objid)){
718
      DEBUGMSGTL(("usmUser","write to usmUserAuthProtocol: bad length\n"));
719
      return SNMP_ERR_WRONGLENGTH;
720
  }
721
  if (action == COMMIT){
722
      size = var_val_len/sizeof(oid);
723
      memcpy(objid, var_val, var_val_len);
724
 
725
      /* don't allow creations here */
726
      if ((uptr = usm_parse_user(name, name_len)) == NULL)
727
        return SNMP_ERR_NOSUCHNAME;
728
 
729
      /* check the objid for validity */
730
      /* only allow sets to perform a change to usmNoAuthProtocol */
731
      if (snmp_oid_compare(objid, size, usmNoAuthProtocol,
732
                  sizeof(usmNoAuthProtocol)/sizeof(oid)) != 0)
733
        return SNMP_ERR_INCONSISTENTVALUE;
734
 
735
      /* if the priv protocol is not usmNoPrivProtocol, we can't change */
736
      if (snmp_oid_compare(uptr->privProtocol, uptr->privProtocolLen, usmNoPrivProtocol,
737
                  sizeof(usmNoPrivProtocol)/sizeof(oid)) != 0)
738
        return SNMP_ERR_INCONSISTENTVALUE;
739
 
740
      /* finally, we can do it */
741
      optr = uptr->authProtocol;
742
      if ((uptr->authProtocol = snmp_duplicate_objid(objid, size))
743
          == NULL) {
744
        uptr->authProtocol = optr;
745
        return SNMP_ERR_GENERR;
746
      }
747
      free(optr);
748
      uptr->authProtocolLen = size;
749
  }
750
  return SNMP_ERR_NOERROR;
751
}  /* end write_usmUserAuthProtocol() */
752
 
753
/*******************************************************************-o-******
754
 * write_usmUserAuthKeyChange
755
 *
756
 * Parameters:
757
 *       action
758
 *      *var_val        Octet string representing new KeyChange value.
759
 *       var_val_type
760
 *       var_val_len
761
 *      *statP          (UNUSED)
762
 *      *name           OID of user upon which to perform set operation.
763
 *       name_len
764
 *
765
 * Returns:
766
 *      SNMP_ERR_NOERR          Success.
767
 *      SNMP_ERR_WRONGTYPE
768
 *      SNMP_ERR_WRONGLENGTH
769
 *      SNMP_ERR_NOSUCHNAME
770
 *      SNMP_ERR_GENERR
771
 *
772
 * Note: This function handles both the usmUserAuthKeyChange and
773
 *       usmUserOwnAuthKeyChange objects.  We are not passed the name
774
 *       of the user requseting the keychange, so we leave this to the
775
 *       calling module to verify when and if we should be called.  To
776
 *       change this would require a change in the mib module API to
777
 *       pass in the securityName requesting the change.
778
 *
779
 * XXX:  should handle action=UNDO's.
780
 */
781
int
782
write_usmUserAuthKeyChange(
783
   int      action,
784
   u_char   *var_val,
785
   u_char   var_val_type,
786
   size_t   var_val_len,
787
   u_char   *statP,
788
   oid      *name,
789
   size_t   name_len)
790
{
791
    static unsigned char   string[SNMP_MAXBUF_SMALL];
792
  struct usmUser        *uptr;
793
  unsigned char          buf[SNMP_MAXBUF_SMALL];
794
  size_t                 buflen = SNMP_MAXBUF_SMALL;
795
 
796
  char                  fnAuthKey[]    = "write_usmUserAuthKeyChange",
797
                        fnOwnAuthKey[] = "write_usmUserOwnAuthKeyChange",
798
                        *fname;
799
 
800
  if (name[USM_MIB_LENGTH-1] == 6)
801
    fname = fnAuthKey;
802
  else
803
    fname = fnOwnAuthKey;
804
 
805
  if (var_val_type != ASN_OCTET_STR) {
806
    DEBUGMSGTL(("usmUser","write to %s not ASN_OCTET_STR\n", fname));
807
    return SNMP_ERR_WRONGTYPE;
808
  }
809
 
810
  if (var_val_len > sizeof(string)) {
811
    DEBUGMSGTL(("usmUser","write to %s: bad length\n", fname));
812
    return SNMP_ERR_WRONGLENGTH;
813
  }
814
 
815
  if (action == COMMIT) {
816
    /* don't allow creations here */
817
    if ((uptr = usm_parse_user(name, name_len)) == NULL) {
818
      return SNMP_ERR_NOSUCHNAME;
819
    }
820
 
821
    /* Change the key. */
822
    DEBUGMSGTL(("usmUser","%s: changing auth key for user %s\n", fname, uptr->secName));
823
 
824
    if (decode_keychange(uptr->authProtocol, uptr->authProtocolLen,
825
                         uptr->authKey, uptr->authKeyLen,
826
                         var_val, var_val_len,
827
                         buf, &buflen) != SNMPERR_SUCCESS) {
828
      DEBUGMSGTL(("usmUser","%s: ... failed\n", fname));
829
        return SNMP_ERR_GENERR;
830
    }
831
    DEBUGMSGTL(("usmUser","%s: ... succeeded\n", fname));
832
    SNMP_FREE(uptr->authKey);
833
    memdup(&uptr->authKey, buf, buflen);
834
    uptr->authKeyLen = buflen;
835
  }
836
 
837
  return SNMP_ERR_NOERROR;
838
} /* end write_usmUserAuthKeyChange() */
839
 
840
int
841
write_usmUserPrivProtocol(
842
   int      action,
843
   u_char   *var_val,
844
   u_char   var_val_type,
845
   size_t   var_val_len,
846
   u_char   *statP,
847
   oid      *name,
848
   size_t   name_len)
849
{
850
  /* variables we may use later */
851
  static oid objid[USM_LENGTH_OID_MAX];
852
  static oid *optr;
853
  struct usmUser *uptr;
854
  size_t size;
855
 
856
  if (var_val_type != ASN_OBJECT_ID){
857
      DEBUGMSGTL(("usmUser","write to usmUserPrivProtocol not ASN_OBJECT_ID\n"));
858
      return SNMP_ERR_WRONGTYPE;
859
  }
860
  if (var_val_len > sizeof(objid)){
861
      DEBUGMSGTL(("usmUser","write to usmUserPrivProtocol: bad length\n"));
862
      return SNMP_ERR_WRONGLENGTH;
863
  }
864
  if (action == COMMIT){
865
      size = var_val_len/sizeof(oid);
866
      memcpy(objid, var_val, var_val_len);
867
 
868
      /* don't allow creations here */
869
      if ((uptr = usm_parse_user(name, name_len)) == NULL)
870
        return SNMP_ERR_NOSUCHNAME;
871
 
872
      /* check the objid for validity */
873
      /* only allow sets to perform a change to usmNoPrivProtocol */
874
      if (snmp_oid_compare(objid, size, usmNoPrivProtocol,
875
                  sizeof(usmNoPrivProtocol)/sizeof(oid)) != 0)
876
        return SNMP_ERR_INCONSISTENTVALUE;
877
 
878
      /* finally, we can do it */
879
      optr = uptr->privProtocol;
880
      if ((uptr->privProtocol = snmp_duplicate_objid(objid, size))
881
          == NULL) {
882
        uptr->privProtocol = optr;
883
        return SNMP_ERR_GENERR;
884
      }
885
      free(optr);
886
      uptr->privProtocolLen = size;
887
  }
888
  return SNMP_ERR_NOERROR;
889
}  /* end write_usmUserPrivProtocol() */
890
 
891
/*
892
 * Note: This function handles both the usmUserPrivKeyChange and
893
 *       usmUserOwnPrivKeyChange objects.  We are not passed the name
894
 *       of the user requseting the keychange, so we leave this to the
895
 *       calling module to verify when and if we should be called.  To
896
 *       change this would require a change in the mib module API to
897
 *       pass in the securityName requesting the change.
898
 *
899
 */
900
int
901
write_usmUserPrivKeyChange(
902
   int      action,
903
   u_char   *var_val,
904
   u_char   var_val_type,
905
   size_t   var_val_len,
906
   u_char   *statP,
907
   oid      *name,
908
   size_t   name_len)
909
{
910
  static unsigned char   string[SNMP_MAXBUF_SMALL];
911
  struct usmUser        *uptr;
912
  unsigned char          buf[SNMP_MAXBUF_SMALL];
913
  size_t                 buflen = SNMP_MAXBUF_SMALL;
914
 
915
  char                  fnPrivKey[]    = "write_usmUserPrivKeyChange",
916
                        fnOwnPrivKey[] = "write_usmUserOwnPrivKeyChange",
917
                        *fname;
918
 
919
  if (name[USM_MIB_LENGTH-1] == 9)
920
    fname = fnPrivKey;
921
  else
922
    fname = fnOwnPrivKey;
923
 
924
  if (var_val_type != ASN_OCTET_STR) {
925
    DEBUGMSGTL(("usmUser","write to %s not ASN_OCTET_STR\n", fname));
926
    return SNMP_ERR_WRONGTYPE;
927
  }
928
 
929
  if (var_val_len > sizeof(string)) {
930
    DEBUGMSGTL(("usmUser","write to %s: bad length\n", fname));
931
    return SNMP_ERR_WRONGLENGTH;
932
  }
933
 
934
  if (action == COMMIT) {
935
    /* don't allow creations here */
936
    if ((uptr = usm_parse_user(name, name_len)) == NULL) {
937
      return SNMP_ERR_NOSUCHNAME;
938
    }
939
 
940
    /* Change the key. */
941
    DEBUGMSGTL(("usmUser","%s: changing priv key for user %s\n", fname, uptr->secName));
942
 
943
    if (decode_keychange(uptr->authProtocol, uptr->authProtocolLen,
944
                         uptr->privKey, uptr->privKeyLen,
945
                         var_val, var_val_len,
946
                         buf, &buflen) != SNMPERR_SUCCESS) {
947
      DEBUGMSGTL(("usmUser","%s: ... failed\n", fname));
948
        return SNMP_ERR_GENERR;
949
    }
950
    DEBUGMSGTL(("usmUser","%s: ... succeeded\n", fname));
951
    SNMP_FREE(uptr->privKey);
952
    memdup(&uptr->privKey, buf, buflen);
953
    uptr->privKeyLen = buflen;
954
  }
955
 
956
  return SNMP_ERR_NOERROR;
957
}  /* end write_usmUserPrivKeyChange() */
958
 
959
int
960
write_usmUserPublic(
961
   int      action,
962
   u_char   *var_val,
963
   u_char   var_val_type,
964
   size_t   var_val_len,
965
   u_char   *statP,
966
   oid      *name,
967
   size_t   name_len)
968
{
969
  /* variables we may use later */
970
  static unsigned char string[SNMP_MAXBUF];
971
 
972
  struct usmUser *uptr;
973
 
974
  if (var_val_type != ASN_OCTET_STR){
975
      DEBUGMSGTL(("usmUser","write to usmUserPublic not ASN_OCTET_STR\n"));
976
      return SNMP_ERR_WRONGTYPE;
977
  }
978
  if (var_val_len > sizeof(string)){
979
      DEBUGMSGTL(("usmUser","write to usmUserPublic: bad length\n"));
980
      return SNMP_ERR_WRONGLENGTH;
981
  }
982
  if (action == COMMIT) {
983
    /* don't allow creations here */
984
    if ((uptr = usm_parse_user(name, name_len)) == NULL) {
985
      return SNMP_ERR_NOSUCHNAME;
986
    }
987
    if (uptr->userPublicString)
988
      free(uptr->userPublicString);
989
    uptr->userPublicString = (u_char *) malloc(var_val_len+1);
990
    if (uptr->userPublicString == NULL) {
991
      return SNMP_ERR_GENERR;
992
    }
993
    memcpy(uptr->userPublicString, var_val, var_val_len);
994
    uptr->userPublicString[var_val_len] = 0;
995
    DEBUGMSG(("usmUser", "setting public string: %d - %s\n", var_val_len,
996
              uptr->userPublicString));
997
  }
998
  return SNMP_ERR_NOERROR;
999
}  /* end write_usmUserPublic() */
1000
 
1001
int
1002
write_usmUserStorageType(
1003
   int      action,
1004
   u_char   *var_val,
1005
   u_char   var_val_type,
1006
   size_t   var_val_len,
1007
   u_char   *statP,
1008
   oid      *name,
1009
   size_t   name_len)
1010
{
1011
  /* variables we may use later */
1012
  static long long_ret;
1013
  struct usmUser *uptr;
1014
 
1015
  if (var_val_type != ASN_INTEGER){
1016
      DEBUGMSGTL(("usmUser","write to usmUserStorageType not ASN_INTEGER\n"));
1017
      return SNMP_ERR_WRONGTYPE;
1018
  }
1019
  if (var_val_len > sizeof(long_ret)){
1020
      DEBUGMSGTL(("usmUser","write to usmUserStorageType: bad length\n"));
1021
      return SNMP_ERR_WRONGLENGTH;
1022
  }
1023
  if (action == COMMIT){
1024
      /* don't allow creations here */
1025
      if ((uptr = usm_parse_user(name, name_len)) == NULL) {
1026
        return SNMP_ERR_NOSUCHNAME;
1027
      }
1028
      long_ret = *((long *) var_val);
1029
      if ((long_ret == ST_VOLATILE || long_ret == ST_NONVOLATILE) &&
1030
          (uptr->userStorageType == ST_VOLATILE ||
1031
           uptr->userStorageType == ST_NONVOLATILE))
1032
        uptr->userStorageType = long_ret;
1033
      else
1034
        return SNMP_ERR_INCONSISTENTVALUE;
1035
  }
1036
  return SNMP_ERR_NOERROR;
1037
}  /* end write_usmUserStorageType() */
1038
 
1039
/*******************************************************************-o-******
1040
 * write_usmUserStatus
1041
 *
1042
 * Parameters:
1043
 *       action
1044
 *      *var_val
1045
 *       var_val_type
1046
 *       var_val_len
1047
 *      *statP
1048
 *      *name
1049
 *       name_len
1050
 *
1051
 * Returns:
1052
 *      SNMP_ERR_NOERROR                On success.
1053
 *      SNMP_ERR_GENERR
1054
 *      SNMP_ERR_INCONSISTENTNAME
1055
 *      SNMP_ERR_INCONSISTENTVALUE
1056
 *      SNMP_ERR_WRONGLENGTH
1057
 *      SNMP_ERR_WRONGTYPE
1058
 */
1059
int
1060
write_usmUserStatus(
1061
   int      action,
1062
   u_char   *var_val,
1063
   u_char   var_val_type,
1064
   size_t   var_val_len,
1065
   u_char   *statP,
1066
   oid      *name,
1067
   size_t   name_len)
1068
{
1069
  /* variables we may use later */
1070
  static long long_ret;
1071
  unsigned char *engineID;
1072
  size_t engineIDLen;
1073
  char *newName;
1074
  size_t nameLen;
1075
  struct usmUser *uptr;
1076
 
1077
  if (var_val_type != ASN_INTEGER){
1078
      DEBUGMSGTL(("usmUser","write to usmUserStatus not ASN_INTEGER\n"));
1079
      return SNMP_ERR_WRONGTYPE;
1080
  }
1081
  if (var_val_len > sizeof(long_ret)){
1082
      DEBUGMSGTL(("usmUser","write to usmUserStatus: bad length\n"));
1083
      return SNMP_ERR_WRONGLENGTH;
1084
  }
1085
  if (action == COMMIT){
1086
    long_ret = *((long *) var_val);
1087
 
1088
    /* ditch illegal values now */
1089
    /* notReady can not be used, but the return error code is not mentioned */
1090
    if (long_ret == RS_NOTREADY || long_ret < 1 || long_ret > 6)
1091
      return SNMP_ERR_INCONSISTENTVALUE;
1092
 
1093
    /* see if we can parse the oid for engineID/name first */
1094
    if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len-USM_MIB_LENGTH,
1095
                      &engineID, &engineIDLen, (u_char **)&newName, &nameLen))
1096
      return SNMP_ERR_INCONSISTENTNAME;
1097
 
1098
    /* Now see if a user already exists with these index values */
1099
    uptr = usm_get_user(engineID, engineIDLen, newName);
1100
 
1101
 
1102
    if (uptr) {                 /* If so, we set the appropriate value... */
1103
      free(engineID);
1104
      free(newName);
1105
      if (long_ret == RS_CREATEANDGO || long_ret == RS_CREATEANDWAIT) {
1106
        return SNMP_ERR_INCONSISTENTVALUE;
1107
      }
1108
      if (long_ret == RS_DESTROY) {
1109
        usm_remove_user(uptr);
1110
        usm_free_user(uptr);
1111
      } else {
1112
        uptr->userStatus = long_ret;
1113
      }
1114
 
1115
    } else {                    /* ...else we create a new user */
1116
      /* check for a valid status column set */
1117
      if (long_ret == RS_ACTIVE || long_ret == RS_NOTINSERVICE) {
1118
        free(engineID);
1119
        free(newName);
1120
        return SNMP_ERR_INCONSISTENTVALUE;
1121
      }
1122
      if (long_ret == RS_DESTROY) {
1123
        /* destroying a non-existent row is actually legal */
1124
        free(engineID);
1125
        free(newName);
1126
        return SNMP_ERR_NOERROR;
1127
      }
1128
 
1129
      /* generate a new user */
1130
      if ((uptr = usm_create_user()) == NULL) {
1131
        free(engineID);
1132
        free(newName);
1133
        return SNMP_ERR_GENERR;
1134
      }
1135
 
1136
      /* copy in the engineID */
1137
      uptr->engineID =
1138
        (unsigned char *) malloc(engineIDLen);
1139
      if (uptr->engineID == NULL) {
1140
        free(engineID);
1141
        free(newName);
1142
        usm_free_user(uptr);
1143
        return SNMP_ERR_GENERR;
1144
      }
1145
      uptr->engineIDLen = engineIDLen;
1146
      memcpy(uptr->engineID, engineID, engineIDLen);
1147
      free(engineID);
1148
 
1149
      /* copy in the name and secname */
1150
      if ((uptr->name = strdup(newName)) == NULL) {
1151
        free(newName);
1152
        usm_free_user(uptr);
1153
        return SNMP_ERR_GENERR;
1154
      }
1155
      free(newName);
1156
      if ((uptr->secName = strdup(uptr->name)) == NULL) {
1157
        usm_free_user(uptr);
1158
        return SNMP_ERR_GENERR;
1159
      }
1160
 
1161
      /* set the status of the row based on the request */
1162
      if (long_ret == RS_CREATEANDGO)
1163
        uptr->userStatus = RS_ACTIVE;
1164
      else if (long_ret == RS_CREATEANDWAIT)
1165
        uptr->userStatus = RS_NOTINSERVICE;
1166
 
1167
      /* finally, add it to our list of users */
1168
      usm_add_user(uptr);
1169
 
1170
    }  /* endif -- uptr */
1171
  }  /* endif -- action==COMMIT */
1172
 
1173
  return SNMP_ERR_NOERROR;
1174
 
1175
}  /* end write_usmUserStatus() */
1176
 
1177
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

powered by: WebSVN 2.1.0

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