Hello,
I would like to propose the attached patch to the Python bindings.  This is a 
patch to version 5.4.2.1.  Currently, including null-bytes in octet strings 
doesn't work because it's just treating the strings from Python as 
null-terminated strings instead of getting their actual length.  I discovered 
this while attempting to set CISCO-VTP-MIB::vlanTrunkPortVlansEnabled*, which 
is basically a bit-string and will often contain null-bytes.

As I'm new to contributing code to Net-SNMP, please let me know if I need to do 
anything different to get this included in the codebase.

Thanks.

-- 
Regards,
Tommy Beadle ([email protected])
QA Engineer
Arbor Networks -- How Networks Grow
www.arbornetworks.com
--- python/netsnmp/client_intf.c.old    2008-09-04 18:52:42.000000000 -0400
+++ python/netsnmp/client_intf.c        2010-02-05 21:52:49.000000000 -0500
@@ -1081,20 +1081,22 @@ py_netsnmp_construct_varbind(void)
   return PyObject_CallFunction(callable, "");
 }
 
-static char *
-py_netsnmp_attr_string(PyObject *obj, char * attr_name)
+static int
+py_netsnmp_attr_string(PyObject *obj, char * attr_name, char **val,
+    Py_ssize_t *len)
 {
-  char *val = NULL;
-
+  *val = NULL;
   if (obj && attr_name && PyObject_HasAttrString(obj, attr_name)) {
     PyObject *attr = PyObject_GetAttrString(obj, attr_name);
     if (attr) {
-      val = PyString_AsString(attr);
+      int retval;
+      retval = PyString_AsStringAndSize(attr, val, len);
       Py_DECREF(attr);
+      return retval;
     }
   }
 
-  return val;
+  return -1;
 }
 
 static long
@@ -1395,6 +1397,8 @@ netsnmp_get(PyObject *self, PyObject *ar
   int err_ind;
   int err_num;
   char err_str[STR_BUF_SIZE];
+  char *tmpstr;
+  Py_ssize_t tmplen;
           
   oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
 
@@ -1406,7 +1410,10 @@ netsnmp_get(PyObject *self, PyObject *ar
 
     ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
 
-    strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+    if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+      goto done;
+    }
+    memcpy(&err_str, tmpstr, tmplen);
     err_num = py_netsnmp_attr_long(session, "ErrorNum");
     err_ind = py_netsnmp_attr_long(session, "ErrorInd");
 
@@ -1427,12 +1434,13 @@ netsnmp_get(PyObject *self, PyObject *ar
       PyObject *varlist_iter = PyObject_GetIter(varlist);
 
       while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
-       tag = py_netsnmp_attr_string(varbind, "tag");
-       iid = py_netsnmp_attr_string(varbind, "iid");
-
-
-       tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, 
-                      NULL, best_guess);
+       if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+           py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+       {
+         oid_arr_len = 0;
+       } else {
+         tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+       }
 
        if (oid_arr_len) {
          snmp_add_null_var(pdu, oid_arr, oid_arr_len);
@@ -1600,6 +1608,8 @@ netsnmp_getnext(PyObject *self, PyObject
   int err_ind;
   int err_num;
   char err_str[STR_BUF_SIZE];
+  char *tmpstr;
+  Py_ssize_t tmplen;
           
   oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
 
@@ -1611,7 +1621,10 @@ netsnmp_getnext(PyObject *self, PyObject
 
     ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
 
-    strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+    if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+      goto done;
+    }
+    memcpy(&err_str, tmpstr, tmplen);
     err_num = py_netsnmp_attr_long(session, "ErrorNum");
     err_ind = py_netsnmp_attr_long(session, "ErrorInd");
 
@@ -1632,11 +1645,13 @@ netsnmp_getnext(PyObject *self, PyObject
       PyObject *varlist_iter = PyObject_GetIter(varlist);
 
       while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
-       tag = py_netsnmp_attr_string(varbind, "tag");
-       iid = py_netsnmp_attr_string(varbind, "iid");
-
-       tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, 
-                      NULL, best_guess);
+       if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+           py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+       {
+         oid_arr_len = 0;
+       } else {
+         tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+       }
 
        if (_debug_level) 
          printf("netsnmp_getnext: filling request: %s:%s:%d:%d\n", 
@@ -1809,6 +1824,8 @@ netsnmp_walk(PyObject *self, PyObject *a
   char err_str[STR_BUF_SIZE];
   int notdone = 1;
   int result_count = 0;
+  char *tmpstr;
+  Py_ssize_t tmplen;
           
   oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
 
@@ -1827,7 +1844,10 @@ netsnmp_walk(PyObject *self, PyObject *a
     }
     ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
 
-    strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+    if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+      goto done;
+    }
+    memcpy(&err_str, tmpstr, tmplen);
     err_num = py_netsnmp_attr_long(session, "ErrorNum");
     err_ind = py_netsnmp_attr_long(session, "ErrorInd");
 
@@ -1848,11 +1868,13 @@ netsnmp_walk(PyObject *self, PyObject *a
     
     /* get the initial starting oids*/
     while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
-      tag = py_netsnmp_attr_string(varbind, "tag");
-      iid = py_netsnmp_attr_string(varbind, "iid");
-
-      tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, 
-              NULL, best_guess);
+      if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+         py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+      {
+        oid_arr_len = 0;
+      } else {
+        tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+      }
 
       if (_debug_level) 
        printf("netsnmp_walk: filling request: %s:%s:%d:%d\n", 
@@ -2079,6 +2101,8 @@ netsnmp_getbulk(PyObject *self, PyObject
   int err_ind;
   int err_num;
   char err_str[STR_BUF_SIZE];
+  char *tmpstr;
+  Py_ssize_t tmplen;
           
   oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
 
@@ -2093,7 +2117,10 @@ netsnmp_getbulk(PyObject *self, PyObject
       
       ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
 
-      strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+      if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+        goto done;
+      }
+      memcpy(&err_str, tmpstr, tmplen);
       err_num = py_netsnmp_attr_long(session, "ErrorNum");
       err_ind = py_netsnmp_attr_long(session, "ErrorInd");
 
@@ -2116,11 +2143,13 @@ netsnmp_getbulk(PyObject *self, PyObject
       varbinds_iter = PyObject_GetIter(varbinds);
 
       while (varbinds_iter && (varbind = PyIter_Next(varbinds_iter))) {
-       tag = py_netsnmp_attr_string(varbind, "tag");
-       iid = py_netsnmp_attr_string(varbind, "iid");
-
-       tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, 
-                      NULL, best_guess);
+        if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+          py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+        {
+          oid_arr_len = 0;
+        } else {
+          tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+        }
 
        if (oid_arr_len) {
          snmp_add_null_var(pdu, oid_arr, oid_arr_len);
@@ -2303,6 +2332,8 @@ netsnmp_set(PyObject *self, PyObject *ar
   int err_ind;
   int err_num;
   char err_str[STR_BUF_SIZE];
+  char *tmpstr;
+  Py_ssize_t tmplen;
           
   oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
 
@@ -2315,7 +2346,10 @@ netsnmp_set(PyObject *self, PyObject *ar
     ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
 
     /* PyObject_SetAttrString(); */
-    strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+    if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+      goto done;
+    }
+    memcpy(&err_str, tmpstr, tmplen);
     err_num = py_netsnmp_attr_long(session, "ErrorNum");
     err_ind = py_netsnmp_attr_long(session, "ErrorInd");
 
@@ -2329,11 +2363,13 @@ netsnmp_set(PyObject *self, PyObject *ar
       PyObject *varlist_iter = PyObject_GetIter(varlist);
 
       while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
-       tag = py_netsnmp_attr_string(varbind, "tag");
-       iid = py_netsnmp_attr_string(varbind, "iid");
-
-       tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, 
-                      &type, best_guess);
+        if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+          py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+        {
+          oid_arr_len = 0;
+        } else {
+          tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, &type, best_guess);
+        }
 
        if (oid_arr_len==0) {
          if (verbose)
@@ -2344,7 +2380,10 @@ netsnmp_set(PyObject *self, PyObject *ar
        }
 
        if (type == TYPE_UNKNOWN) {
-         type_str = py_netsnmp_attr_string(varbind, "type");
+         if (py_netsnmp_attr_string(varbind, "type", &type_str, NULL) < 0) {
+           snmp_free_pdu(pdu);
+           goto done;
+         }
          type = __translate_appl_type(type_str);
          if (type == TYPE_UNKNOWN) {
            if (verbose)
@@ -2354,8 +2393,11 @@ netsnmp_set(PyObject *self, PyObject *ar
          }
        }
 
-       val = py_netsnmp_attr_string(varbind, "val");
-       strcpy(tmp_val_str, val);
+       if (py_netsnmp_attr_string(varbind, "val", &val, &tmplen) < 0) {
+         snmp_free_pdu(pdu);
+         goto done;
+       }
+       memcpy(tmp_val_str, val, tmplen);
        if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
          for(ep = tp->enums; ep; ep = ep->next) {
            if (val && !strcmp(ep->label, val)) {
@@ -2364,7 +2406,7 @@ netsnmp_set(PyObject *self, PyObject *ar
            }
          }
        }
-       len = STRLEN(tmp_val_str);
+       len = (int)tmplen;
        status = __add_var_val_str(pdu, oid_arr, oid_arr_len,
                                tmp_val_str, len, type);
 
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to