mirror of
https://github.com/nmap/nmap.git
synced 2026-01-07 06:59:03 +00:00
o Expanded and tweaked the product/version/info of service scans in an
attempt to reduce the number of warnings like "Warning: Servicescan
failed to fill info_template...". Parts of this change include:
o Improved the text of the warning to be less confusing
o Increased the internal version info buffer to 256 chars from 128
o Increased the final version string length to 160 from 128 chars
o Changed the behavior when constructing the final version string so
that if it runs out of space, rather than dropping the output of that
template it truncates the template with ...
o Fixed the printing of unneeded spaces between templates when one of the
templates isn't going to be printed at all.
This commit is contained in:
13
CHANGELOG
13
CHANGELOG
@@ -1,5 +1,18 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o Expanded and tweaked the product/version/info of service scans in an
|
||||
attempt to reduce the number of warnings like "Warning: Servicescan
|
||||
failed to fill info_template...". Parts of this change include:
|
||||
o Improved the text of the warning to be less confusing
|
||||
o Increased the internal version info buffer to 256 chars from 128
|
||||
o Increased the final version string length to 160 from 128 chars
|
||||
o Changed the behavior when constructing the final version string so
|
||||
that if it runs out of space, rather than dropping the output of that
|
||||
template it truncates the template with ...
|
||||
o Fixed the printing of unneeded spaces between templates when one of the
|
||||
templates isn't going to be printed at all.
|
||||
[Brandon]
|
||||
|
||||
o [Zenmap] Worked around a GTK+ bug on Windows reported by Henry Nymann.
|
||||
It caused a crash when opening the Hosts Viewer on a host that had OS
|
||||
information. A window appeared saying simply "Runtime Error!". [David]
|
||||
|
||||
32
docs/TODO
32
docs/TODO
@@ -24,22 +24,6 @@ o [Zenmap] Should probably give some sort of widget indication that a
|
||||
scan is running. Or maybe a different sort of indication is in
|
||||
order. [David]
|
||||
|
||||
o Improvements to presentation of version detection
|
||||
information. [Brandon]
|
||||
o Allow longer strings. Right now it can be 128 chars for the
|
||||
fullversion info, I think. But that isn't enough for this useful
|
||||
information-packed string: "Apache httpd 2.0.52 ((Red Hat)
|
||||
mod_perl/1.99_16 Perl/v5.8.5 DAV/2 mod_jk/1.2.19 PHP/4.3.9
|
||||
mod_python/3.1.3 Python/2.3.4 mod_ssl/2.0.52 OpenSSL/0.9.7a)".
|
||||
After discussion w/Brandon, we're going to allow 160 chars total.
|
||||
o Instead of omitting all information when version info string too
|
||||
long, we're going to truncate and allow 157 characters, plus
|
||||
ellipses (...)
|
||||
o Brandon says: "my final gripe is that the full version string is
|
||||
constructed as <product><space><version><space>(<extrainfo>).
|
||||
but, even if product or version are blank, the spaces are still
|
||||
there"
|
||||
|
||||
o Change Nmap signature files to use the .sig extension rather than
|
||||
.gpg.txt, as that seems to be what gpg recommends. In fact, gpg
|
||||
will automatically verify the right file if it exists after dropping
|
||||
@@ -562,6 +546,22 @@ o random tip database
|
||||
|
||||
DONE:
|
||||
|
||||
o Improvements to presentation of version detection
|
||||
information. [Brandon]
|
||||
o Allow longer strings. Right now it can be 128 chars for the
|
||||
fullversion info, I think. But that isn't enough for this useful
|
||||
information-packed string: "Apache httpd 2.0.52 ((Red Hat)
|
||||
mod_perl/1.99_16 Perl/v5.8.5 DAV/2 mod_jk/1.2.19 PHP/4.3.9
|
||||
mod_python/3.1.3 Python/2.3.4 mod_ssl/2.0.52 OpenSSL/0.9.7a)".
|
||||
After discussion w/Brandon, we're going to allow 160 chars total.
|
||||
o Instead of omitting all information when version info string too
|
||||
long, we're going to truncate and allow 157 characters, plus
|
||||
ellipses (...)
|
||||
o Brandon says: "my final gripe is that the full version string is
|
||||
constructed as <product><space><version><space>(<extrainfo>).
|
||||
but, even if product or version are blank, the spaces are still
|
||||
there"
|
||||
|
||||
o I need an output-autoflush option of some sort. This could be
|
||||
useful to ensure I get all the --packet_trace and debug data before
|
||||
Nmap crashes. Actually, I'm not sure that is so critical.
|
||||
|
||||
77
portlist.cc
77
portlist.cc
@@ -147,26 +147,67 @@ Port::~Port() {
|
||||
// out sd->fullversion. If unavailable, it will be set to zero length.
|
||||
static void populateFullVersionString(struct serviceDeductions *sd) {
|
||||
char *dst = sd->fullversion;
|
||||
unsigned int spaceleft = sizeof(sd->fullversion) - 1;
|
||||
unsigned int spaceleft = sizeof(sd->fullversion) - 1; // Leave room for \0
|
||||
int needpad = 0; // Do we need to pad a space between the next template?
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
if (sd->product && spaceleft >= strlen(sd->product)) {
|
||||
strncat(dst, sd->product, spaceleft);
|
||||
spaceleft -= strlen(sd->product);
|
||||
/* Sometimes there is really great product/version/extra information
|
||||
* available that won't quite fit. Rather than just drop that information
|
||||
* this routine will truncate the string that is too long with "...".
|
||||
* If there are fewer than 8 characters left don't bother and just skip
|
||||
* that bit of information.
|
||||
*/
|
||||
|
||||
if (sd->product && spaceleft >= 8) {
|
||||
if (spaceleft < strlen(sd->product)) {
|
||||
strncat(dst, sd->product, spaceleft - 3); // Leave room for "..."
|
||||
strncat(dst, "...", spaceleft);
|
||||
spaceleft = 0;
|
||||
}
|
||||
else {
|
||||
strncat(dst, sd->product, spaceleft);
|
||||
spaceleft -= strlen(sd->product);
|
||||
}
|
||||
needpad = 1;
|
||||
}
|
||||
|
||||
if (sd->version && spaceleft >= (strlen(sd->version) + 1)) {
|
||||
strncat(dst, " ", spaceleft);
|
||||
strncat(dst, sd->version, spaceleft);
|
||||
spaceleft -= strlen(sd->version) + 1;
|
||||
if (sd->version && spaceleft >= 8) {
|
||||
if (needpad) {
|
||||
strncat(dst, " ", spaceleft);
|
||||
spaceleft--;
|
||||
}
|
||||
|
||||
if (spaceleft < strlen(sd->version)) {
|
||||
strncat(dst, sd->version, spaceleft - 3);
|
||||
strncat(dst, "...", spaceleft);
|
||||
spaceleft = 0;
|
||||
}
|
||||
else {
|
||||
strncat(dst, sd->version, spaceleft);
|
||||
spaceleft -= strlen(sd->version);
|
||||
}
|
||||
needpad = 1;
|
||||
}
|
||||
|
||||
if (sd->extrainfo && spaceleft >= (strlen(sd->extrainfo) + 3)) {
|
||||
strncat(dst, " (", spaceleft);
|
||||
strncat(dst, sd->extrainfo, spaceleft);
|
||||
if (sd->extrainfo && spaceleft >= 8) {
|
||||
if (needpad) {
|
||||
strncat(dst, " ", spaceleft);
|
||||
spaceleft--;
|
||||
}
|
||||
// This time we need to trucate inside of the () so we have spaceleft - 2
|
||||
strncat(dst, "(", spaceleft);
|
||||
if (spaceleft - 2 < strlen(sd->extrainfo)) {
|
||||
strncat(dst, sd->extrainfo, spaceleft - 5);
|
||||
strncat(dst, "...", spaceleft - 2);
|
||||
spaceleft = 1; // Fit the paren
|
||||
}
|
||||
else {
|
||||
strncat(dst, sd->extrainfo, spaceleft);
|
||||
spaceleft -= (strlen(sd->extrainfo) + 2);
|
||||
}
|
||||
strncat(dst, ")", spaceleft);
|
||||
spaceleft -= strlen(sd->extrainfo) + 3;
|
||||
spaceleft--;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -296,12 +337,12 @@ void Port::setServiceProbeResults(enum serviceprobestate sres,
|
||||
else
|
||||
serviceprobe_fp = NULL;
|
||||
|
||||
serviceprobe_product = cstringSanityCheck(product, 64);
|
||||
serviceprobe_version = cstringSanityCheck(version, 64);
|
||||
serviceprobe_extrainfo = cstringSanityCheck(extrainfo, 128);
|
||||
serviceprobe_hostname = cstringSanityCheck(hostname, 64);
|
||||
serviceprobe_ostype = cstringSanityCheck(ostype, 64);
|
||||
serviceprobe_devicetype = cstringSanityCheck(devicetype, 64);
|
||||
serviceprobe_product = cstringSanityCheck(product, 80);
|
||||
serviceprobe_version = cstringSanityCheck(version, 80);
|
||||
serviceprobe_extrainfo = cstringSanityCheck(extrainfo, 256);
|
||||
serviceprobe_hostname = cstringSanityCheck(hostname, 80);
|
||||
serviceprobe_ostype = cstringSanityCheck(ostype, 32);
|
||||
serviceprobe_devicetype = cstringSanityCheck(devicetype, 32);
|
||||
}
|
||||
|
||||
/* Sets the results of an RPC scan. if rpc_status is not
|
||||
|
||||
@@ -159,7 +159,7 @@ struct serviceDeductions {
|
||||
enum service_tunnel_type service_tunnel;
|
||||
// This is a combined representation of product, version, and extrainfo.
|
||||
// It will be zero length if unavailable.
|
||||
char fullversion[128];
|
||||
char fullversion[160];
|
||||
// if we should give the user a service fingerprint to submit, here it is. Otherwise NULL.
|
||||
const char *service_fp;
|
||||
enum service_detection_type dtype; // definition above
|
||||
|
||||
@@ -155,10 +155,10 @@ public:
|
||||
// is placed in these 6 strings. Otherwise the string will be 0 length.
|
||||
char product_matched[80];
|
||||
char version_matched[80];
|
||||
char extrainfo_matched[128];
|
||||
char hostname_matched[128];
|
||||
char ostype_matched[64];
|
||||
char devicetype_matched[64];
|
||||
char extrainfo_matched[256];
|
||||
char hostname_matched[80];
|
||||
char ostype_matched[32];
|
||||
char devicetype_matched[32];
|
||||
enum service_tunnel_type tunnel; /* SERVICE_TUNNEL_NONE, SERVICE_TUNNEL_SSL */
|
||||
// This stores our SSL session id, which will help speed up subsequent
|
||||
// SSL connections. It's overwritten each time. void* is used so we don't
|
||||
@@ -445,7 +445,7 @@ const struct MatchDetails *ServiceProbeMatch::testMatch(const u8 *buf, int bufle
|
||||
int i;
|
||||
static char product[80];
|
||||
static char version[80];
|
||||
static char info[128];
|
||||
static char info[256]; /* We will truncate with ... later */
|
||||
static char hostname[80];
|
||||
static char ostype[32];
|
||||
static char devicetype[32];
|
||||
@@ -770,8 +770,10 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (product_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, product_template, product, productlen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill product_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",
|
||||
(version_template)? version_template : "", (info_template)? info_template : "");
|
||||
error("Warning: Servicescan failed to fill product_template (subjectlen: %d, productlen: %d). Capture exceeds length? Match string was line %d: v/%s/%s/%s", subjectlen, productlen, deflineno,
|
||||
(product_template)? product_template : "",
|
||||
(version_template)? version_template : "",
|
||||
(info_template)? info_template : "");
|
||||
if (productlen > 0) *product = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
@@ -780,8 +782,10 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (version_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, version_template, version, versionlen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill version_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",
|
||||
(version_template)? version_template : "", (info_template)? info_template : "");
|
||||
error("Warning: Servicescan failed to fill version_template (subjectlen: %d, versionlen: %d). Capture exceeds length? Match string was line %d: v/%s/%s/%s", subjectlen, versionlen, deflineno,
|
||||
(product_template)? product_template : "",
|
||||
(version_template)? version_template : "",
|
||||
(info_template)? info_template : "");
|
||||
if (versionlen > 0) *version = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
@@ -790,8 +794,10 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (info_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, info_template, info, infolen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill info_template (subjectlen: %d). Too long? Match string was line %d: v/%s/%s/%s", subjectlen, deflineno, (product_template)? product_template : "",
|
||||
(version_template)? version_template : "", (info_template)? info_template : "");
|
||||
error("Warning: Servicescan failed to fill info_template (subjectlen: %d, infolen: %d). Capture exceeds length? Match string was line %d: v/%s/%s/%s", subjectlen, infolen, deflineno,
|
||||
(product_template)? product_template : "",
|
||||
(version_template)? version_template : "",
|
||||
(info_template)? info_template : "");
|
||||
if (infolen > 0) *info = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
@@ -800,7 +806,8 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (hostname_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, hostname_template, hostname, hostnamelen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill hostname_template (subjectlen: %d). Too long? Match string was line %d: h/%s/", subjectlen, deflineno, (hostname_template)? hostname_template : "");
|
||||
error("Warning: Servicescan failed to fill hostname_template (subjectlen: %d, hostnamelen: %d). Capture exceeds length? Match string was line %d: h/%s/", subjectlen, hostnamelen, deflineno,
|
||||
(hostname_template)? hostname_template : "");
|
||||
if (hostnamelen > 0) *hostname = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
@@ -809,7 +816,8 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (ostype_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, ostype_template, ostype, ostypelen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill ostype_template (subjectlen: %d). Too long? Match string was line %d: p/%s/", subjectlen, deflineno, (ostype_template)? ostype_template : "");
|
||||
error("Warning: Servicescan failed to fill ostype_template (subjectlen: %d, ostypelen: %d). Capture exceeds length? Match string was line %d: p/%s/", subjectlen, ostypelen, deflineno,
|
||||
(ostype_template)? ostype_template : "");
|
||||
if (ostypelen > 0) *ostype = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
@@ -818,7 +826,8 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen,
|
||||
if (devicetype_template) {
|
||||
rc = dotmplsubst(subject, subjectlen, ovector, nummatches, devicetype_template, devicetype, devicetypelen);
|
||||
if (rc != 0) {
|
||||
error("Warning: Servicescan failed to fill devicetype_template (subjectlen: %d). Too long? Match string was line %d: d/%s/", subjectlen, deflineno, (devicetype_template)? devicetype_template : "");
|
||||
error("Warning: Servicescan failed to fill devicetype_template (subjectlen: %d, devicetypelen: %d). Too long? Match string was line %d: d/%s/", subjectlen, devicetypelen, deflineno,
|
||||
(devicetype_template)? devicetype_template : "");
|
||||
if (devicetypelen > 0) *devicetype = '\0';
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user