Package: snmp
Version: 5.2.2-3ted1
Severity: normal
Tags: patch

This is really a bug that should be forwarded to upstream; I choose to
send it via Debian in the hope that I will not have to maintain my own
version for a very long time.

The option for setting engineBoot and engineTime does not accept the
perfectly valid value 0 (zero).  OK, I admit that the values are
somewhat unusual, but according to RFC 3414 they are legal.  And I
needed them to test a border condition in an SNMP agent.

The reason for the values not being accepted seems to simply be unprecise
testing of the return value for "strtoul".  I include a patch that does a 
somewhat
better job.

best regard

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.5-7.97-smp
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages snmp depends on:
ii  libc6                        2.3.6-7     GNU C Library: Shared libraries
ii  libsnmp9                     5.2.2-3ted1 NET SNMP (Simple Network Managemen

Versions of packages snmp recommends:
ii  perl-modules                  5.8.8-4    Core Perl modules

-- no debconf information
--- net-snmp-5.2.2.orig/snmplib/snmp_parse_args.c
+++ net-snmp-5.2.2/snmplib/snmp_parse_args.c
@@ -13,6 +13,7 @@
  */
 
 #include <net-snmp/net-snmp-config.h>
+#include <errno.h>
 
 #if HAVE_STDLIB_H
 #include <stdlib.h>
@@ -401,21 +402,33 @@
 #define SNMPV3_CMD_OPTIONS
 #ifdef  SNMPV3_CMD_OPTIONS
         case 'Z':
-            session->engineBoots = strtoul(optarg, NULL, 10);
-            if (session->engineBoots == 0 || !isdigit(optarg[0])) {
+            errno = 0;
+            session->engineBoots = strtoul(optarg, &cp, 10);
+            if (errno || cp == optarg) {
                 fprintf(stderr, "Need engine boots value after -Z flag.\n");
                 return (-1);
             }
-            cp = strchr(optarg, ',');
-            if (cp && *(++cp) && isdigit(*cp))
-                session->engineTime = strtoul(cp, NULL, 10);
+            if (*cp == ',') {
+              char *endptr;
+              cp ++;
+              session->engineTime = strtoul(cp, &endptr, 10);
+              if (errno || cp == endptr) {
+                fprintf(stderr, "Need engine time after \"-Z engineBoot,\".\n");
+                return (-1);
+              }
+            }
             /*
              * Handle previous '-Z boot time' syntax 
              */
-            else if ((optind < argc) && isdigit(argv[optind][0]))
-                session->engineTime = strtoul(argv[optind], NULL, 10);
+            else if (optind < argc) {
+              session->engineTime = strtoul(argv[optind], &cp, 10);
+              if (errno || cp == argv[optind]) {
+                fprintf(stderr, "Need engine boots value after -Z flag.\n");
+                return (-1);
+              }
+            }
             else {
-                fprintf(stderr, "Need engine time value after -Z flag.\n");
+                fprintf(stderr, "Need engine time value after \"-Z engineBoot\".\n");
                 return (-1);
             }
             break;
--- net-snmp-5.2.2.orig/snmplib/snmpv3.c
+++ net-snmp-5.2.2/snmplib/snmpv3.c
@@ -3,6 +3,7 @@
  */
 
 #include <net-snmp/net-snmp-config.h>
+#include <errno.h>
 #ifdef HAVE_LIMITS_H
 #include <limits.h>
 #endif
@@ -262,17 +263,24 @@
     switch (*cp) {
 
     case 'Z':
-        session->engineBoots = strtoul(optarg, NULL, 10);
-        if (session->engineBoots == 0 || !isdigit(optarg[0])) {
+        errno = 0;
+        session->engineBoots = strtoul(optarg, &cp, 10);
+        if (errno || cp == optarg) {
             fprintf(stderr, "Need engine boots value after -3Z flag.\n");
             return (-1);
         }
-        cp = strchr(optarg, ',');
-        if (cp && *(++cp) && isdigit(*cp))
-            session->engineTime = strtoul(cp, NULL, 10);
-        else {
-            fprintf(stderr, "Need engine time value after -3Z flag.\n");
+        if (*cp == ',') {
+          char *endptr;
+          cp ++;
+          session->engineTime = strtoul(cp, &endptr, 10);
+          if (errno || cp == endptr) {
+            fprintf(stderr, "Need engine time after \"-3Z engineBoot,\".\n");
             return (-1);
+          }
+        }
+        else {
+          fprintf(stderr, "Need engine time after \"-3Z engineBoot\".\n");
+          return (-1);
         }
         break;
 

Reply via email to