Coverage Report

Created: 2024-09-11 06:05

/src/net-snmp/snmplib/snmp_parse_args.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * snmp_parse_args.c
3
 */
4
/* Portions of this file are subject to the following copyright(s).  See
5
 * the Net-SNMP's COPYING file for more details and other copyrights
6
 * that may apply:
7
 */
8
/*
9
 * Portions of this file are copyrighted by:
10
 * Copyright @ 2003 Sun Microsystems, Inc. All rights reserved.
11
 * Use is subject to license terms specified in the COPYING file
12
 * distributed with the Net-SNMP package.
13
 *
14
 * Portions of this file are copyrighted by:
15
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
16
 * Use is subject to license terms specified in the COPYING file
17
 * distributed with the Net-SNMP package.
18
 */
19
20
#include <net-snmp/net-snmp-config.h>
21
#include <errno.h>
22
23
#ifdef HAVE_STDLIB_H
24
#include <stdlib.h>
25
#endif
26
#ifdef HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#ifdef HAVE_STRING_H
30
#include <string.h>
31
#else
32
#include <strings.h>
33
#endif
34
#include <sys/types.h>
35
#include <stdio.h>
36
#ifdef HAVE_UNISTD_H
37
#include <unistd.h>
38
#endif
39
#include <ctype.h>
40
#ifdef HAVE_NETINET_IN_H
41
#include <netinet/in.h>
42
#endif
43
#ifdef TIME_WITH_SYS_TIME
44
# include <sys/time.h>
45
# include <time.h>
46
#else
47
# ifdef HAVE_SYS_TIME_H
48
#  include <sys/time.h>
49
# else
50
#  include <time.h>
51
# endif
52
#endif
53
#ifdef HAVE_SYS_SELECT_H
54
#include <sys/select.h>
55
#endif
56
#ifdef HAVE_NETDB_H
57
#include <netdb.h>
58
#endif
59
#ifdef HAVE_ARPA_INET_H
60
#include <arpa/inet.h>
61
#endif
62
63
#include <net-snmp/net-snmp-includes.h>
64
#include <net-snmp/types.h>
65
#include <net-snmp/output_api.h>
66
#include <net-snmp/config_api.h>
67
#include <net-snmp/library/snmpv3.h>
68
#include <net-snmp/library/snmp_parse_args.h>   /* for "internal" definitions */
69
#include <net-snmp/utilities.h>
70
71
#include <net-snmp/library/snmp_api.h>
72
#include <net-snmp/library/snmp_client.h>
73
#include <net-snmp/library/mib.h>
74
#include <net-snmp/library/scapi.h>
75
#include <net-snmp/library/keytools.h>
76
77
#include <net-snmp/version.h>
78
#include <net-snmp/library/parse.h>
79
#include <net-snmp/library/snmpv3.h>
80
#include <net-snmp/library/transform_oids.h>
81
82
void
83
snmp_parse_args_usage(FILE * outf)
84
0
{
85
0
    fprintf(outf, "[OPTIONS] AGENT");
86
0
}
87
88
void
89
snmp_parse_args_descriptions(FILE * outf)
90
0
{
91
0
    fprintf(outf, "  Version:  %s\n", netsnmp_get_version());
92
0
    fprintf(outf, "  Web:      http://www.net-snmp.org/\n");
93
0
    fprintf(outf,
94
0
            "  Email:    net-snmp-coders@lists.sourceforge.net\n\nOPTIONS:\n");
95
0
    fprintf(outf, "  -h, --help\t\tdisplay this help message\n");
96
0
    fprintf(outf,
97
0
            "  -H\t\t\tdisplay configuration file directives understood\n");
98
0
    fprintf(outf, "  -v 1|2c|3\t\tspecifies SNMP version to use\n");
99
0
    fprintf(outf, "  -V, --version\t\tdisplay package version number\n");
100
0
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
101
0
    fprintf(outf, "SNMP Version 1 or 2c specific\n");
102
0
    fprintf(outf, "  -c COMMUNITY\t\tset the community string\n");
103
0
#endif /* support for community based SNMP */
104
0
    fprintf(outf, "SNMP Version 3 specific\n");
105
0
    fprintf(outf,
106
0
            "  -a PROTOCOL\t\tset authentication protocol (MD5|SHA|SHA-224|SHA-256|SHA-384|SHA-512)\n");
107
0
    fprintf(outf,
108
0
            "  -A PASSPHRASE\t\tset authentication protocol pass phrase\n");
109
0
    fprintf(outf,
110
0
            "  -e ENGINE-ID\t\tset security engine ID (e.g. 800000020109840301)\n");
111
0
    fprintf(outf,
112
0
            "  -E ENGINE-ID\t\tset context engine ID (e.g. 800000020109840301)\n");
113
0
    fprintf(outf,
114
0
            "  -l LEVEL\t\tset security level (noAuthNoPriv|authNoPriv|authPriv)\n");
115
0
    fprintf(outf, "  -n CONTEXT\t\tset context name (e.g. bridge1)\n");
116
0
    fprintf(outf, "  -u USER-NAME\t\tset security name (e.g. bert)\n");
117
0
#ifdef HAVE_AES
118
0
    fprintf(outf, "  -x PROTOCOL\t\tset privacy protocol (DES|AES"
119
0
#ifdef NETSNMP_DRAFT_BLUMENTHAL_AES_04
120
0
            "|AES-192|AES-256"
121
0
#endif
122
0
            ")\n");
123
#else
124
    fprintf(outf, "  -x PROTOCOL\t\tset privacy protocol (DES)\n");
125
#endif
126
0
    fprintf(outf, "  -X PASSPHRASE\t\tset privacy protocol pass phrase\n");
127
0
    fprintf(outf,
128
0
            "  -Z BOOTS,TIME\t\tset destination engine boots/time\n");
129
0
    fprintf(outf, "General communication options\n");
130
0
    fprintf(outf, "  -r RETRIES\t\tset the number of retries\n");
131
0
    fprintf(outf,
132
0
            "  -t TIMEOUT\t\tset the request timeout (in seconds)\n");
133
0
    fprintf(outf, "Debugging\n");
134
0
    fprintf(outf, "  -d\t\t\tdump input/output packets in hexadecimal\n");
135
0
#ifndef NETSNMP_DISABLE_DEBUGGING
136
0
    fprintf(outf,
137
0
            "  -D[TOKEN[,...]]\tturn on debugging output for the specified TOKENs\n\t\t\t   (ALL gives extremely verbose debugging output)\n");
138
0
#endif
139
0
    fprintf(outf, "General options\n");
140
0
    fprintf(outf,
141
0
            "  -m MIB[" ENV_SEPARATOR "...]\t\tload given list of MIBs (ALL loads everything)\n");
142
0
    fprintf(outf,
143
0
            "  -M DIR[" ENV_SEPARATOR "...]\t\tlook in given list of directories for MIBs\n");
144
0
#ifndef NETSNMP_DISABLE_MIB_LOADING
145
0
    fprintf(outf,
146
0
            "    (default: %s)\n", netsnmp_get_mib_directory());
147
0
    fprintf(outf,
148
0
            "  -P MIBOPTS\t\tToggle various defaults controlling MIB parsing:\n");
149
0
    snmp_mib_toggle_options_usage("\t\t\t  ", outf);
150
0
#endif
151
0
    fprintf(outf,
152
0
            "  -O OUTOPTS\t\tToggle various defaults controlling output display:\n");
153
0
    snmp_out_toggle_options_usage("\t\t\t  ", outf);
154
0
    fprintf(outf,
155
0
            "  -I INOPTS\t\tToggle various defaults controlling input parsing:\n");
156
0
    snmp_in_toggle_options_usage("\t\t\t  ", outf);
157
0
    fprintf(outf,
158
0
            "  -L LOGOPTS\t\tToggle various defaults controlling logging:\n");
159
0
    snmp_log_options_usage("\t\t\t  ", outf);
160
0
    fflush(outf);
161
0
}
162
163
#define BUF_SIZE 512
164
165
void
166
handle_long_opt(const char *myoptarg)
167
0
{
168
0
    char           *cp, *cp2;
169
    /*
170
     * else it's a long option, so process it like name=value 
171
     */
172
0
    cp = (char *)malloc(strlen(myoptarg) + 3);
173
0
    if (!cp)
174
0
        return;
175
0
    strcpy(cp, myoptarg);
176
0
    cp2 = strchr(cp, '=');
177
0
    if (!cp2 && !strchr(cp, ' ')) {
178
        /*
179
         * well, they didn't specify an argument as far as we
180
         * can tell.  Give them a '1' as the argument (which
181
         * works for boolean tokens and a few others) and let
182
         * them suffer from there if it's not what they
183
         * wanted 
184
         */
185
0
        strcat(cp, " 1");
186
0
    } else {
187
        /*
188
         * replace the '=' with a ' ' 
189
         */
190
0
        if (cp2)
191
0
            *cp2 = ' ';
192
0
    }
193
0
    netsnmp_config(cp);
194
0
    free(cp);
195
0
}
196
197
int
198
netsnmp_parse_args(int argc,
199
                   char **argv,
200
                   netsnmp_session * session, const char *localOpts,
201
                   void (*proc) (int, char *const *, int),
202
                   int flags)
203
1.76k
{
204
1.76k
    int             arg, ret, sp = 0;
205
1.76k
    const char     *cp;
206
1.76k
    char           *Apsz = NULL;
207
1.76k
    char           *Xpsz = NULL;
208
1.76k
    char           *Cpsz = NULL;
209
1.76k
    char            Opts[BUF_SIZE];
210
1.76k
    int             zero_sensitive = !( flags & NETSNMP_PARSE_ARGS_NOZERO );
211
1.76k
    char           *backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = NULL;
212
213
    /*
214
     * initialize session to default values 
215
     */
216
1.76k
    snmp_sess_init(session);
217
1.76k
    strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:L:s:");
218
1.76k
    if (localOpts) {
219
1.76k
        if (strlen(localOpts) + strlen(Opts) >= sizeof(Opts)) {
220
0
            snmp_log(LOG_ERR, "Too many localOpts in snmp_parse_args()\n");
221
0
            return -1;
222
0
        }
223
1.76k
        strcat(Opts, localOpts);
224
1.76k
    }
225
226
    /*
227
     * get the options 
228
     */
229
1.76k
    DEBUGMSGTL(("snmp_parse_args", "starting: %d/%d\n", optind, argc));
230
7.04k
    for (arg = 0; arg < argc; arg++) {
231
5.28k
        DEBUGMSGTL(("snmp_parse_args", " arg %d = %s\n", arg, argv[arg]));
232
5.28k
    }
233
234
1.76k
    optind = 1;
235
3.52k
    while (optind < argc && (arg = getopt(argc, argv, Opts)) != EOF) {
236
1.76k
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %c (optarg %s) (sp %d)\n",
237
1.76k
                    optind, arg, optarg, sp));
238
1.76k
        switch (arg) {
239
0
        case '-':
240
0
            if (strcasecmp(optarg, "help") == 0) {
241
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
242
0
                goto out;
243
0
            }
244
0
            if (strcasecmp(optarg, "version") == 0) {
245
0
                fprintf(stderr,"NET-SNMP version: %s\n",netsnmp_get_version());
246
0
                ret = NETSNMP_PARSE_ARGS_SUCCESS_EXIT;
247
0
                goto out;
248
0
            }
249
250
0
            handle_long_opt(optarg);
251
0
            break;
252
253
0
        case 'V':
254
0
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
255
0
            ret = NETSNMP_PARSE_ARGS_SUCCESS_EXIT;
256
0
            goto out;
257
258
0
        case 'h':
259
0
            ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
260
0
            goto out;
261
262
0
        case 'H':
263
0
            init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE);
264
0
            fprintf(stderr, "Configuration directives understood:\n");
265
0
            read_config_print_usage("  ");
266
0
            ret = NETSNMP_PARSE_ARGS_SUCCESS_EXIT;
267
0
            goto out;
268
269
0
        case 'Y':
270
0
            netsnmp_config_remember(optarg);
271
0
            break;
272
273
0
#ifndef NETSNMP_DISABLE_MIB_LOADING
274
0
        case 'm':
275
0
            setenv("MIBS", optarg, 1);
276
0
            break;
277
278
0
        case 'M':
279
0
            netsnmp_get_mib_directory(); /* prepare the default directories */
280
0
            netsnmp_set_mib_directory(optarg);
281
0
            break;
282
0
#endif /* NETSNMP_DISABLE_MIB_LOADING */
283
284
0
        case 'O':
285
0
            cp = snmp_out_options(optarg, argc, argv);
286
0
            if (cp != NULL) {
287
0
                fprintf(stderr, "Unknown output option passed to -O: %c.\n", 
288
0
      *cp);
289
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
290
0
                goto out;
291
0
            }
292
0
            break;
293
294
0
        case 'I':
295
0
            cp = snmp_in_options(optarg, argc, argv);
296
0
            if (cp != NULL) {
297
0
                fprintf(stderr, "Unknown input option passed to -I: %c.\n",
298
0
      *cp);
299
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
300
0
                goto out;
301
0
            }
302
0
            break;
303
304
0
#ifndef NETSNMP_DISABLE_MIB_LOADING
305
0
        case 'P':
306
0
            cp = snmp_mib_toggle_options(optarg);
307
0
            if (cp != NULL) {
308
0
                fprintf(stderr,
309
0
                        "Unknown parsing option passed to -P: %c.\n", *cp);
310
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
311
0
                goto out;
312
0
            }
313
0
            break;
314
0
#endif /* NETSNMP_DISABLE_MIB_LOADING */
315
316
1.76k
        case 'D':
317
#ifdef NETSNMP_NO_DEBUGGING
318
            fprintf(stderr, "Debug not configured in\n");
319
            ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
320
            goto out;
321
#else
322
1.76k
            debug_register_tokens(optarg);
323
1.76k
            snmp_set_do_debugging(1);
324
1.76k
#endif
325
1.76k
            break;
326
327
0
        case 'd':
328
0
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, 
329
0
           NETSNMP_DS_LIB_DUMP_PACKET, 1);
330
0
            break;
331
332
0
        case 's':
333
0
            session->localname = strdup(optarg);
334
0
            break;
335
336
0
        case 'v':
337
0
            session->version = -1;
338
0
#ifndef NETSNMP_DISABLE_SNMPV1
339
0
            if (!strcmp(optarg, "1")) {
340
0
                session->version = SNMP_VERSION_1;
341
0
            }
342
0
#endif
343
0
#ifndef NETSNMP_DISABLE_SNMPV2C
344
0
            if (!strcasecmp(optarg, "2c")) {
345
0
                session->version = SNMP_VERSION_2c;
346
0
            }
347
0
#endif
348
0
            if (!strcasecmp(optarg, "3")) {
349
0
                session->version = SNMP_VERSION_3;
350
0
            }
351
0
            if (session->version == -1) {
352
0
                fprintf(stderr,
353
0
                        "Invalid version specified after -v flag: %s\n",
354
0
                        optarg);
355
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
356
0
                goto out;
357
0
            }
358
0
            break;
359
360
0
        case 'p':
361
0
            fprintf(stderr, "Warning: -p option is no longer used - ");
362
0
            fprintf(stderr, "specify the remote host as HOST:PORT\n");
363
0
            ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
364
0
            goto out;
365
366
0
        case 'T':
367
0
        {
368
0
            char leftside[SNMP_MAXBUF_MEDIUM], rightside[SNMP_MAXBUF_MEDIUM];
369
0
            char *tmpcp, *tmpopt;
370
            
371
            /* ensure we have a proper argument */
372
0
            tmpopt = strdup(optarg);
373
0
            tmpcp = strchr(tmpopt, '=');
374
0
            if (!tmpcp) {
375
0
                fprintf(stderr, "-T expects a NAME=VALUE pair.\n");
376
0
                free(tmpopt);
377
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
378
0
                goto out;
379
0
            }
380
0
            *tmpcp++ = '\0';
381
382
            /* create the transport config container if this is the first */
383
0
            if (!session->transport_configuration) {
384
0
                netsnmp_container_init_list();
385
0
                session->transport_configuration =
386
0
                    netsnmp_container_find("transport_configuration:fifo");
387
0
                if (!session->transport_configuration) {
388
0
                    fprintf(stderr, "failed to initialize the transport configuration container\n");
389
0
                    free(tmpopt);
390
0
                    ret = NETSNMP_PARSE_ARGS_ERROR;
391
0
                    goto out;
392
0
                }
393
394
0
                session->transport_configuration->compare =
395
0
                    netsnmp_transport_config_compare;
396
0
            }
397
398
            /* set the config */
399
0
            strlcpy(leftside, tmpopt, sizeof(leftside));
400
0
            strlcpy(rightside, tmpcp, sizeof(rightside));
401
402
0
            CONTAINER_INSERT(session->transport_configuration,
403
0
                             netsnmp_transport_create_config(leftside,
404
0
                                                             rightside));
405
0
            free(tmpopt);
406
0
        }
407
0
        break;
408
            
409
0
        case 't':
410
0
            session->timeout = (long)(atof(optarg) * 1000000L);
411
0
            if (session->timeout <= 0) {
412
0
                fprintf(stderr, "Invalid timeout in seconds after -t flag.\n");
413
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
414
0
                goto out;
415
0
            }
416
0
            break;
417
418
0
        case 'r':
419
0
            session->retries = atoi(optarg);
420
0
            if (session->retries < 0 || !isdigit((unsigned char)(optarg[0]))) {
421
0
                fprintf(stderr, "Invalid number of retries after -r flag.\n");
422
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
423
0
                goto out;
424
0
            }
425
0
            break;
426
427
0
        case 'c':
428
0
      if (zero_sensitive) {
429
0
                SNMP_FREE(Cpsz); /* free any previous value */
430
0
    if ((Cpsz = strdup(optarg)) != NULL) {
431
0
        memset(optarg, '\0', strlen(optarg));
432
0
    } else {
433
0
        fprintf(stderr, "malloc failure processing -c flag.\n");
434
0
        ret = NETSNMP_PARSE_ARGS_ERROR;
435
0
                    goto out;
436
0
    }
437
0
      } else {
438
0
    Cpsz = strdup(optarg);
439
0
      }
440
0
            break;
441
442
0
        case '3':
443
0
            if (snmpv3_parse_args(optarg, session, &Apsz, &Xpsz, argc, argv,
444
0
                                  flags) < 0){
445
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
446
0
                goto out;
447
0
            }
448
0
            break;
449
450
0
        case 'L':
451
0
            if (snmp_log_options(optarg, argc, argv) < 0) {
452
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
453
0
                goto out;
454
0
            }
455
0
            break;
456
457
0
#define SNMPV3_CMD_OPTIONS
458
0
#ifdef  SNMPV3_CMD_OPTIONS
459
0
        case 'Z':
460
0
        case 'e':
461
0
        case 'E':
462
0
        case 'n':
463
0
        case 'l':
464
0
        case 'u':
465
0
#ifdef NETSNMP_SECMOD_USM
466
0
        case 'a':
467
0
        case 'x':
468
0
        case 'A':
469
0
        case 'X':
470
0
#endif             /* NETSNMP_SECMOD_USM */
471
0
            if (snmpv3_parse_arg(arg, optarg, session, &Apsz, &Xpsz, argc,
472
0
                                 argv, flags) < 0){
473
0
                ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
474
0
                goto out;
475
0
            }
476
0
            break;
477
0
#endif                          /* SNMPV3_CMD_OPTIONS */
478
479
0
        case '?':
480
0
            ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
481
0
            goto out;
482
483
0
        default:
484
0
            proc(argc, argv, arg);
485
0
            break;
486
1.76k
        }
487
1.76k
    }
488
1.76k
    DEBUGMSGTL(("snmp_parse_args", "finished: %d/%d\n", optind, argc));
489
    
490
    /*
491
     * save command line parameters which should have precedence above config file settings
492
     *    (There ought to be a more scalable approach than this....)
493
     */
494
1.76k
    if (netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION)) {
495
0
        backup_NETSNMP_DS_LIB_OUTPUT_PRECISION = 
496
0
            strdup(netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION));
497
0
    }
498
499
    /*
500
     * read in MIB database and initialize the snmp library, read the config file
501
     */
502
1.76k
    init_snmp(NETSNMP_APPLICATION_CONFIG_TYPE);
503
504
    /*
505
     * restore command line parameters which should have precedence above config file settings
506
     */
507
1.76k
    if(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION) {
508
0
        netsnmp_ds_set_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OUTPUT_PRECISION, backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
509
0
        free(backup_NETSNMP_DS_LIB_OUTPUT_PRECISION);
510
0
    }
511
512
    /*
513
     * session default version 
514
     */
515
1.76k
    if (session->version == SNMP_DEFAULT_VERSION) {
516
        /*
517
         * run time default version 
518
         */
519
1.76k
        session->version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
520
1.76k
                NETSNMP_DS_LIB_SNMPVERSION);
521
522
        /*
523
         * compile time default version 
524
         */
525
1.76k
        if (!session->version) {
526
1.76k
            switch (NETSNMP_DEFAULT_SNMP_VERSION) {
527
0
#ifndef NETSNMP_DISABLE_SNMPV1
528
0
            case 1:
529
0
                session->version = SNMP_VERSION_1;
530
0
                break;
531
0
#endif
532
533
0
#ifndef NETSNMP_DISABLE_SNMPV2C
534
1.76k
            case 2:
535
1.76k
                session->version = SNMP_VERSION_2c;
536
1.76k
                break;
537
0
#endif
538
539
0
            case 3:
540
0
                session->version = SNMP_VERSION_3;
541
0
                break;
542
543
0
            default:
544
0
                snmp_log(LOG_ERR, "Can't determine a valid SNMP version for the session\n");
545
0
                return(NETSNMP_PARSE_ARGS_ERROR);
546
1.76k
            }
547
1.76k
        } else {
548
0
#ifndef NETSNMP_DISABLE_SNMPV1
549
0
            if (session->version == NETSNMP_DS_SNMP_VERSION_1)  /* bogus value.  version 1 actually = 0 */
550
0
                session->version = SNMP_VERSION_1;
551
0
#endif
552
0
        }
553
1.76k
    }
554
555
1.76k
#ifdef NETSNMP_SECMOD_USM
556
    /* XXX: this should ideally be moved to snmpusm.c somehow */
557
558
    /*
559
     * make master key from pass phrases 
560
     */
561
1.76k
    if (Apsz) {
562
0
        session->securityAuthKeyLen = USM_AUTH_KU_LEN;
563
0
        if (session->securityAuthProto == NULL) {
564
            /*
565
             * get .conf set default 
566
             */
567
0
            const oid      *def =
568
0
                get_default_authtype(&session->securityAuthProtoLen);
569
0
            session->securityAuthProto =
570
0
                snmp_duplicate_objid(def, session->securityAuthProtoLen);
571
0
        }
572
0
        if (session->securityAuthProto == NULL) {
573
0
            session->securityAuthProto =
574
0
                snmp_duplicate_objid(SNMP_DEFAULT_AUTH_PROTO,
575
0
                                     SNMP_DEFAULT_AUTH_PROTOLEN);
576
0
            session->securityAuthProtoLen = SNMP_DEFAULT_AUTH_PROTOLEN;
577
0
        }
578
0
        if (generate_Ku(session->securityAuthProto,
579
0
                        session->securityAuthProtoLen,
580
0
                        (u_char *) Apsz, strlen(Apsz),
581
0
                        session->securityAuthKey,
582
0
                        &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
583
0
            snmp_perror(argv[0]);
584
0
            fprintf(stderr,
585
0
                    "Error generating a key (Ku) from the supplied authentication pass phrase. \n");
586
0
            ret = NETSNMP_PARSE_ARGS_ERROR;
587
0
            goto out;
588
0
        }
589
0
        free(Apsz);
590
0
        Apsz = NULL;
591
0
    }
592
1.76k
    if (Xpsz) {
593
0
        session->securityPrivKeyLen = USM_PRIV_KU_LEN;
594
0
        if (session->securityPrivProto == NULL) {
595
            /*
596
             * get .conf set default 
597
             */
598
0
            const oid      *def =
599
0
                get_default_privtype(&session->securityPrivProtoLen);
600
0
            session->securityPrivProto =
601
0
                snmp_duplicate_objid(def, session->securityPrivProtoLen);
602
0
        }
603
0
        if (session->securityPrivProto == NULL) {
604
0
            session->securityPrivProto =
605
0
                snmp_duplicate_objid(SNMP_DEFAULT_PRIV_PROTO,
606
0
                                     SNMP_DEFAULT_PRIV_PROTOLEN);
607
0
            session->securityPrivProtoLen = SNMP_DEFAULT_PRIV_PROTOLEN;
608
0
        }
609
0
        if (generate_Ku(session->securityAuthProto,
610
0
                        session->securityAuthProtoLen,
611
0
                        (u_char *) Xpsz, strlen(Xpsz),
612
0
                        session->securityPrivKey,
613
0
                        &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
614
0
            snmp_perror(argv[0]);
615
0
            fprintf(stderr,
616
0
                    "Error generating a key (Ku) from the supplied privacy pass phrase. \n");
617
0
            ret = NETSNMP_PARSE_ARGS_ERROR;
618
0
            goto out;
619
0
        }
620
0
        free(Xpsz);
621
0
        Xpsz = NULL;
622
0
    }
623
1.76k
#endif /* NETSNMP_SECMOD_USM */
624
625
    /*
626
     * get the hostname 
627
     */
628
1.76k
    if (optind == argc) {
629
0
        fprintf(stderr, "No hostname specified.\n");
630
0
        ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
631
0
        goto out;
632
0
    }
633
1.76k
    session->peername = strdup(argv[optind++]); /* hostname */
634
635
1.76k
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
636
    /*
637
     * If v1 or v2c, check community has been set, either by a -c option above,
638
     * or via a default token somewhere.  
639
     * If neither, it will be taken from the incoming request PDU.
640
     */
641
642
#if defined(NETSNMP_DISABLE_SNMPV1)
643
    if (session->version == SNMP_VERSION_2c)
644
#else 
645
#if defined(NETSNMP_DISABLE_SNMPV2C)
646
    if (session->version == SNMP_VERSION_1)
647
#else
648
1.76k
    if (session->version == SNMP_VERSION_1 ||
649
1.76k
  session->version == SNMP_VERSION_2c)
650
1.76k
#endif
651
1.76k
#endif
652
1.76k
    {
653
1.76k
        if (Cpsz == NULL) {
654
1.76k
            Cpsz = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
655
1.76k
           NETSNMP_DS_LIB_COMMUNITY);
656
1.76k
      if (Cpsz == NULL) {
657
1.76k
                if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
658
1.76k
                                           NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY)){
659
0
                    DEBUGMSGTL(("snmp_parse_args",
660
0
                                "ignoring that the community string is not present\n"));
661
0
                    session->community = NULL;
662
0
                    session->community_len = 0;
663
1.76k
                } else {
664
1.76k
                    fprintf(stderr, "No community name specified.\n");
665
1.76k
                    ret = NETSNMP_PARSE_ARGS_ERROR_USAGE;
666
1.76k
                    goto out;
667
1.76k
                }
668
1.76k
      } else {
669
0
                Cpsz = NULL;
670
0
            }
671
1.76k
  } else {
672
0
            session->community = (unsigned char *)Cpsz;
673
0
            session->community_len = strlen(Cpsz);
674
0
            Cpsz = NULL;
675
0
        }
676
1.76k
    }
677
0
#endif /* support for community based SNMP */
678
679
0
    ret = optind;
680
681
1.76k
out:
682
1.76k
    free(Apsz);
683
1.76k
    free(Xpsz);
684
1.76k
    free(Cpsz);
685
1.76k
    return ret;
686
0
}
687
688
int
689
snmp_parse_args(int argc,
690
                char **argv,
691
                netsnmp_session * session, const char *localOpts,
692
                void (*proc) (int, char *const *, int))
693
1.76k
{
694
1.76k
    return netsnmp_parse_args(argc, argv, session, localOpts, proc, 0);
695
1.76k
}