Nmap Development mailing list archives

Re: [RFC][PATCH] NSE version numbering


From: Djalal Harouni <tixxdz () opendz org>
Date: Mon, 11 Apr 2011 16:43:33 +0100

On 2011-04-03 15:34:12 -0500, Ron wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hey Djalal,
Thx for the comment, and sorry for the delay.

I think this idea sounds promising! Using the svn revision number is a good way of doing it. 

I think the key will be mapping different functions/libraries to the svn revision when they were introduced. I can 
see that getting out of hand or confusing very quickly. Do you have any ideas of how we can manage that in, perhaps, 
an automated way?
Right this is the key, but we may track only Nmap/NSE core changes that
are exposed to NSE scripts/libraries, only compiled code which includes:
*.cc files and of course nse_*.lua, more precisely only the code
exported to the scripts, e.g: NSE API.
Some changes to the nse_main.lua file, like the new rules must be
tracked, but a lot of other changes do not concern scripts, they do not
need to know about them.

NSE libraries (*.lua) are parts of scripts, and they should be handled
like scripts (do not track or manage them), only the NSE API exported by
the compiled code should be tracked.

Now if we think about this, there are not a lot of changes of this
nature, perhaps we can have a better idea about this with some statistics.
e.g: last year how many commits to the NSE core (compiled code) affected
directly scripts and libraries ?

Nessus tends to just die if the version isn't high enough. 
Well, for Nmap the current proposed design will be:
* If we are in the scrict mode (load only supported scripts), Nmap
  should just ignore unsupported scripts. However if it happens that a
  new updated script (with its libraries) is trying to call an
  unsupported/new NSE API (probably a new function), then run it and let
  it fail, this means that there is a bug in the script, more precisely
  in the version field (nse=$required_nse_version) or the script writer
  didn't test the stdnse.VERSION (current NSE core version) before
  calling this new function. These are bugs and we should not hide them.

  Of course we can also add hooks to catch any call to unsupported
  functions, print a message to the user that he should report this to
  nmap-dev or update his Nmap/NSE core ..., and then clean and terminate
  the script/thread, this way other scripts can continue running.

* No strict mode (load all the scripts): some new updated scripts will
  fail.


I was thinking that we should make the 'load all the scripts' the default
and introduce this compatibility system to Nmap, before the update
system. This way we'll have enough time to make tests and when the 
update feed system is merged then the default behaviour could change to
'load only supported scripts'.

We must go slowly and make sure that things have been thought out
well, otherwise it will be a big mess :)

A lot of C programs will reduce their own functionality or implement things inline using pre-compiler defines 
(sometimes in an automated way). 

Do you see a way to automate it? That is, a script that'll look through a .nse, match up a list of functions that are 
used against a list of when each one was introduced, then tell you what the minimum svn version is?
I don't know if this will be practical or can be automated, since we
can't modify the script's code, but if we are interested in the svn
revision of the current NSE we can just grab it and adapt the script.

Here is a real example:
David has committed my get_interface patch as r22853, this patch
introduces two new NSE core functions:
* get_interface()
* get_interface_info()

Any new script that calls these functions must be written like this:
<code>
...
author = "..."
categories = {...}
nse = 22853
...
</code>


Now if we consider an old script like: sniffer-detect, this script calls
the 'nmap.get_interface_link()' function which will be deprecated by the
new 'nmap.get_interface_info()' function (BTW I have not made this change
yet, I'll do it).
In this case we have two options:

1) use the new svn revision number as the required NSE version:
<code>
author = "..."
nse = 22853
categories = {...}
</code>

In this case the script will be ignored if the current NSE core revision
number is lower than 22853.


2) be cool, think about the users and the tool, and use stdnse.VERSION:
<code>
...
author = "..."
nse = 10000 -- this is just an example of an old svn revision number
categories = {...}
...
...
-- test if we have a new NSE version
if stdnse.VERSION >= 22853 then
  -- use the new committed nmap.get_interface_info()
  ...
else
  -- use the old nmap_get_interface_link()
  ...
end

...
</code>

In this case the script will run correctly and it will try to guess
which function to call 'nmap.get_interface_link() or
'nmap.get_interface_info()' based on the current NSE core revision
number. This will be very useful when some NSE exposed functions are
deprecated.

-- 
tixxdz
http://opendz.org
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: