#2552 DateAndTime truncated with Python Bindings

linux
open
nobody
None
5
2014-08-12
2014-06-02
Kurt Frederiksen
No

Operating System: CentOS 6.5 (2.6.32-431.17.1.el6.x86_64)
NetSNMP Version (latest): net-snmp-5.5-49.el6_5.1.x86_64

When I use the python bindings for Net-SNMP to set an DateAndTime object the resultant value is truncated down to 4 octets with the least significant 4 octets truncated (0x07da0101000f0000 gets truncated down to 0x07da0101). I have verified this both by querying the agent after setting the value, and by using wireshark. When I attempt to set the value using the netsnmp command line the value is not truncated, so this leads me to believe that the issue is with the bindings.

I am using the DateAndTime object as defined by SNMPv2-TC, the smi is as follows:
DateAndTime ::= TEXTUAL-CONVENTION
DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
STATUS current
DESCRIPTION
"A date-time specification.

        field  octets  contents                  range
        -----  ------  --------                  -----
          1      1-2   year*                     0..65536
          2       3    month                     1..12
          3       4    day                       1..31
          4       5    hour                      0..23
          5       6    minutes                   0..59
          6       7    seconds                   0..60
                       (use 60 for leap-second)
          7       8    deci-seconds              0..9
          8       9    direction from UTC        '+' / '-'
          9      10    hours from UTC*           0..13
         10      11    minutes from UTC          0..59

        * Notes:
        - the value of year is in network-byte order
        - daylight saving time in New Zealand is +13

        For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
        displayed as:

                         1992-5-26,13:30:15.0,-4:0

        Note that if only local time is known, then timezone
        information (fields 8-10) is not present."
SYNTAX       OCTET STRING (SIZE (8 | 11))

Discussion

  • Spent a bit more time investigating the issue here are the results of what was found:
    1) net-snmp python bindings appear to be truncating values when the octect has a value of 00 and after. I have confirmed that the same set command works correctly when executed from the command line.

    2) The value appears to traverse the python code correctly. I believe the issue is with the c code, specificially in the function netsnmp_set() in the file client_intf.c. Specifically the error appears to be between where the c code gets the varlist_iter and the send_sync_pdu. As far as I can tell the PyObject_GetIter(varlist) calls back to the python code to get the iterator and the send_sync_pdu is where the snmp is put on the wire.

    If anyone could help me trace through what this code is doing or take a look at this issue for me, it would be much appreciated.

     
  • Compiled 5.5-49.el6_5.1 from source and was able to edit the C code to enable better debugging. Here is what was found.

    1) The netsnmp_set() function appears to be the location of the bug. varbind.val which comes from varlist[0] is correct when the value is checked in the client.py. I am not sure how to verify it is getting received by the C code correctly, but I would like to do this verification.

    2) The value is being extracted with the "val = py_netsnmp_attr_string(varbind, "val");" call within netsnmp_set() function appears to be incomplete. A length calculation is being called on the val function which in turn determines the length which is being put on the wire. If the len value is hard coded then the "additional" bits appear to be random garbage when viewed on the wire. Based on this information it appears the len function is correctly doing its job, however, the data is not correctly being parsed down from the python code.

    Any help debugging would be appreciated.

    Thanks.

     
  • After looking through the C Code I determined that the strcpy() and strlen() functions were the source of the truncation problem. This is due to \00 correctly being read as a truncating character. The solution was to alter client.py to send down the length to client_intf.c, which respectfully now uses the length passed down for TYPE_OCTETSTR to iterate over val to copy it to tmp_val_str. During testing a separate bug was found, we are still investigating this issue and will file an additional bug report.

    I am still working on generating a patch for this issue.

     
  • Bill Fenner
    Bill Fenner
    2014-07-13

    Thank you for your persistence, Kurt.

     
  • Enclosed is a patch which resolves the issue in the redhat version of net-snmp found here:
    https://www.redhat.com/archives/rhsa-announce/2014-March/msg00030.html

    Credit for the patch goes to Ross Weisman.

    After examining the netsnmp 5.7 code it appears the issue has been resolved. However, we were not able to test to verify as we were unable to build python bindings correctly on a CENTOS 6 and Windows 7 machine. If anyone has tips on how to build we would be happy to test. It looks like the python net-snmp binding build instructions have not been updated in years so any tips would be helpful. Even a link to something on the wiki on how to build on a modern OS would be appreciated.

     
  • Bill Fenner
    Bill Fenner
    2014-07-17

    I was curious about the need for instructions for building the python bindings on a modern OS, so I downloaded the CentOS 7 livecd and the net-snmp-5.7.3-pre3 sources, and did:

    sudo yum -y install gcc python-devel perl(ExtUtils::Embed)
    ./configure --with-python-modules --prefix=/usr --libdir=/usr/lib64 --with-defaults
    make
    sudo make install
    

    and I had a working python module on what I believe could be considered a modern OS.

     
    • Sweet thank you.

      Has anyone tried to build the python bindings on Windows 7? I tried to build 5.7.2.1. I have had a lot of trouble. They will not build using the VS2008 C++ compilier due to client_intf.c using netdb.h and arpa/inet.h instead of winsock2.h. Even with these items changed the VS2008 C++ compilier does not have strtoull (system.h) and there appears to be no viable replacement so it is impossible to build.

      I did try using the mingw compilier instead and used the win32 build instructions and this https://sourceforge.net/p/net-snmp/mailman/net-snmp-users/thread/20120213201710.GA3220@pom.pom/ . It appears the make file which is generated with the command "./configure --prefix="$BASEDIR" --with-ssl --with-sdk" creates a make file which is unable to be used due to missing separators, and other assorted issues (looks to deal with the echo mainly). This appears to be an issue with all make files generated so perhaps the rules file it is using to generate the files is incorrect. I did try the configure command in the readme file however none of the arguments provided were valid.

      I would really like to test the latest build on a windows machine. Perhaps I should file this as another bug?

      Thanks

       
      Last edit: Kurt Frederiksen 2014-07-17
  • Niels Baggesen
    Niels Baggesen
    2014-07-18

    That is the curse of long-lived releases. CentOS/RedHat 5 ships with 5.1.2 and is supposed to live for three more years. CentOS/RedHat 6 with 5.5 is supposed to live until 2021!