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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [snmp/] [agent/] [current/] [src/] [mibgroup/] [snmpv3/] [usmUser.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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