On Tue, Mar 29, 2016 at 09:38:05PM +0100, Steven Chamberlain wrote: > Commit deed97cc in pkg-net-snmp Git, changed debian/snmpd.postinst > SNMP_USER from "snmp" to "Debian-snmp". I think a corresponding change > is missing from debian/snmpd.default as it fails to start snmpd with: > > Starting SNMP services::Bad user id: snmp
Ah. I didn't test snmpd, only the client tools. > Also, `dpkg-buildpackage -S` fails in an already-built tree, because the > files below are generated during the build, and debian/rules clean does > not remove them: Yes, I knew about this one -- however, I wasn't going to try to fix all issues in the existing package at once. :-) > I've attached a diff against your NMU to fix both of these things. > After that, the client and server both work nicely for me, IPv6 too. Thanks! I've squashed your changes into my NMU diff and done a re-upload. New diff attached. /* Steinar */ -- Homepage: https://www.sesse.net/
>From d87d05256001f852dd8f66116b5d11a16b713b45 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" <sgunder...@bigfoot.com> Date: Tue, 29 Mar 2016 02:03:37 +0200 Subject: [PATCH] Diff for 5.7.3+dfsg-1.1 NMU, adding various patches for bugfixes (and one small new feature). --- debian/changelog | 21 +++- debian/patches/callback_print.diff | 13 +++ .../do_not_callback_for_failed_reports.diff | 129 +++++++++++++++++++++ debian/patches/fix_engineid_reprobe.diff | 16 +++ debian/patches/fix_perl_bulk_gets.diff | 88 ++++++++++++++ debian/patches/let_perl_access_engineid.diff | 94 +++++++++++++++ debian/patches/series | 5 + debian/rules | 6 +- debian/snmpd.default | 2 +- 9 files changed, 370 insertions(+), 4 deletions(-) create mode 100644 debian/patches/callback_print.diff create mode 100644 debian/patches/do_not_callback_for_failed_reports.diff create mode 100644 debian/patches/fix_engineid_reprobe.diff create mode 100644 debian/patches/fix_perl_bulk_gets.diff create mode 100644 debian/patches/let_perl_access_engineid.diff diff --git a/debian/changelog b/debian/changelog index 94bf7e1..e4622d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,8 @@ -net-snmp (5.7.3+dfsg-2) UNRELEASED; urgency=medium +net-snmp (5.7.3+dfsg-1.1) unstable; urgency=medium + + * Non-maintainer upload, done on top of the latest version in pkg-net-snmp + git, as well as adding Steven Chamberlain's kFreeBSD patches from + bug #810892. [ Hideki Yamane ] * debian/patches @@ -24,7 +28,20 @@ net-snmp (5.7.3+dfsg-2) UNRELEASED; urgency=medium * Re-enable IPv6 on kfreebsd (Closes: #765846) * Build with the libbsd overlay on kfreebsd, for nlist - -- Hideki Yamane <henr...@debian.org> Thu, 18 Jun 2015 06:43:28 +0900 + [ Steinar H. Gunderson ] + * New patches, mostly for various bug fixes (some of them for crash bugs): + * fix_engineid_reprobe.diff: Do not probe engineID for USM + if it is already given. (Closes: #765873) + * callback_print.diff: Fix enum formatting when doing asynchronous queries + from Perl. (Closes: #765289) + * do_not_callback_for_failed_reports.diff: Fix access of freed data due to + callbacks for reports occasionally coming twice. + * fix_perl_bulk_gets.diff: Fix handling of truncated bulk get responses + in the Perl module. (Patch 1278 in upstream patch tracker.) + * let_perl_access_engineid.diff: Add a new functions to let Perl code + access the security engine ID. + + -- Steinar H. Gunderson <se...@debian.org> Tue, 29 Mar 2016 10:30:24 +0200 net-snmp (5.7.3+dfsg-1) unstable; urgency=medium diff --git a/debian/patches/callback_print.diff b/debian/patches/callback_print.diff new file mode 100644 index 0000000..f4b6df6 --- /dev/null +++ b/debian/patches/callback_print.diff @@ -0,0 +1,13 @@ +--- net-snmp-5.7.2.1~dfsg.orig/perl/SNMP/SNMP.xs ++++ net-snmp-5.7.2.1~dfsg/perl/SNMP/SNMP.xs +@@ -1300,6 +1300,10 @@ void *cb_data; + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_OIDS, 1); + netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, NETSNMP_OID_OUTPUT_NUMERIC); + } ++ if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseEnums", 8, 1))) ++ sprintval_flag = USE_ENUMS; ++ if (SvIV(*hv_fetch((HV*)SvRV(sess_ref),"UseSprintValue", 14, 1))) ++ sprintval_flag = USE_SPRINT_VALUE; + + sv_bless(varlist_ref, gv_stashpv("SNMP::VarList",0)); + for(vars = (pdu?pdu->variables:NULL); vars; vars = vars->next_variable) { diff --git a/debian/patches/do_not_callback_for_failed_reports.diff b/debian/patches/do_not_callback_for_failed_reports.diff new file mode 100644 index 0000000..96db193 --- /dev/null +++ b/debian/patches/do_not_callback_for_failed_reports.diff @@ -0,0 +1,129 @@ +Index: net-snmp-5.7.3/snmplib/snmp_api.c +=================================================================== +--- net-snmp-5.7.3.orig/snmplib/snmp_api.c ++++ net-snmp-5.7.3/snmplib/snmp_api.c +@@ -5346,71 +5346,71 @@ _sess_process_packet(void *sessp, netsnm + * should be per session ! + */ + +- if (callback == NULL +- || callback(NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE, sp, +- pdu->reqid, pdu, magic) == 1) { +- if (pdu->command == SNMP_MSG_REPORT) { +- if (sp->s_snmp_errno == SNMPERR_NOT_IN_TIME_WINDOW || +- snmpv3_get_report_type(pdu) == +- SNMPERR_NOT_IN_TIME_WINDOW) { +- /* +- * trigger immediate retry on recoverable Reports +- * * (notInTimeWindow), incr_retries == TRUE to prevent +- * * inifinite resend +- */ +- if (rp->retries <= sp->retries) { +- snmp_resend_request(slp, rp, TRUE); +- break; +- } else { +- /* We're done with retries, so no longer waiting for a response */ +- if (magic) { +- ((struct synch_state*)magic)->waiting = 0; +- } +- } ++ if (pdu->command == SNMP_MSG_REPORT) { ++ if (sp->s_snmp_errno == SNMPERR_NOT_IN_TIME_WINDOW || ++ snmpv3_get_report_type(pdu) == ++ SNMPERR_NOT_IN_TIME_WINDOW) { ++ /* ++ * trigger immediate retry on recoverable Reports ++ * * (notInTimeWindow), incr_retries == TRUE to prevent ++ * * inifinite resend ++ */ ++ if (rp->retries <= sp->retries) { ++ snmp_resend_request(slp, rp, TRUE); ++ break; + } else { +- if (SNMPV3_IGNORE_UNAUTH_REPORTS) { +- break; +- } else { /* Set the state to no longer be waiting, since we're done with retries */ +- if (magic) { +- ((struct synch_state*)magic)->waiting = 0; +- } ++ /* We're done with retries, so no longer waiting for a response */ ++ if (magic) { ++ ((struct synch_state*)magic)->waiting = 0; ++ } ++ } ++ } else { ++ if (SNMPV3_IGNORE_UNAUTH_REPORTS) { ++ break; ++ } else { /* Set the state to no longer be waiting, since we're done with retries */ ++ if (magic) { ++ ((struct synch_state*)magic)->waiting = 0; + } + } ++ } + +- /* +- * Handle engineID discovery. +- */ +- if (!sp->securityEngineIDLen && pdu->securityEngineIDLen) { +- sp->securityEngineID = +- (u_char *) malloc(pdu->securityEngineIDLen); +- if (sp->securityEngineID == NULL) { ++ /* ++ * Handle engineID discovery. ++ */ ++ if (!sp->securityEngineIDLen && pdu->securityEngineIDLen) { ++ sp->securityEngineID = ++ (u_char *) malloc(pdu->securityEngineIDLen); ++ if (sp->securityEngineID == NULL) { ++ /* ++ * TODO FIX: recover after message callback *? ++ */ ++ return -1; ++ } ++ memcpy(sp->securityEngineID, pdu->securityEngineID, ++ pdu->securityEngineIDLen); ++ sp->securityEngineIDLen = pdu->securityEngineIDLen; ++ if (!sp->contextEngineIDLen) { ++ sp->contextEngineID = ++ (u_char *) malloc(pdu-> ++ securityEngineIDLen); ++ if (sp->contextEngineID == NULL) { + /* + * TODO FIX: recover after message callback *? +- */ ++ */ + return -1; + } +- memcpy(sp->securityEngineID, pdu->securityEngineID, ++ memcpy(sp->contextEngineID, ++ pdu->securityEngineID, + pdu->securityEngineIDLen); +- sp->securityEngineIDLen = pdu->securityEngineIDLen; +- if (!sp->contextEngineIDLen) { +- sp->contextEngineID = +- (u_char *) malloc(pdu-> +- securityEngineIDLen); +- if (sp->contextEngineID == NULL) { +- /* +- * TODO FIX: recover after message callback *? +- */ +- return -1; +- } +- memcpy(sp->contextEngineID, +- pdu->securityEngineID, +- pdu->securityEngineIDLen); +- sp->contextEngineIDLen = +- pdu->securityEngineIDLen; +- } ++ sp->contextEngineIDLen = ++ pdu->securityEngineIDLen; + } + } ++ } + ++ if (callback == NULL || ++ callback(NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE, sp, ++ pdu->reqid, pdu, magic) == 1) { + /* + * Successful, so delete request. + */ diff --git a/debian/patches/fix_engineid_reprobe.diff b/debian/patches/fix_engineid_reprobe.diff new file mode 100644 index 0000000..c9d4778 --- /dev/null +++ b/debian/patches/fix_engineid_reprobe.diff @@ -0,0 +1,16 @@ +Index: net-snmp-5.7.3/snmplib/snmpusm.c +=================================================================== +--- net-snmp-5.7.3.orig/snmplib/snmpusm.c ++++ net-snmp-5.7.3/snmplib/snmpusm.c +@@ -3129,6 +3129,11 @@ int usm_discover_engineid(void *slpv, ne + int status, i; + struct session_list *slp = (struct session_list *) slpv; + ++ if (slp->session->securityEngineIDLen != 0) { ++ DEBUGMSGTL(("snmp_api", "engineID already known, skipping probe\n")); ++ return SNMPERR_SUCCESS; ++ } ++ + if (usm_build_probe_pdu(&pdu) != 0) { + DEBUGMSGTL(("snmp_api", "unable to create probe PDU\n")); + return SNMP_ERR_GENERR; diff --git a/debian/patches/fix_perl_bulk_gets.diff b/debian/patches/fix_perl_bulk_gets.diff new file mode 100644 index 0000000..88d1fe4 --- /dev/null +++ b/debian/patches/fix_perl_bulk_gets.diff @@ -0,0 +1,88 @@ +Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm +=================================================================== +--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.pm ++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm +@@ -866,22 +866,11 @@ sub _gettable_do_it() { + + $vbl = $_[$#_] if ($state->{'options'}{'callback'}); + +- while ($#$vbl > -1 && !$this->{ErrorNum}) { +- if (($#$vbl + 1) % ($#{$state->{'stopconds'}} + 1) != 0) { +- if ($vbl->[$#$vbl][2] ne 'ENDOFMIBVIEW') { +- # unless it's an end of mib view we didn't get the +- # proper number of results back. +- print STDERR "ack: gettable results not appropriate\n"; +- } +- my @k = keys(%{$state->{'result_hash'}}); +- last if ($#k > -1); # bail with what we have +- return; +- } +- +- $state->{'varbinds'} = []; +- my $newstopconds; ++ my $num_vbls = defined($vbl) ? scalar @$vbl : 0; ++ my $num_stopconds = scalar @{$state->{'stopconds'}}; + +- my $lastsetstart = ($state->{'repeatcount'}-1) * ($#{$state->{'stopconds'}}+1); ++ while ($num_vbls > 0 && !$this->{ErrorNum}) { ++ my @found_eof = (0) x $num_stopconds; + + for (my $i = 0; $i <= $#$vbl; $i++) { + my $row_oid = SNMP::translateObj($vbl->[$i][0]); +@@ -890,9 +879,11 @@ sub _gettable_do_it() { + my $row_value = $vbl->[$i][2]; + my $row_type = $vbl->[$i][3]; + +- if ($row_oid =~ +- /^$state->{'stopconds'}[$i % ($#{$state->{'stopconds'}}+1)]/ && +- $row_value ne 'ENDOFMIBVIEW' ){ ++ my $stopcond_num = $i % $num_stopconds; ++ my $stopcond = $state->{'stopconds'}[$stopcond_num]; ++ if ($row_oid !~ /^\Q$stopcond\E/ || $row_value eq 'ENDOFMIBVIEW') { ++ $found_eof[$stopcond_num] = 1; ++ } else { + + if ($row_type eq "OBJECTID") { + +@@ -903,26 +894,30 @@ sub _gettable_do_it() { + + } + ++ # continue past this next time ++ ++ $state->{'varbinds'}[$stopcond_num] = [ $row_text, $row_index ]; ++ + # Place the results in a hash + + $state->{'result_hash'}{$row_index}{$row_text} = $row_value; ++ } ++ } + +- # continue past this next time +- if ($i >= $lastsetstart) { +- push @$newstopconds, +- $state->{'stopconds'}->[$i%($#{$state->{'stopconds'}}+1)]; +- push @{$state->{'varbinds'}},[$vbl->[$i][0],$vbl->[$i][1]]; +- } ++ my @newstopconds = (); ++ my @newvarbinds = (); ++ for (my $i = 0; $i < $num_stopconds; ++$i) { ++ unless ($found_eof[$i]) { ++ push @newstopconds, $state->{'stopconds'}[$i]; ++ push @newvarbinds, $state->{'varbinds'}[$i]; + } + } +- if ($#$newstopconds == -1) { ++ if ($#newstopconds == -1) { + last; + } +- if ($#{$state->{'varbinds'}} == -1) { +- print "gettable ack. shouldn't get here\n"; +- } ++ $state->{'varbinds'} = \@newvarbinds; ++ $state->{'stopconds'} = \@newstopconds; + $vbl = $state->{'varbinds'}; +- $state->{'stopconds'} = $newstopconds; + + # + # if we've been configured with a callback, then call the diff --git a/debian/patches/let_perl_access_engineid.diff b/debian/patches/let_perl_access_engineid.diff new file mode 100644 index 0000000..b65135f --- /dev/null +++ b/debian/patches/let_perl_access_engineid.diff @@ -0,0 +1,94 @@ +Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm +=================================================================== +--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.pm ++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.pm +@@ -1238,6 +1238,16 @@ sub inform { + return(wantarray() ? @res : $res[0]); + } + ++sub get_sec_engine_id { ++ my $this = shift; ++ return SNMP::_get_sec_engine_id($this); ++} ++ ++sub get_context_engine_id { ++ my $this = shift; ++ return SNMP::_get_context_engine_id($this); ++} ++ + package SNMP::TrapSession; + @SNMP::TrapSession::ISA = ('SNMP::Session'); + +@@ -2034,6 +2044,17 @@ as well. + + =back + ++=item $sess->get_sec_engine_id ++ ++Returns the security engine ID for the current session, whether probed ++or provided by the client, in hex format suitable for the SecEngineId ++parameter when creating a session in the future. Returns undef if we have not ++had not had any contact with the remote agent yet. ++ ++=item $sess->get_context_engine_id ++ ++Like get_sec_engine_id, but for the context engine ID (ContextEngineId). ++ + =back + + =head1 SNMP::TrapSession +Index: net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.xs +=================================================================== +--- net-snmp-5.7.2.1+dfsg.orig/perl/SNMP/SNMP.xs ++++ net-snmp-5.7.2.1+dfsg/perl/SNMP/SNMP.xs +@@ -4741,6 +4741,50 @@ done: + + + char * ++snmp_get_sec_engine_id(sess_ref) ++ SV * sess_ref ++ CODE: ++ { ++ RETVAL = NULL; ++ if (SvROK(sess_ref)) { ++ SV **sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1); ++ SnmpSession *ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv)); ++ if (ss->securityEngineIDLen > 0) { ++ binary_to_hex(ss->securityEngineID, ++ ss->securityEngineIDLen, ++ &RETVAL); ++ } ++ } ++ } ++ OUTPUT: ++ RETVAL ++ CLEANUP: ++ netsnmp_free(RETVAL); ++ ++ ++char * ++snmp_get_context_engine_id(sess_ref) ++ SV * sess_ref ++ CODE: ++ { ++ RETVAL = NULL; ++ if (SvROK(sess_ref)) { ++ SV **sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1); ++ SnmpSession *ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv)); ++ if (ss->contextEngineIDLen > 0) { ++ binary_to_hex(ss->contextEngineID, ++ ss->contextEngineIDLen, ++ &RETVAL); ++ } ++ } ++ } ++ OUTPUT: ++ RETVAL ++ CLEANUP: ++ netsnmp_free(RETVAL); ++ ++ ++char * + snmp_get_type(tag, best_guess) + char * tag + int best_guess diff --git a/debian/patches/series b/debian/patches/series index 5ad0dc2..a93def2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -25,3 +25,8 @@ fix-request-id-0.patch 0025-Bug-788964-net-snmp-snmp_pdu_parse-DoS.patch 0026-fix-Bug-785380-incorrect-date-format.patch 0027-fix-455707-traptoemail-use-FQDN.patch +let_perl_access_engineid.diff +fix_perl_bulk_gets.diff +do_not_callback_for_failed_reports.diff +callback_print.diff +fix_engineid_reprobe.diff diff --git a/debian/rules b/debian/rules index ed866a9..d2e7ece 100755 --- a/debian/rules +++ b/debian/rules @@ -64,7 +64,11 @@ override_dh_clean: dh_clean rm -rf `find . -name .libs` \ python/build \ - python/netsnmp_python.egg-info + python/netsnmp_python.egg-info \ + dist/generation-scripts/gen-variables \ + perl/SNMP/t/snmptest.cmd \ + perl/TrapReceiver/const-c.inc \ + perl/TrapReceiver/const-xs.inc override_dh_strip: dh_strip -plibsnmp$(LIB_VERSION) --dbg-package=libsnmp$(LIB_VERSION)-dbg diff --git a/debian/snmpd.default b/debian/snmpd.default index e47dec8..f4ee7a7 100644 --- a/debian/snmpd.default +++ b/debian/snmpd.default @@ -8,4 +8,4 @@ export MIBS= SNMPDRUN=yes # snmpd options (use syslog, close stdin/out/err). -SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux,mteTrigger,mteTriggerConf -p /run/snmpd.pid' +SNMPDOPTS='-Lsd -Lf /dev/null -u Debian-snmp -g Debian-snmp -I -smux,mteTrigger,mteTriggerConf -p /run/snmpd.pid' -- 2.7.0