diff --git a/CHANGELOG b/CHANGELOG
index 15361412a..e4599759c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,9 @@
o [NSE][GH#2136][GH#2137] Rectify error "time result cannot be represented..."
in the AFP library. [Clément Notin]
+o [NSE][GH#1473] It is now possible to control whether the SNMP library uses
+ v1 (default) or v2c by setting script argument snmp.version. [nnposter]
+
o [NSE][GH#2128] MySQL library was not properly parsing server responses,
resulting in script crashes. [nnposter]
diff --git a/nselib/snmp.lua b/nselib/snmp.lua
index a73a1e1f7..e7802a174 100644
--- a/nselib/snmp.lua
+++ b/nselib/snmp.lua
@@ -1,6 +1,8 @@
---
-- SNMP library.
--
+-- @args snmp.version The SNMP protocol version. Use "v1" or 0 for SNMPv1 (default) and "v2c" or 1 for SNMPv2c.
+--
-- @author Patrik Karlsson
-- @author Gioacchino Mazzurco
-- @copyright Same as Nmap--See https://nmap.org/book/man-legal.html
@@ -137,15 +139,38 @@ function decode(encStr, pos)
return decoder:decode( encStr, pos )
end
+local version_to_num = {v1=0, v2c=1}
+local num_to_version = {[0]="v1", [1]="v2c"}
+
+--- Returns the numerical value of a given SNMP protocol version
+--
+-- Numerical input is simply passed through, assuming it is valid.
+-- String input is translated to its corresponding numerical value.
+-- @param version of the SNMP protocol. See script argument snmp.version for valid codes
+-- @param default numerical version of the SNMP protocol if the version parameter is nil or its value is invalid.
+-- @return 0 or 1, depending on which protocol version was specified.
+local function getVersion (version, default)
+ if version then
+ version = version_to_num[version] or tonumber(version)
+ if num_to_version[version] then
+ return version
+ end
+ stdnse.debug1("Unrecognized SNMP version; proceeding with SNMP" .. num_to_version[default])
+ end
+ return default
+end
+
+-- the library functions will use this version of SNMP by default
+local default_version = getVersion(stdnse.get_script_args("snmp.version"), 0)
+
---
-- Create an SNMP packet.
-- @param PDU SNMP Protocol Data Unit to be encapsulated in the packet.
--- @param version SNMP version, default 0 (SNMP V1).
+-- @param version SNMP version; defaults to script argument snmp.version
-- @param commStr community string.
function buildPacket(PDU, version, commStr)
- if (not version) then version = 0 end
local packet = {}
- packet[1] = version
+ packet[1] = getVersion(version, default_version)
packet[2] = commStr
packet[3] = PDU
return packet
@@ -433,7 +458,7 @@ Helper = {
-- @param community string containing SNMP community
-- @param options A table with appropriate options:
-- * timeout - the timeout in milliseconds (Default: 5000)
- -- * version - the SNMP version code (Default: 0 (SNMP V1))
+ -- * version - the SNMP version; defaults to script argument snmp.version.
-- @return o a new instance of Helper
new = function( self, host, port, community, options )
local o = {}
@@ -461,7 +486,7 @@ Helper = {
o.options = options or {
timeout = 5000,
- version = 0
+ version = default_version
}
return o
diff --git a/scripts/snmp-brute.nse b/scripts/snmp-brute.nse
index c64a594c1..a284dbc96 100644
--- a/scripts/snmp-brute.nse
+++ b/scripts/snmp-brute.nse
@@ -151,7 +151,7 @@ local send_snmp_queries = function(socket, result, nextcommunity)
condvar("signal")
return
end
- payload = snmp.encode(snmp.buildPacket(request, 0, community))
+ payload = snmp.encode(snmp.buildPacket(request, nil, community))
status, err = socket:send(payload)
if not status then
result.status = false
diff --git a/scripts/snmp-sysdescr.nse b/scripts/snmp-sysdescr.nse
index 24f3d00e2..128c8e7eb 100644
--- a/scripts/snmp-sysdescr.nse
+++ b/scripts/snmp-sysdescr.nse
@@ -5,7 +5,7 @@ local snmp = require "snmp"
local string = require "string"
description = [[
-Attempts to extract system information from an SNMP version 1 service.
+Attempts to extract system information from an SNMP service.
]]
---