diff options
author | Andrew Geissler <geissonator@yahoo.com> | 2020-04-13 21:39:40 +0300 |
---|---|---|
committer | Andrew Geissler <geissonator@yahoo.com> | 2020-05-05 16:30:44 +0300 |
commit | 82c905dc58a36aeae40b1b273a12f63fb1973cf4 (patch) | |
tree | 38caf00263451b5036435cdc36e035b25d32e623 /meta-openembedded/meta-oe/recipes-security/nmap | |
parent | 83ecb75644b3d677c274188f9ac0b2374d6f6925 (diff) | |
download | openbmc-82c905dc58a36aeae40b1b273a12f63fb1973cf4.tar.xz |
meta-openembedded and poky: subtree updates
Squash of the following due to dependencies among them
and OpenBMC changes:
meta-openembedded: subtree update:d0748372d2..9201611135
meta-openembedded: subtree update:9201611135..17fd382f34
poky: subtree update:9052e5b32a..2e11d97b6c
poky: subtree update:2e11d97b6c..a8544811d7
The change log was too large for the jenkins plugin
to handle therefore it has been removed. Here is
the first and last commit of each subtree:
meta-openembedded:d0748372d2
cppzmq: bump to version 4.6.0
meta-openembedded:17fd382f34
mpv: Remove X11 dependency
poky:9052e5b32a
package_ipk: Remove pointless comment to trigger rebuild
poky:a8544811d7
pbzip2: Fix license warning
Change-Id: If0fc6c37629642ee207a4ca2f7aa501a2c673cd6
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Diffstat (limited to 'meta-openembedded/meta-oe/recipes-security/nmap')
3 files changed, 1779 insertions, 3 deletions
diff --git a/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-Make-ndiff-support-python3.patch b/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-Make-ndiff-support-python3.patch new file mode 100644 index 0000000000..2ca18b0efb --- /dev/null +++ b/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-Make-ndiff-support-python3.patch @@ -0,0 +1,1720 @@ +From bbbf474b2ebdbdac4d557e3351210f3fe2175c33 Mon Sep 17 00:00:00 2001 +From: Mingli Yu <mingli.yu@windriver.com> +Date: Fri, 14 Feb 2020 10:09:55 +0000 +Subject: [PATCH] Make ndiff support python3 + +Backport a patch from debian to make ndiff support +python3. + +Refer to https://sources.debian.org/data/main/n/nmap/7.80+dfsg1-2/debian/patches/0004-Python3-port-of-ndiff.patch + +Upstream-Status: Pending + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + Makefile.in | 12 +- + ndiff/ndiff.py | 495 +++++++++++++++++----------------- + ndiff/ndifftest.py | 94 +++---- + ndiff/scripts/ndiff | 14 +- + ndiff/setup.py | 34 +-- + ndiff/test-scans/anonymize.py | 18 +- + 6 files changed, 333 insertions(+), 334 deletions(-) + mode change 100644 => 100755 ndiff/setup.py + +diff --git a/Makefile.in b/Makefile.in +index eee8863..32f86ba 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -35,6 +35,7 @@ ZENMAPDIR = @ZENMAPDIR@ + NDIFFDIR = @NDIFFDIR@ + NPINGDIR = @NPINGDIR@ + PYTHON = @PYTHON@ ++PYTHON3 = /usr/bin/env python3 + DEFS = @DEFS@ -DNMAP_PLATFORM=\"$(NMAP_PLATFORM)\" -DNMAPDATADIR=\"$(nmapdatadir)\" + # With GCC, add extra security checks to source code. + # http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html +@@ -260,7 +261,7 @@ clean-zenmap: + rm -f $(ZENMAPDIR)/zenmapCore/Name.pyc + + clean-ndiff: +- -cd $(NDIFFDIR) && $(PYTHON) setup.py clean --all ++ -cd $(NDIFFDIR) && $(PYTHON3) setup.py clean --all + + clean-nping: + -cd $(NPINGDIR) && $(MAKE) clean +@@ -368,6 +369,7 @@ tests/check_dns: $(OBJS) + # this as the location of the interpreter whenever we're not doing a + # local installation. + DEFAULT_PYTHON_PATH = /usr/bin/env python ++DEFAULT_PYTHON3_PATH = /usr/bin/env python3 + + build-zenmap: $(ZENMAPDIR)/setup.py $(ZENMAPDIR)/zenmapCore/Version.py + # When DESTDIR is defined, assume we're building an executable +@@ -388,13 +390,13 @@ install-zenmap: $(ZENMAPDIR)/setup.py + ln -sf zenmap $(DESTDIR)$(bindir)/xnmap + + build-ndiff: +- cd $(NDIFFDIR) && $(PYTHON) setup.py build $(if $(DESTDIR),--executable "$(DEFAULT_PYTHON_PATH)") ++ cd $(NDIFFDIR) && $(PYTHON3) setup.py build $(if $(DESTDIR),--executable "$(DEFAULT_PYTHON3_PATH)") + + build-nping: $(NPINGDIR)/Makefile build-nbase build-nsock build-netutil $(NPINGDIR)/nping.h @DNET_BUILD@ @PCAP_BUILD@ + @cd $(NPINGDIR) && $(MAKE) + + install-ndiff: +- cd $(NDIFFDIR) && $(PYTHON) setup.py install --prefix "$(prefix)" --install-lib="${PYTHON_SITEPACKAGES_DIR}" $(if $(DESTDIR),--root "$(DESTDIR)") ++ cd $(NDIFFDIR) && $(PYTHON3) setup.py install --prefix "$(prefix)" --install-lib="${PYTHON_SITEPACKAGES_DIR}" $(if $(DESTDIR),--root "$(DESTDIR)") + + NSE_FILES = scripts/script.db scripts/*.nse + NSE_LIB_LUA_FILES = nselib/*.lua nselib/*.luadoc +@@ -443,7 +445,7 @@ uninstall-zenmap: + rm -f $(DESTDIR)$(bindir)/xnmap + + uninstall-ndiff: +- cd $(NDIFFDIR) && $(PYTHON) setup.py uninstall ++ cd $(NDIFFDIR) && $(PYTHON3) setup.py uninstall + + uninstall-ncat: + @cd $(NCATDIR) && $(MAKE) uninstall +@@ -458,7 +460,7 @@ check-ncat: + @cd $(NCATDIR) && $(MAKE) check + + check-ndiff: +- @cd $(NDIFFDIR) && $(PYTHON) ndifftest.py ++ @cd $(NDIFFDIR) && $(PYTHON3) ndifftest.py + + check-nsock: + @cd $(NSOCKDIR)/src && $(MAKE) check +diff --git a/ndiff/ndiff.py b/ndiff/ndiff.py +index 043273f..abbd1c5 100755 +--- a/ndiff/ndiff.py ++++ b/ndiff/ndiff.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + + # Ndiff + # +@@ -26,11 +26,11 @@ xml.__path__ = [x for x in xml.__path__ if "_xmlplus" not in x] + import xml.sax + import xml.sax.saxutils + import xml.dom.minidom +-from StringIO import StringIO ++from io import StringIO + + verbose = False + +-NDIFF_XML_VERSION = u"1" ++NDIFF_XML_VERSION = "1" + + + class OverrideEntityResolver(xml.sax.handler.EntityResolver): +@@ -78,35 +78,35 @@ class Scan(object): + def write_nmaprun_open(self, writer): + attrs = {} + if self.scanner is not None: +- attrs[u"scanner"] = self.scanner ++ attrs["scanner"] = self.scanner + if self.args is not None: +- attrs[u"args"] = self.args ++ attrs["args"] = self.args + if self.start_date is not None: +- attrs[u"start"] = "%d" % time.mktime(self.start_date.timetuple()) +- attrs[u"startstr"] = self.start_date.strftime( ++ attrs["start"] = "%d" % time.mktime(self.start_date.timetuple()) ++ attrs["startstr"] = self.start_date.strftime( + "%a %b %d %H:%M:%S %Y") + if self.version is not None: +- attrs[u"version"] = self.version +- writer.startElement(u"nmaprun", attrs) ++ attrs["version"] = self.version ++ writer.startElement("nmaprun", attrs) + + def write_nmaprun_close(self, writer): +- writer.endElement(u"nmaprun") ++ writer.endElement("nmaprun") + + def nmaprun_to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"nmaprun") ++ elem = document.createElement("nmaprun") + if self.scanner is not None: +- elem.setAttribute(u"scanner", self.scanner) ++ elem.setAttribute("scanner", self.scanner) + if self.args is not None: +- elem.setAttribute(u"args", self.args) ++ elem.setAttribute("args", self.args) + if self.start_date is not None: + elem.setAttribute( +- u"start", "%d" % time.mktime(self.start_date.timetuple())) ++ "start", "%d" % time.mktime(self.start_date.timetuple())) + elem.setAttribute( +- u"startstr", ++ "startstr", + self.start_date.strftime("%a %b %d %H:%M:%S %Y")) + if self.version is not None: +- elem.setAttribute(u"version", self.version) ++ elem.setAttribute("version", self.version) + frag.appendChild(elem) + return frag + +@@ -136,17 +136,17 @@ class Host(object): + + def format_name(self): + """Return a human-readable identifier for this host.""" +- address_s = u", ".join(a.s for a in sorted(self.addresses)) +- hostname_s = u", ".join(sorted(self.hostnames)) ++ address_s = ", ".join(a.s for a in sorted(self.addresses)) ++ hostname_s = ", ".join(sorted(self.hostnames)) + if len(hostname_s) > 0: + if len(address_s) > 0: +- return u"%s (%s)" % (hostname_s, address_s) ++ return "%s (%s)" % (hostname_s, address_s) + else: + return hostname_s + elif len(address_s) > 0: + return address_s + else: +- return u"<no name>" ++ return "<no name>" + + def add_port(self, port): + self.ports[port.spec] = port +@@ -163,46 +163,46 @@ class Host(object): + return state is None or state in self.extraports + + def extraports_string(self): +- list = [(count, state) for (state, count) in self.extraports.items()] ++ locallist = [(count, state) for (state, count) in list(self.extraports.items())] + # Reverse-sort by count. +- list.sort(reverse=True) +- return u", ".join( +- [u"%d %s ports" % (count, state) for (count, state) in list]) ++ locallist.sort(reverse=True) ++ return ", ".join( ++ ["%d %s ports" % (count, state) for (count, state) in locallist]) + + def state_to_dom_fragment(self, document): + frag = document.createDocumentFragment() + if self.state is not None: +- elem = document.createElement(u"status") +- elem.setAttribute(u"state", self.state) ++ elem = document.createElement("status") ++ elem.setAttribute("state", self.state) + frag.appendChild(elem) + return frag + + def hostname_to_dom_fragment(self, document, hostname): + frag = document.createDocumentFragment() +- elem = document.createElement(u"hostname") +- elem.setAttribute(u"name", hostname) ++ elem = document.createElement("hostname") ++ elem.setAttribute("name", hostname) + frag.appendChild(elem) + return frag + + def extraports_to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- for state, count in self.extraports.items(): +- elem = document.createElement(u"extraports") +- elem.setAttribute(u"state", state) +- elem.setAttribute(u"count", unicode(count)) ++ for state, count in list(self.extraports.items()): ++ elem = document.createElement("extraports") ++ elem.setAttribute("state", state) ++ elem.setAttribute("count", str(count)) + frag.appendChild(elem) + return frag + + def os_to_dom_fragment(self, document, os): + frag = document.createDocumentFragment() +- elem = document.createElement(u"osmatch") +- elem.setAttribute(u"name", os) ++ elem = document.createElement("osmatch") ++ elem.setAttribute("name", os) + frag.appendChild(elem) + return frag + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"host") ++ elem = document.createElement("host") + + if self.state is not None: + elem.appendChild(self.state_to_dom_fragment(document)) +@@ -211,13 +211,13 @@ class Host(object): + elem.appendChild(addr.to_dom_fragment(document)) + + if len(self.hostnames) > 0: +- hostnames_elem = document.createElement(u"hostnames") ++ hostnames_elem = document.createElement("hostnames") + for hostname in self.hostnames: + hostnames_elem.appendChild( + self.hostname_to_dom_fragment(document, hostname)) + elem.appendChild(hostnames_elem) + +- ports_elem = document.createElement(u"ports") ++ ports_elem = document.createElement("ports") + ports_elem.appendChild(self.extraports_to_dom_fragment(document)) + for port in sorted(self.ports.values()): + if not self.is_extraports(port.state): +@@ -226,13 +226,13 @@ class Host(object): + elem.appendChild(ports_elem) + + if len(self.os) > 0: +- os_elem = document.createElement(u"os") ++ os_elem = document.createElement("os") + for os in self.os: + os_elem.appendChild(self.os_to_dom_fragment(document, os)) + elem.appendChild(os_elem) + + if len(self.script_results) > 0: +- hostscript_elem = document.createElement(u"hostscript") ++ hostscript_elem = document.createElement("hostscript") + for sr in self.script_results: + hostscript_elem.appendChild(sr.to_dom_fragment(document)) + elem.appendChild(hostscript_elem) +@@ -246,7 +246,7 @@ class Address(object): + self.s = s + + def __eq__(self, other): +- return self.__cmp__(other) == 0 ++ return self.sort_key() == other.sort_key() + + def __ne__(self, other): + return not self.__eq__(other) +@@ -254,8 +254,8 @@ class Address(object): + def __hash__(self): + return hash(self.sort_key()) + +- def __cmp__(self, other): +- return cmp(self.sort_key(), other.sort_key()) ++ def __lt__(self, other): ++ return self.sort_key() < other.sort_key() + + def __str__(self): + return str(self.s) +@@ -264,21 +264,21 @@ class Address(object): + return self.s + + def new(type, s): +- if type == u"ipv4": ++ if type == "ipv4": + return IPv4Address(s) +- elif type == u"ipv6": ++ elif type == "ipv6": + return IPv6Address(s) +- elif type == u"mac": ++ elif type == "mac": + return MACAddress(s) + else: +- raise ValueError(u"Unknown address type %s." % type) ++ raise ValueError("Unknown address type %s." % type) + new = staticmethod(new) + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"address") +- elem.setAttribute(u"addr", self.s) +- elem.setAttribute(u"addrtype", self.type) ++ elem = document.createElement("address") ++ elem.setAttribute("addr", self.s) ++ elem.setAttribute("addrtype", self.type) + frag.appendChild(elem) + return frag + +@@ -287,21 +287,21 @@ class Address(object): + + + class IPv4Address(Address): +- type = property(lambda self: u"ipv4") ++ type = property(lambda self: "ipv4") + + def sort_key(self): + return (0, self.s) + + + class IPv6Address(Address): +- type = property(lambda self: u"ipv6") ++ type = property(lambda self: "ipv6") + + def sort_key(self): + return (1, self.s) + + + class MACAddress(Address): +- type = property(lambda self: u"mac") ++ type = property(lambda self: "mac") + + def sort_key(self): + return (2, self.s) +@@ -320,28 +320,25 @@ class Port(object): + + def state_string(self): + if self.state is None: +- return u"unknown" ++ return "unknown" + else: +- return unicode(self.state) ++ return str(self.state) + + def spec_string(self): +- return u"%d/%s" % self.spec ++ return "%d/%s" % self.spec + +- def __cmp__(self, other): +- d = cmp(self.spec, other.spec) +- if d != 0: +- return d +- return cmp((self.spec, self.service, self.script_results), +- (other.spec, other.service, other.script_results)) ++ def __lt__(self, other): ++ return (self.spec, self.service, self.script_results) < ( ++ other.spec, other.service, other.script_results) + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"port") +- elem.setAttribute(u"portid", unicode(self.spec[0])) +- elem.setAttribute(u"protocol", self.spec[1]) ++ elem = document.createElement("port") ++ elem.setAttribute("portid", str(self.spec[0])) ++ elem.setAttribute("protocol", self.spec[1]) + if self.state is not None: +- state_elem = document.createElement(u"state") +- state_elem.setAttribute(u"state", self.state) ++ state_elem = document.createElement("state") ++ state_elem.setAttribute("state", self.state) + elem.appendChild(state_elem) + elem.appendChild(self.service.to_dom_fragment(document)) + for sr in self.script_results: +@@ -385,7 +382,7 @@ class Service(object): + if len(parts) == 0: + return None + else: +- return u"/".join(parts) ++ return "/".join(parts) + + def version_string(self): + """Get a string like in the VERSION column of Nmap output.""" +@@ -395,17 +392,17 @@ class Service(object): + if self.version is not None: + parts.append(self.version) + if self.extrainfo is not None: +- parts.append(u"(%s)" % self.extrainfo) ++ parts.append("(%s)" % self.extrainfo) + + if len(parts) == 0: + return None + else: +- return u" ".join(parts) ++ return " ".join(parts) + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"service") +- for attr in (u"name", u"product", u"version", u"extrainfo", u"tunnel"): ++ elem = document.createElement("service") ++ for attr in ("name", "product", "version", "extrainfo", "tunnel"): + v = getattr(self, attr) + if v is None: + continue +@@ -435,53 +432,53 @@ class ScriptResult(object): + result = [] + lines = self.output.splitlines() + if len(lines) > 0: +- lines[0] = self.id + u": " + lines[0] ++ lines[0] = self.id + ": " + lines[0] + for line in lines[:-1]: +- result.append(u"| " + line) ++ result.append("| " + line) + if len(lines) > 0: +- result.append(u"|_ " + lines[-1]) ++ result.append("|_ " + lines[-1]) + return result + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- elem = document.createElement(u"script") +- elem.setAttribute(u"id", self.id) +- elem.setAttribute(u"output", self.output) ++ elem = document.createElement("script") ++ elem.setAttribute("id", self.id) ++ elem.setAttribute("output", self.output) + frag.appendChild(elem) + return frag + + + def format_banner(scan): + """Format a startup banner more or less like Nmap does.""" +- scanner = u"Nmap" +- if scan.scanner is not None and scan.scanner != u"nmap": ++ scanner = "Nmap" ++ if scan.scanner is not None and scan.scanner != "nmap": + scanner = scan.scanner + parts = [scanner] + if scan.version is not None: + parts.append(scan.version) +- parts.append(u"scan") ++ parts.append("scan") + if scan.start_date is not None: +- parts.append(u"initiated %s" % scan.start_date.strftime( ++ parts.append("initiated %s" % scan.start_date.strftime( + "%a %b %d %H:%M:%S %Y")) + if scan.args is not None: +- parts.append(u"as: %s" % scan.args) +- return u" ".join(parts) ++ parts.append("as: %s" % scan.args) ++ return " ".join(parts) + + + def print_script_result_diffs_text(title, script_results_a, script_results_b, + script_result_diffs, f=sys.stdout): +- table = Table(u"*") ++ table = Table("*") + for sr_diff in script_result_diffs: + sr_diff.append_to_port_table(table) + if len(table) > 0: +- print >> f ++ print(file=f) + if len(script_results_b) == 0: +- print >> f, u"-%s:" % title ++ print("-%s:" % title, file=f) + elif len(script_results_a) == 0: +- print >> f, u"+%s:" % title ++ print("+%s:" % title, file=f) + else: +- print >> f, u" %s:" % title +- print >> f, table ++ print(" %s:" % title, file=f) ++ print(table, file=f) + + + def script_result_diffs_to_dom_fragment(elem, script_results_a, +@@ -489,13 +486,13 @@ def script_result_diffs_to_dom_fragment(elem, script_results_a, + if len(script_results_a) == 0 and len(script_results_b) == 0: + return document.createDocumentFragment() + elif len(script_results_b) == 0: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + for sr in script_results_a: + elem.appendChild(sr.to_dom_fragment(document)) + a_elem.appendChild(elem) + return a_elem + elif len(script_results_a) == 0: +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + for sr in script_results_b: + elem.appendChild(sr.to_dom_fragment(document)) + b_elem.appendChild(elem) +@@ -581,10 +578,10 @@ class ScanDiffText(ScanDiff): + banner_a = format_banner(self.scan_a) + banner_b = format_banner(self.scan_b) + if banner_a != banner_b: +- print >> self.f, u"-%s" % banner_a +- print >> self.f, u"+%s" % banner_b ++ print("-%s" % banner_a, file=self.f) ++ print("+%s" % banner_b, file=self.f) + elif verbose: +- print >> self.f, u" %s" % banner_a ++ print(" %s" % banner_a, file=self.f) + + def output_pre_scripts(self, pre_script_result_diffs): + print_script_result_diffs_text("Pre-scan script results", +@@ -597,7 +594,7 @@ class ScanDiffText(ScanDiff): + post_script_result_diffs, self.f) + + def output_host_diff(self, h_diff): +- print >> self.f ++ print(file=self.f) + h_diff.print_text(self.f) + + def output_ending(self): +@@ -622,8 +619,8 @@ class ScanDiffXML(ScanDiff): + + def output_beginning(self): + self.writer.startDocument() +- self.writer.startElement(u"nmapdiff", {u"version": NDIFF_XML_VERSION}) +- self.writer.startElement(u"scandiff", {}) ++ self.writer.startElement("nmapdiff", {"version": NDIFF_XML_VERSION}) ++ self.writer.startElement("scandiff", {}) + + if self.nmaprun_differs(): + self.writer.frag_a( +@@ -636,7 +633,7 @@ class ScanDiffXML(ScanDiff): + + def output_pre_scripts(self, pre_script_result_diffs): + if len(pre_script_result_diffs) > 0 or verbose: +- prescript_elem = self.document.createElement(u"prescript") ++ prescript_elem = self.document.createElement("prescript") + frag = script_result_diffs_to_dom_fragment( + prescript_elem, self.scan_a.pre_script_results, + self.scan_b.pre_script_results, pre_script_result_diffs, +@@ -646,7 +643,7 @@ class ScanDiffXML(ScanDiff): + + def output_post_scripts(self, post_script_result_diffs): + if len(post_script_result_diffs) > 0 or verbose: +- postscript_elem = self.document.createElement(u"postscript") ++ postscript_elem = self.document.createElement("postscript") + frag = script_result_diffs_to_dom_fragment( + postscript_elem, self.scan_a.post_script_results, + self.scan_b.post_script_results, post_script_result_diffs, +@@ -660,8 +657,8 @@ class ScanDiffXML(ScanDiff): + frag.unlink() + + def output_ending(self): +- self.writer.endElement(u"scandiff") +- self.writer.endElement(u"nmapdiff") ++ self.writer.endElement("scandiff") ++ self.writer.endElement("nmapdiff") + self.writer.endDocument() + + +@@ -719,9 +716,9 @@ class HostDiff(object): + self.cost += os_cost + + extraports_a = tuple((count, state) +- for (state, count) in self.host_a.extraports.items()) ++ for (state, count) in list(self.host_a.extraports.items())) + extraports_b = tuple((count, state) +- for (state, count) in self.host_b.extraports.items()) ++ for (state, count) in list(self.host_b.extraports.items())) + if extraports_a != extraports_b: + self.extraports_changed = True + self.cost += 1 +@@ -747,69 +744,69 @@ class HostDiff(object): + # Names and addresses. + if self.id_changed: + if host_a.state is not None: +- print >> f, u"-%s:" % host_a.format_name() ++ print("-%s:" % host_a.format_name(), file=f) + if self.host_b.state is not None: +- print >> f, u"+%s:" % host_b.format_name() ++ print("+%s:" % host_b.format_name(), file=f) + else: +- print >> f, u" %s:" % host_a.format_name() ++ print(" %s:" % host_a.format_name(), file=f) + + # State. + if self.state_changed: + if host_a.state is not None: +- print >> f, u"-Host is %s." % host_a.state ++ print("-Host is %s." % host_a.state, file=f) + if host_b.state is not None: +- print >> f, u"+Host is %s." % host_b.state ++ print("+Host is %s." % host_b.state, file=f) + elif verbose: +- print >> f, u" Host is %s." % host_b.state ++ print(" Host is %s." % host_b.state, file=f) + + # Extraports. + if self.extraports_changed: + if len(host_a.extraports) > 0: +- print >> f, u"-Not shown: %s" % host_a.extraports_string() ++ print("-Not shown: %s" % host_a.extraports_string(), file=f) + if len(host_b.extraports) > 0: +- print >> f, u"+Not shown: %s" % host_b.extraports_string() ++ print("+Not shown: %s" % host_b.extraports_string(), file=f) + elif verbose: + if len(host_a.extraports) > 0: +- print >> f, u" Not shown: %s" % host_a.extraports_string() ++ print(" Not shown: %s" % host_a.extraports_string(), file=f) + + # Port table. +- port_table = Table(u"** * * *") ++ port_table = Table("** * * *") + if host_a.state is None: +- mark = u"+" ++ mark = "+" + elif host_b.state is None: +- mark = u"-" ++ mark = "-" + else: +- mark = u" " +- port_table.append((mark, u"PORT", u"STATE", u"SERVICE", u"VERSION")) ++ mark = " " ++ port_table.append((mark, "PORT", "STATE", "SERVICE", "VERSION")) + + for port in self.ports: + port_diff = self.port_diffs[port] + port_diff.append_to_port_table(port_table, host_a, host_b) + + if len(port_table) > 1: +- print >> f, port_table ++ print(port_table, file=f) + + # OS changes. + if self.os_changed or verbose: + if len(host_a.os) > 0: + if len(host_b.os) > 0: +- print >> f, u" OS details:" ++ print(" OS details:", file=f) + else: +- print >> f, u"-OS details:" ++ print("-OS details:", file=f) + elif len(host_b.os) > 0: +- print >> f, u"+OS details:" ++ print("+OS details:", file=f) + # os_diffs is a list of 5-tuples returned by + # difflib.SequenceMatcher. + for op, i1, i2, j1, j2 in self.os_diffs: + if op == "replace" or op == "delete": + for i in range(i1, i2): +- print >> f, "- %s" % host_a.os[i] ++ print("- %s" % host_a.os[i], file=f) + if op == "replace" or op == "insert": + for i in range(j1, j2): +- print >> f, "+ %s" % host_b.os[i] ++ print("+ %s" % host_b.os[i], file=f) + if op == "equal": + for i in range(i1, i2): +- print >> f, " %s" % host_a.os[i] ++ print(" %s" % host_a.os[i], file=f) + + print_script_result_diffs_text("Host script results", + host_a.script_results, host_b.script_results, +@@ -820,32 +817,32 @@ class HostDiff(object): + host_b = self.host_b + + frag = document.createDocumentFragment() +- hostdiff_elem = document.createElement(u"hostdiff") ++ hostdiff_elem = document.createElement("hostdiff") + frag.appendChild(hostdiff_elem) + + if host_a.state is None or host_b.state is None: + # The host is missing in one scan. Output the whole thing. + if host_a.state is not None: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild(host_a.to_dom_fragment(document)) + hostdiff_elem.appendChild(a_elem) + elif host_b.state is not None: +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild(host_b.to_dom_fragment(document)) + hostdiff_elem.appendChild(b_elem) + return frag + +- host_elem = document.createElement(u"host") ++ host_elem = document.createElement("host") + + # State. + if host_a.state == host_b.state: + if verbose: + host_elem.appendChild(host_a.state_to_dom_fragment(document)) + else: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild(host_a.state_to_dom_fragment(document)) + host_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild(host_b.state_to_dom_fragment(document)) + host_elem.appendChild(b_elem) + +@@ -854,31 +851,31 @@ class HostDiff(object): + addrset_b = set(host_b.addresses) + for addr in sorted(addrset_a.intersection(addrset_b)): + host_elem.appendChild(addr.to_dom_fragment(document)) +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + for addr in sorted(addrset_a - addrset_b): + a_elem.appendChild(addr.to_dom_fragment(document)) + if a_elem.hasChildNodes(): + host_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + for addr in sorted(addrset_b - addrset_a): + b_elem.appendChild(addr.to_dom_fragment(document)) + if b_elem.hasChildNodes(): + host_elem.appendChild(b_elem) + + # Host names. +- hostnames_elem = document.createElement(u"hostnames") ++ hostnames_elem = document.createElement("hostnames") + hostnameset_a = set(host_a.hostnames) + hostnameset_b = set(host_b.hostnames) + for hostname in sorted(hostnameset_a.intersection(hostnameset_b)): + hostnames_elem.appendChild( + host_a.hostname_to_dom_fragment(document, hostname)) +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + for hostname in sorted(hostnameset_a - hostnameset_b): + a_elem.appendChild( + host_a.hostname_to_dom_fragment(document, hostname)) + if a_elem.hasChildNodes(): + hostnames_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + for hostname in sorted(hostnameset_b - hostnameset_a): + b_elem.appendChild( + host_b.hostname_to_dom_fragment(document, hostname)) +@@ -887,15 +884,15 @@ class HostDiff(object): + if hostnames_elem.hasChildNodes(): + host_elem.appendChild(hostnames_elem) + +- ports_elem = document.createElement(u"ports") ++ ports_elem = document.createElement("ports") + # Extraports. + if host_a.extraports == host_b.extraports: + ports_elem.appendChild(host_a.extraports_to_dom_fragment(document)) + else: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild(host_a.extraports_to_dom_fragment(document)) + ports_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild(host_b.extraports_to_dom_fragment(document)) + ports_elem.appendChild(b_elem) + # Port list. +@@ -911,18 +908,18 @@ class HostDiff(object): + + # OS changes. + if self.os_changed or verbose: +- os_elem = document.createElement(u"os") ++ os_elem = document.createElement("os") + # os_diffs is a list of 5-tuples returned by + # difflib.SequenceMatcher. + for op, i1, i2, j1, j2 in self.os_diffs: + if op == "replace" or op == "delete": +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + for i in range(i1, i2): + a_elem.appendChild(host_a.os_to_dom_fragment( + document, host_a.os[i])) + os_elem.appendChild(a_elem) + if op == "replace" or op == "insert": +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + for i in range(j1, j2): + b_elem.appendChild(host_b.os_to_dom_fragment( + document, host_b.os[i])) +@@ -936,7 +933,7 @@ class HostDiff(object): + + # Host script changes. + if len(self.script_result_diffs) > 0 or verbose: +- hostscript_elem = document.createElement(u"hostscript") ++ hostscript_elem = document.createElement("hostscript") + host_elem.appendChild(script_result_diffs_to_dom_fragment( + hostscript_elem, host_a.script_results, + host_b.script_results, self.script_result_diffs, +@@ -989,38 +986,38 @@ class PortDiff(object): + self.port_b.service.version_string()] + if a_columns == b_columns: + if verbose or self.script_result_diffs > 0: +- table.append([u" "] + a_columns) ++ table.append([" "] + a_columns) + else: + if not host_a.is_extraports(self.port_a.state): +- table.append([u"-"] + a_columns) ++ table.append(["-"] + a_columns) + if not host_b.is_extraports(self.port_b.state): +- table.append([u"+"] + b_columns) ++ table.append(["+"] + b_columns) + + for sr_diff in self.script_result_diffs: + sr_diff.append_to_port_table(table) + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +- portdiff_elem = document.createElement(u"portdiff") ++ portdiff_elem = document.createElement("portdiff") + frag.appendChild(portdiff_elem) + if (self.port_a.spec == self.port_b.spec and + self.port_a.state == self.port_b.state): +- port_elem = document.createElement(u"port") +- port_elem.setAttribute(u"portid", unicode(self.port_a.spec[0])) +- port_elem.setAttribute(u"protocol", self.port_a.spec[1]) ++ port_elem = document.createElement("port") ++ port_elem.setAttribute("portid", str(self.port_a.spec[0])) ++ port_elem.setAttribute("protocol", self.port_a.spec[1]) + if self.port_a.state is not None: +- state_elem = document.createElement(u"state") +- state_elem.setAttribute(u"state", self.port_a.state) ++ state_elem = document.createElement("state") ++ state_elem.setAttribute("state", self.port_a.state) + port_elem.appendChild(state_elem) + if self.port_a.service == self.port_b.service: + port_elem.appendChild( + self.port_a.service.to_dom_fragment(document)) + else: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild( + self.port_a.service.to_dom_fragment(document)) + port_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild( + self.port_b.service.to_dom_fragment(document)) + port_elem.appendChild(b_elem) +@@ -1028,10 +1025,10 @@ class PortDiff(object): + port_elem.appendChild(sr_diff.to_dom_fragment(document)) + portdiff_elem.appendChild(port_elem) + else: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild(self.port_a.to_dom_fragment(document)) + portdiff_elem.appendChild(a_elem) +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild(self.port_b.to_dom_fragment(document)) + portdiff_elem.appendChild(b_elem) + +@@ -1086,13 +1083,13 @@ class ScriptResultDiff(object): + for op, i1, i2, j1, j2 in diffs.get_opcodes(): + if op == "replace" or op == "delete": + for k in range(i1, i2): +- table.append_raw(u"-" + a_lines[k]) ++ table.append_raw("-" + a_lines[k]) + if op == "replace" or op == "insert": + for k in range(j1, j2): +- table.append_raw(u"+" + b_lines[k]) ++ table.append_raw("+" + b_lines[k]) + if op == "equal": + for k in range(i1, i2): +- table.append_raw(u" " + a_lines[k]) ++ table.append_raw(" " + a_lines[k]) + + def to_dom_fragment(self, document): + frag = document.createDocumentFragment() +@@ -1102,11 +1099,11 @@ class ScriptResultDiff(object): + frag.appendChild(self.sr_a.to_dom_fragment(document)) + else: + if self.sr_a is not None: +- a_elem = document.createElement(u"a") ++ a_elem = document.createElement("a") + a_elem.appendChild(self.sr_a.to_dom_fragment(document)) + frag.appendChild(a_elem) + if self.sr_b is not None: +- b_elem = document.createElement(u"b") ++ b_elem = document.createElement("b") + b_elem.appendChild(self.sr_b.to_dom_fragment(document)) + frag.appendChild(b_elem) + return frag +@@ -1120,7 +1117,7 @@ class Table(object): + copied to the output.""" + self.widths = [] + self.rows = [] +- self.prefix = u"" ++ self.prefix = "" + self.padding = [] + j = 0 + while j < len(template) and template[j] != "*": +@@ -1145,7 +1142,7 @@ class Table(object): + + for i in range(len(row)): + if row[i] is None: +- s = u"" ++ s = "" + else: + s = str(row[i]) + if i == len(self.widths): +@@ -1167,7 +1164,7 @@ class Table(object): + for row in self.rows: + parts = [self.prefix] + i = 0 +- if isinstance(row, basestring): ++ if isinstance(row, str): + # A raw string. + lines.append(row) + else: +@@ -1176,13 +1173,13 @@ class Table(object): + if i < len(self.padding): + parts.append(self.padding[i]) + i += 1 +- lines.append(u"".join(parts).rstrip()) +- return u"\n".join(lines) ++ lines.append("".join(parts).rstrip()) ++ return "\n".join(lines) + + + def warn(str): + """Print a warning to stderr.""" +- print >> sys.stderr, str ++ print(str, file=sys.stderr) + + + class NmapContentHandler(xml.sax.handler.ContentHandler): +@@ -1200,22 +1197,22 @@ class NmapContentHandler(xml.sax.handler.ContentHandler): + self.current_port = None + + self._start_elem_handlers = { +- u"nmaprun": self._start_nmaprun, +- u"host": self._start_host, +- u"status": self._start_status, +- u"address": self._start_address, +- u"hostname": self._start_hostname, +- u"extraports": self._start_extraports, +- u"port": self._start_port, +- u"state": self._start_state, +- u"service": self._start_service, +- u"script": self._start_script, +- u"osmatch": self._start_osmatch, +- u"finished": self._start_finished, ++ "nmaprun": self._start_nmaprun, ++ "host": self._start_host, ++ "status": self._start_status, ++ "address": self._start_address, ++ "hostname": self._start_hostname, ++ "extraports": self._start_extraports, ++ "port": self._start_port, ++ "state": self._start_state, ++ "service": self._start_service, ++ "script": self._start_script, ++ "osmatch": self._start_osmatch, ++ "finished": self._start_finished, + } + self._end_elem_handlers = { +- u'host': self._end_host, +- u'port': self._end_port, ++ 'host': self._end_host, ++ 'port': self._end_port, + } + + def parent_element(self): +@@ -1245,68 +1242,68 @@ class NmapContentHandler(xml.sax.handler.ContentHandler): + def _start_nmaprun(self, name, attrs): + assert self.parent_element() is None + if "start" in attrs: +- start_timestamp = int(attrs.get(u"start")) ++ start_timestamp = int(attrs.get("start")) + self.scan.start_date = datetime.datetime.fromtimestamp( + start_timestamp) +- self.scan.scanner = attrs.get(u"scanner") +- self.scan.args = attrs.get(u"args") +- self.scan.version = attrs.get(u"version") ++ self.scan.scanner = attrs.get("scanner") ++ self.scan.args = attrs.get("args") ++ self.scan.version = attrs.get("version") + + def _start_host(self, name, attrs): +- assert self.parent_element() == u"nmaprun" ++ assert self.parent_element() == "nmaprun" + self.current_host = Host() + self.scan.hosts.append(self.current_host) + + def _start_status(self, name, attrs): +- assert self.parent_element() == u"host" ++ assert self.parent_element() == "host" + assert self.current_host is not None +- state = attrs.get(u"state") ++ state = attrs.get("state") + if state is None: + warn(u'%s element of host %s is missing the "state" attribute; ' +- 'assuming \unknown\.' % ( ++ r'assuming \unknown\.' % ( + name, self.current_host.format_name())) + return + self.current_host.state = state + + def _start_address(self, name, attrs): +- assert self.parent_element() == u"host" ++ assert self.parent_element() == "host" + assert self.current_host is not None +- addr = attrs.get(u"addr") ++ addr = attrs.get("addr") + if addr is None: +- warn(u'%s element of host %s is missing the "addr" ' ++ warn('%s element of host %s is missing the "addr" ' + 'attribute; skipping.' % ( + name, self.current_host.format_name())) + return +- addrtype = attrs.get(u"addrtype", u"ipv4") ++ addrtype = attrs.get("addrtype", "ipv4") + self.current_host.add_address(Address.new(addrtype, addr)) + + def _start_hostname(self, name, attrs): +- assert self.parent_element() == u"hostnames" ++ assert self.parent_element() == "hostnames" + assert self.current_host is not None +- hostname = attrs.get(u"name") ++ hostname = attrs.get("name") + if hostname is None: +- warn(u'%s element of host %s is missing the "name" ' ++ warn('%s element of host %s is missing the "name" ' + 'attribute; skipping.' % ( + name, self.current_host.format_name())) + return + self.current_host.add_hostname(hostname) + + def _start_extraports(self, name, attrs): +- assert self.parent_element() == u"ports" ++ assert self.parent_element() == "ports" + assert self.current_host is not None +- state = attrs.get(u"state") ++ state = attrs.get("state") + if state is None: +- warn(u'%s element of host %s is missing the "state" ' ++ warn('%s element of host %s is missing the "state" ' + 'attribute; assuming "unknown".' % ( + name, self.current_host.format_name())) + state = None + if state in self.current_host.extraports: +- warn(u'Duplicate extraports state "%s" in host %s.' % ( ++ warn('Duplicate extraports state "%s" in host %s.' % ( + state, self.current_host.format_name())) + +- count = attrs.get(u"count") ++ count = attrs.get("count") + if count is None: +- warn(u'%s element of host %s is missing the "count" ' ++ warn('%s element of host %s is missing the "count" ' + 'attribute; assuming 0.' % ( + name, self.current_host.format_name())) + count = 0 +@@ -1314,99 +1311,99 @@ class NmapContentHandler(xml.sax.handler.ContentHandler): + try: + count = int(count) + except ValueError: +- warn(u"Can't convert extraports count \"%s\" " ++ warn("Can't convert extraports count \"%s\" " + "to an integer in host %s; assuming 0." % ( +- attrs[u"count"], self.current_host.format_name())) ++ attrs["count"], self.current_host.format_name())) + count = 0 + self.current_host.extraports[state] = count + + def _start_port(self, name, attrs): +- assert self.parent_element() == u"ports" ++ assert self.parent_element() == "ports" + assert self.current_host is not None +- portid_str = attrs.get(u"portid") ++ portid_str = attrs.get("portid") + if portid_str is None: +- warn(u'%s element of host %s missing the "portid" ' ++ warn('%s element of host %s missing the "portid" ' + 'attribute; skipping.' % ( + name, self.current_host.format_name())) + return + try: + portid = int(portid_str) + except ValueError: +- warn(u"Can't convert portid \"%s\" to an integer " ++ warn("Can't convert portid \"%s\" to an integer " + "in host %s; skipping port." % ( + portid_str, self.current_host.format_name())) + return +- protocol = attrs.get(u"protocol") ++ protocol = attrs.get("protocol") + if protocol is None: +- warn(u'%s element of host %s missing the "protocol" ' ++ warn('%s element of host %s missing the "protocol" ' + 'attribute; skipping.' % ( + name, self.current_host.format_name())) + return + self.current_port = Port((portid, protocol)) + + def _start_state(self, name, attrs): +- assert self.parent_element() == u"port" ++ assert self.parent_element() == "port" + assert self.current_host is not None + if self.current_port is None: + return + if "state" not in attrs: +- warn(u'%s element of port %s is missing the "state" ' ++ warn('%s element of port %s is missing the "state" ' + 'attribute; assuming "unknown".' % ( + name, self.current_port.spec_string())) + return +- self.current_port.state = attrs[u"state"] ++ self.current_port.state = attrs["state"] + self.current_host.add_port(self.current_port) + + def _start_service(self, name, attrs): +- assert self.parent_element() == u"port" ++ assert self.parent_element() == "port" + assert self.current_host is not None + if self.current_port is None: + return +- self.current_port.service.name = attrs.get(u"name") +- self.current_port.service.product = attrs.get(u"product") +- self.current_port.service.version = attrs.get(u"version") +- self.current_port.service.extrainfo = attrs.get(u"extrainfo") +- self.current_port.service.tunnel = attrs.get(u"tunnel") ++ self.current_port.service.name = attrs.get("name") ++ self.current_port.service.product = attrs.get("product") ++ self.current_port.service.version = attrs.get("version") ++ self.current_port.service.extrainfo = attrs.get("extrainfo") ++ self.current_port.service.tunnel = attrs.get("tunnel") + + def _start_script(self, name, attrs): + result = ScriptResult() +- result.id = attrs.get(u"id") ++ result.id = attrs.get("id") + if result.id is None: +- warn(u'%s element missing the "id" attribute; skipping.' % name) ++ warn('%s element missing the "id" attribute; skipping.' % name) + return + +- result.output = attrs.get(u"output") ++ result.output = attrs.get("output") + if result.output is None: +- warn(u'%s element missing the "output" attribute; skipping.' ++ warn('%s element missing the "output" attribute; skipping.' + % name) + return +- if self.parent_element() == u"prescript": ++ if self.parent_element() == "prescript": + self.scan.pre_script_results.append(result) +- elif self.parent_element() == u"postscript": ++ elif self.parent_element() == "postscript": + self.scan.post_script_results.append(result) +- elif self.parent_element() == u"hostscript": ++ elif self.parent_element() == "hostscript": + self.current_host.script_results.append(result) +- elif self.parent_element() == u"port": ++ elif self.parent_element() == "port": + self.current_port.script_results.append(result) + else: +- warn(u"%s element not inside prescript, postscript, hostscript, " ++ warn("%s element not inside prescript, postscript, hostscript, " + "or port element; ignoring." % name) + return + + def _start_osmatch(self, name, attrs): +- assert self.parent_element() == u"os" ++ assert self.parent_element() == "os" + assert self.current_host is not None + if "name" not in attrs: +- warn(u'%s element of host %s is missing the "name" ' ++ warn('%s element of host %s is missing the "name" ' + 'attribute; skipping.' % ( + name, self.current_host.format_name())) + return +- self.current_host.os.append(attrs[u"name"]) ++ self.current_host.os.append(attrs["name"]) + + def _start_finished(self, name, attrs): +- assert self.parent_element() == u"runstats" ++ assert self.parent_element() == "runstats" + if "time" in attrs: +- end_timestamp = int(attrs.get(u"time")) ++ end_timestamp = int(attrs.get("time")) + self.scan.end_date = datetime.datetime.fromtimestamp(end_timestamp) + + def _end_host(self, name): +@@ -1425,23 +1422,23 @@ class XMLWriter (xml.sax.saxutils.XMLGenerator): + + def frag(self, frag): + for node in frag.childNodes: +- node.writexml(self.f, newl=u"\n") ++ node.writexml(self.f, newl="\n") + + def frag_a(self, frag): +- self.startElement(u"a", {}) ++ self.startElement("a", {}) + for node in frag.childNodes: +- node.writexml(self.f, newl=u"\n") +- self.endElement(u"a") ++ node.writexml(self.f, newl="\n") ++ self.endElement("a") + + def frag_b(self, frag): +- self.startElement(u"b", {}) ++ self.startElement("b", {}) + for node in frag.childNodes: +- node.writexml(self.f, newl=u"\n") +- self.endElement(u"b") ++ node.writexml(self.f, newl="\n") ++ self.endElement("b") + + + def usage(): +- print u"""\ ++ print("""\ + Usage: %s [option] FILE1 FILE2 + Compare two Nmap XML files and display a list of their differences. + Differences include host state changes, port state changes, and changes to +@@ -1451,7 +1448,7 @@ service and OS detection. + -v, --verbose also show hosts and ports that haven't changed. + --text display output in text format (default) + --xml display output in XML format\ +-""" % sys.argv[0] ++""" % sys.argv[0]) + + EXIT_EQUAL = 0 + EXIT_DIFFERENT = 1 +@@ -1459,8 +1456,8 @@ EXIT_ERROR = 2 + + + def usage_error(msg): +- print >> sys.stderr, u"%s: %s" % (sys.argv[0], msg) +- print >> sys.stderr, u"Try '%s -h' for help." % sys.argv[0] ++ print("%s: %s" % (sys.argv[0], msg), file=sys.stderr) ++ print("Try '%s -h' for help." % sys.argv[0], file=sys.stderr) + sys.exit(EXIT_ERROR) + + +@@ -1471,7 +1468,7 @@ def main(): + try: + opts, input_filenames = getopt.gnu_getopt( + sys.argv[1:], "hv", ["help", "text", "verbose", "xml"]) +- except getopt.GetoptError, e: ++ except getopt.GetoptError as e: + usage_error(e.msg) + for o, a in opts: + if o == "-h" or o == "--help": +@@ -1481,15 +1478,15 @@ def main(): + verbose = True + elif o == "--text": + if output_format is not None and output_format != "text": +- usage_error(u"contradictory output format options.") ++ usage_error("contradictory output format options.") + output_format = "text" + elif o == "--xml": + if output_format is not None and output_format != "xml": +- usage_error(u"contradictory output format options.") ++ usage_error("contradictory output format options.") + output_format = "xml" + + if len(input_filenames) != 2: +- usage_error(u"need exactly two input filenames.") ++ usage_error("need exactly two input filenames.") + + if output_format is None: + output_format = "text" +@@ -1502,8 +1499,8 @@ def main(): + scan_a.load_from_file(filename_a) + scan_b = Scan() + scan_b.load_from_file(filename_b) +- except IOError, e: +- print >> sys.stderr, u"Can't open file: %s" % str(e) ++ except IOError as e: ++ print("Can't open file: %s" % str(e), file=sys.stderr) + sys.exit(EXIT_ERROR) + + if output_format == "text": +diff --git a/ndiff/ndifftest.py b/ndiff/ndifftest.py +index 2fa4ae0..27fc525 100755 +--- a/ndiff/ndifftest.py ++++ b/ndiff/ndifftest.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + + # Unit tests for Ndiff. + +@@ -22,7 +22,7 @@ for x in dir(ndiff): + sys.dont_write_bytecode = dont_write_bytecode + del dont_write_bytecode + +-import StringIO ++import io + + + class scan_test(unittest.TestCase): +@@ -52,7 +52,7 @@ class scan_test(unittest.TestCase): + scan.load_from_file("test-scans/single.xml") + host = scan.hosts[0] + self.assertEqual(len(host.ports), 5) +- self.assertEqual(host.extraports.items(), [("filtered", 95)]) ++ self.assertEqual(list(host.extraports.items()), [("filtered", 95)]) + + def test_extraports_multi(self): + """Test that the correct number of known ports is returned when there +@@ -68,9 +68,9 @@ class scan_test(unittest.TestCase): + """Test that nmaprun information is recorded.""" + scan = Scan() + scan.load_from_file("test-scans/empty.xml") +- self.assertEqual(scan.scanner, u"nmap") +- self.assertEqual(scan.version, u"4.90RC2") +- self.assertEqual(scan.args, u"nmap -oX empty.xml -p 1-100") ++ self.assertEqual(scan.scanner, "nmap") ++ self.assertEqual(scan.version, "4.90RC2") ++ self.assertEqual(scan.args, "nmap -oX empty.xml -p 1-100") + + def test_addresses(self): + """Test that addresses are recorded.""" +@@ -84,7 +84,7 @@ class scan_test(unittest.TestCase): + scan = Scan() + scan.load_from_file("test-scans/simple.xml") + host = scan.hosts[0] +- self.assertEqual(host.hostnames, [u"scanme.nmap.org"]) ++ self.assertEqual(host.hostnames, ["scanme.nmap.org"]) + + def test_os(self): + """Test that OS information is recorded.""" +@@ -99,7 +99,7 @@ class scan_test(unittest.TestCase): + scan.load_from_file("test-scans/complex.xml") + host = scan.hosts[0] + self.assertTrue(len(host.script_results) > 0) +- self.assertTrue(len(host.ports[(22, u"tcp")].script_results) > 0) ++ self.assertTrue(len(host.ports[(22, "tcp")].script_results) > 0) + + # This test is commented out because Nmap XML doesn't store any information + # about down hosts, not even the fact that they are down. Recovering the list +@@ -128,16 +128,16 @@ class host_test(unittest.TestCase): + + def test_format_name(self): + h = Host() +- self.assertTrue(isinstance(h.format_name(), basestring)) +- h.add_address(IPv4Address(u"127.0.0.1")) +- self.assertTrue(u"127.0.0.1" in h.format_name()) ++ self.assertTrue(isinstance(h.format_name(), str)) ++ h.add_address(IPv4Address("127.0.0.1")) ++ self.assertTrue("127.0.0.1" in h.format_name()) + h.add_address(IPv6Address("::1")) +- self.assertTrue(u"127.0.0.1" in h.format_name()) +- self.assertTrue(u"::1" in h.format_name()) +- h.add_hostname(u"localhost") +- self.assertTrue(u"127.0.0.1" in h.format_name()) +- self.assertTrue(u"::1" in h.format_name()) +- self.assertTrue(u"localhost" in h.format_name()) ++ self.assertTrue("127.0.0.1" in h.format_name()) ++ self.assertTrue("::1" in h.format_name()) ++ h.add_hostname("localhost") ++ self.assertTrue("127.0.0.1" in h.format_name()) ++ self.assertTrue("::1" in h.format_name()) ++ self.assertTrue("localhost" in h.format_name()) + + def test_empty_get_port(self): + h = Host() +@@ -197,8 +197,8 @@ class host_test(unittest.TestCase): + h = s.hosts[0] + self.assertEqual(len(h.ports), 5) + self.assertEqual(len(h.extraports), 1) +- self.assertEqual(h.extraports.keys()[0], u"filtered") +- self.assertEqual(h.extraports.values()[0], 95) ++ self.assertEqual(list(h.extraports.keys())[0], "filtered") ++ self.assertEqual(list(h.extraports.values())[0], 95) + self.assertEqual(h.state, "up") + + +@@ -241,13 +241,13 @@ class port_test(unittest.TestCase): + """Test the Port class.""" + def test_spec_string(self): + p = Port((10, "tcp")) +- self.assertEqual(p.spec_string(), u"10/tcp") ++ self.assertEqual(p.spec_string(), "10/tcp") + p = Port((100, "ip")) +- self.assertEqual(p.spec_string(), u"100/ip") ++ self.assertEqual(p.spec_string(), "100/ip") + + def test_state_string(self): + p = Port((10, "tcp")) +- self.assertEqual(p.state_string(), u"unknown") ++ self.assertEqual(p.state_string(), "unknown") + + + class service_test(unittest.TestCase): +@@ -255,47 +255,47 @@ class service_test(unittest.TestCase): + def test_compare(self): + """Test that services with the same contents compare equal.""" + a = Service() +- a.name = u"ftp" +- a.product = u"FooBar FTP" +- a.version = u"1.1.1" +- a.tunnel = u"ssl" ++ a.name = "ftp" ++ a.product = "FooBar FTP" ++ a.version = "1.1.1" ++ a.tunnel = "ssl" + self.assertEqual(a, a) + b = Service() +- b.name = u"ftp" +- b.product = u"FooBar FTP" +- b.version = u"1.1.1" +- b.tunnel = u"ssl" ++ b.name = "ftp" ++ b.product = "FooBar FTP" ++ b.version = "1.1.1" ++ b.tunnel = "ssl" + self.assertEqual(a, b) +- b.name = u"http" ++ b.name = "http" + self.assertNotEqual(a, b) + c = Service() + self.assertNotEqual(a, c) + + def test_tunnel(self): + serv = Service() +- serv.name = u"http" +- serv.tunnel = u"ssl" +- self.assertEqual(serv.name_string(), u"ssl/http") ++ serv.name = "http" ++ serv.tunnel = "ssl" ++ self.assertEqual(serv.name_string(), "ssl/http") + + def test_version_string(self): + serv = Service() +- serv.product = u"FooBar" ++ serv.product = "FooBar" + self.assertTrue(len(serv.version_string()) > 0) + serv = Service() +- serv.version = u"1.2.3" ++ serv.version = "1.2.3" + self.assertTrue(len(serv.version_string()) > 0) + serv = Service() +- serv.extrainfo = u"misconfigured" ++ serv.extrainfo = "misconfigured" + self.assertTrue(len(serv.version_string()) > 0) + serv = Service() +- serv.product = u"FooBar" +- serv.version = u"1.2.3" ++ serv.product = "FooBar" ++ serv.version = "1.2.3" + # Must match Nmap output. + self.assertEqual(serv.version_string(), +- u"%s %s" % (serv.product, serv.version)) +- serv.extrainfo = u"misconfigured" ++ "%s %s" % (serv.product, serv.version)) ++ serv.extrainfo = "misconfigured" + self.assertEqual(serv.version_string(), +- u"%s %s (%s)" % (serv.product, serv.version, serv.extrainfo)) ++ "%s %s (%s)" % (serv.product, serv.version, serv.extrainfo)) + + + class ScanDiffSub(ScanDiff): +@@ -703,7 +703,7 @@ class scan_diff_xml_test(unittest.TestCase): + a.load_from_file("test-scans/empty.xml") + b = Scan() + b.load_from_file("test-scans/simple.xml") +- f = StringIO.StringIO() ++ f = io.StringIO() + self.scan_diff = ScanDiffXML(a, b, f) + self.scan_diff.output() + self.xml = f.getvalue() +@@ -712,8 +712,8 @@ class scan_diff_xml_test(unittest.TestCase): + def test_well_formed(self): + try: + document = xml.dom.minidom.parseString(self.xml) +- except Exception, e: +- self.fail(u"Parsing XML diff output caused the exception: %s" ++ except Exception as e: ++ self.fail("Parsing XML diff output caused the exception: %s" + % str(e)) + + +@@ -739,8 +739,8 @@ def host_apply_diff(host, diff): + host.os = diff.host_b.os[:] + + if diff.extraports_changed: +- for state in host.extraports.keys(): +- for port in host.ports.values(): ++ for state in list(host.extraports.keys()): ++ for port in list(host.ports.values()): + if port.state == state: + del host.ports[port.spec] + host.extraports = diff.host_b.extraports.copy() +diff --git a/ndiff/scripts/ndiff b/ndiff/scripts/ndiff +index 8517c07..4671e73 100755 +--- a/ndiff/scripts/ndiff ++++ b/ndiff/scripts/ndiff +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + + # Ndiff + # +@@ -67,15 +67,15 @@ if INSTALL_LIB is not None and is_secure_dir(INSTALL_LIB): + + try: + import ndiff +-except ImportError, e: +- print >> sys.stderr, """\ ++except ImportError as e: ++ print("""\ + Could not import the ndiff module: %s. +-I checked in these directories:""" % repr(e.message) ++I checked in these directories:""" % repr(e), file=sys.stderr) + for dir in sys.path: +- print >> sys.stderr, " %s" % dir +- print >> sys.stderr, """\ ++ print(" %s" % dir, file=sys.stderr) ++ print("""\ + If you installed Ndiff in another directory, you may have to add the +-modules directory to the PYTHONPATH environment variable.""" ++modules directory to the PYTHONPATH environment variable.""", file=sys.stderr) + sys.exit(1) + + import ndiff +diff --git a/ndiff/setup.py b/ndiff/setup.py +old mode 100644 +new mode 100755 +index b5e254c..c49bcf3 +--- a/ndiff/setup.py ++++ b/ndiff/setup.py +@@ -94,7 +94,7 @@ class checked_install(distutils.command.install.install): + self.saved_prefix = sys.prefix + try: + distutils.command.install.install.finalize_options(self) +- except distutils.errors.DistutilsPlatformError, e: ++ except distutils.errors.DistutilsPlatformError as e: + raise distutils.errors.DistutilsPlatformError(str(e) + """ + Installing your distribution's python-dev package may solve this problem.""") + +@@ -155,13 +155,13 @@ Installing your distribution's python-dev package may solve this problem.""") + #!/usr/bin/env python + import errno, os, os.path, sys + +-print 'Uninstall %(name)s' ++print('Uninstall %(name)s') + + answer = raw_input('Are you sure that you want to uninstall ' + '%(name)s (yes/no) ') + + if answer != 'yes' and answer != 'y': +- print 'Not uninstalling.' ++ print('Not uninstalling.') + sys.exit(0) + + """ % {'name': APP_NAME} +@@ -177,8 +177,8 @@ if answer != 'yes' and answer != 'y': + # This should never happen (everything gets installed + # inside the root), but if it does, be safe and don't + # delete anything. +- uninstaller += ("print '%s was not installed inside " +- "the root %s; skipping.'\n" % (output, self.root)) ++ uninstaller += ("print('%s was not installed inside " ++ "the root %s; skipping.')\n" % (output, self.root)) + continue + output = path_strip_prefix(output, self.root) + assert os.path.isabs(output) +@@ -202,24 +202,24 @@ for path in INSTALLED_FILES: + dirs.append(path) + # Delete the files. + for file in files: +- print "Removing '%s'." % file ++ print("Removing '%s'." % file) + try: + os.remove(file) +- except OSError, e: +- print >> sys.stderr, ' Error: %s.' % str(e) ++ except OSError as e: ++ print(' Error: %s.' % str(e), file=sys.stderr) + # Delete the directories. First reverse-sort the normalized paths by + # length so that child directories are deleted before their parents. + dirs = [os.path.normpath(dir) for dir in dirs] + dirs.sort(key = len, reverse = True) + for dir in dirs: + try: +- print "Removing the directory '%s'." % dir ++ print("Removing the directory '%s'." % dir) + os.rmdir(dir) +- except OSError, e: ++ except OSError as e: + if e.errno == errno.ENOTEMPTY: +- print "Directory '%s' not empty; not removing." % dir ++ print("Directory '%s' not empty; not removing." % dir) + else: +- print >> sys.stderr, str(e) ++ print(str(e), file=sys.stderr) + """ + + uninstaller_file = open(uninstaller_filename, 'w') +@@ -227,7 +227,7 @@ for dir in dirs: + uninstaller_file.close() + + # Set exec bit for uninstaller +- mode = ((os.stat(uninstaller_filename)[ST_MODE]) | 0555) & 07777 ++ mode = ((os.stat(uninstaller_filename)[ST_MODE]) | 0o555) & 0o7777 + os.chmod(uninstaller_filename, mode) + + def write_installed_files(self): +@@ -242,7 +242,7 @@ for dir in dirs: + try: + for output in self.get_installed_files(): + assert "\n" not in output +- print >> f, output ++ print(output, file=f) + finally: + f.close() + +@@ -266,7 +266,7 @@ class my_uninstall(distutils.cmd.Command): + # Read the list of installed files. + try: + f = open(INSTALLED_FILES_NAME, "r") +- except IOError, e: ++ except IOError as e: + if e.errno == errno.ENOENT: + log.error("Couldn't open the installation record '%s'. " + "Have you installed yet?" % INSTALLED_FILES_NAME) +@@ -289,7 +289,7 @@ class my_uninstall(distutils.cmd.Command): + try: + if not self.dry_run: + os.remove(file) +- except OSError, e: ++ except OSError as e: + log.error(str(e)) + # Delete the directories. First reverse-sort the normalized paths by + # length so that child directories are deleted before their parents. +@@ -300,7 +300,7 @@ class my_uninstall(distutils.cmd.Command): + log.info("Removing the directory '%s'." % dir) + if not self.dry_run: + os.rmdir(dir) +- except OSError, e: ++ except OSError as e: + if e.errno == errno.ENOTEMPTY: + log.info("Directory '%s' not empty; not removing." % dir) + else: +diff --git a/ndiff/test-scans/anonymize.py b/ndiff/test-scans/anonymize.py +index 9ba612a..fd251fe 100755 +--- a/ndiff/test-scans/anonymize.py ++++ b/ndiff/test-scans/anonymize.py +@@ -1,4 +1,4 @@ +-#!/usr/bin/env python ++#!/usr/bin/env python3 + + # Anonymize an Nmap XML file, replacing host name and IP addresses with random + # anonymous ones. Anonymized names will be consistent between runs of the +@@ -20,20 +20,20 @@ r = random.Random() + + + def hash(s): +- digest = hashlib.sha512(s).hexdigest() ++ digest = hashlib.sha512(s.encode()).hexdigest() + return int(digest, 16) + + + def anonymize_mac_address(addr): + r.seed(hash(addr)) + nums = (0, 0, 0) + tuple(r.randrange(256) for i in range(3)) +- return u":".join(u"%02X" % x for x in nums) ++ return ":".join("%02X" % x for x in nums) + + + def anonymize_ipv4_address(addr): + r.seed(hash(addr)) + nums = (10,) + tuple(r.randrange(256) for i in range(3)) +- return u".".join(unicode(x) for x in nums) ++ return ".".join(str(x) for x in nums) + + + def anonymize_ipv6_address(addr): +@@ -41,7 +41,7 @@ def anonymize_ipv6_address(addr): + # RFC 4193. + nums = (0xFD00 + r.randrange(256),) + nums = nums + tuple(r.randrange(65536) for i in range(7)) +- return u":".join("%04X" % x for x in nums) ++ return ":".join("%04X" % x for x in nums) + + # Maps to memoize address and host name conversions. + hostname_map = {} +@@ -54,11 +54,11 @@ def anonymize_hostname(name): + LETTERS = "acbdefghijklmnopqrstuvwxyz" + r.seed(hash(name)) + length = r.randrange(5, 10) +- prefix = u"".join(r.sample(LETTERS, length)) ++ prefix = "".join(r.sample(LETTERS, length)) + num = r.randrange(1000) +- hostname_map[name] = u"%s-%d.example.com" % (prefix, num) ++ hostname_map[name] = "%s-%d.example.com" % (prefix, num) + if VERBOSE: +- print >> sys.stderr, "Replace %s with %s" % (name, hostname_map[name]) ++ print("Replace %s with %s" % (name, hostname_map[name]), file=sys.stderr) + return hostname_map[name] + + mac_re = re.compile(r'\b([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\b') +@@ -78,7 +78,7 @@ def anonymize_address(addr): + else: + assert False + if VERBOSE: +- print >> sys.stderr, "Replace %s with %s" % (addr, address_map[addr]) ++ print("Replace %s with %s" % (addr, address_map[addr]), file=sys.stderr) + return address_map[addr] + + +-- +2.24.1 + diff --git a/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-configure.ac-make-ndiff-depend-on-python3.patch b/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-configure.ac-make-ndiff-depend-on-python3.patch new file mode 100644 index 0000000000..c43ff9f4d8 --- /dev/null +++ b/meta-openembedded/meta-oe/recipes-security/nmap/files/0001-configure.ac-make-ndiff-depend-on-python3.patch @@ -0,0 +1,48 @@ +From 562893e665a6c9e1b60c8b3242bab6fe78318b3b Mon Sep 17 00:00:00 2001 +From: Mingli Yu <mingli.yu@windriver.com> +Date: Fri, 14 Feb 2020 08:19:54 +0000 +Subject: [PATCH] configure.ac: make ndiff depend on python3 + +Python 2 ceased being maintained on the 1st January 2020. +We've already removed all users of it from oe-core, so +let ndiff depend on python3. + +Upstream-Status: Pending + +Signed-off-by: Mingli Yu <mingli.yu@windriver.com> +--- + .../nmap/7.80-r0/nmap-7.80/configure.ac | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 9d2fff8..5ffdd55 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -237,16 +237,21 @@ if test $HAVE_PYTHON && test "x${PYTHON_VERSION%%.*}" = "x2"; then + HAVE_PYTHON2=true + fi + ++HAVE_PYTHON3=false ++if test $HAVE_PYTHON && test "x${PYTHON_VERSION%%.*}" = "x3"; then ++ HAVE_PYTHON3=true ++fi ++ + NDIFFDIR=ndiff + + # Do they want Ndiff? + AC_ARG_WITH(ndiff, AC_HELP_STRING([--without-ndiff], [Skip installation of the Ndiff utility]), [], [with_ndiff=check]) +-if $HAVE_PYTHON2 ; then : ; ++if $HAVE_PYTHON3 ; then : ; + else + if test "$with_ndiff" = "check" ; then +- AC_MSG_WARN([Not building Ndiff because Python 2.x with x>=4 was not found]) ++ AC_MSG_WARN([Not building Ndiff because Python3 was not found]) + elif test "$with_ndiff" = "yes"; then +- AC_MSG_FAILURE([--with-ndiff requires Python 2.x with x>=4]) ++ AC_MSG_FAILURE([--with-ndiff requires Python3]) + fi + with_ndiff=no + fi +-- +2.24.1 + diff --git a/meta-openembedded/meta-oe/recipes-security/nmap/nmap_7.80.bb b/meta-openembedded/meta-oe/recipes-security/nmap/nmap_7.80.bb index f24194da76..c76d2324e7 100644 --- a/meta-openembedded/meta-oe/recipes-security/nmap/nmap_7.80.bb +++ b/meta-openembedded/meta-oe/recipes-security/nmap/nmap_7.80.bb @@ -10,12 +10,14 @@ SRC_URI = "http://nmap.org/dist/${BP}.tar.bz2 \ file://nmap-replace-shtool-mkdir-with-coreutils-mkdir-command.patch \ file://0001-Include-time.h-header-to-pass-clang-compilation.patch \ file://0002-Fix-building-with-libc.patch \ + file://0001-Make-ndiff-support-python3.patch \ + file://0001-configure.ac-make-ndiff-depend-on-python3.patch \ " SRC_URI[md5sum] = "d37b75b06d1d40f27b76d60db420a1f5" SRC_URI[sha256sum] = "fcfa5a0e42099e12e4bf7a68ebe6fde05553383a682e816a7ec9256ab4773faa" -inherit autotools-brokensep pkgconfig pythonnative +inherit autotools-brokensep pkgconfig python3native PACKAGECONFIG ?= "ncat nping ndiff pcap" @@ -28,7 +30,7 @@ PACKAGECONFIG[libz] = "--with-libz=${STAGING_LIBDIR}/.., --without-libz, zlib, z #disable/enable packages PACKAGECONFIG[nping] = ",--without-nping," PACKAGECONFIG[ncat] = ",--without-ncat," -PACKAGECONFIG[ndiff] = ",--without-ndiff,python" +PACKAGECONFIG[ndiff] = "--with-ndiff=yes,--without-ndiff,python3" PACKAGECONFIG[update] = ",--without-nmap-update," EXTRA_OECONF = "--with-libdnet=included --with-liblinear=included --without-subversion --with-liblua=included" @@ -47,6 +49,12 @@ do_configure() { oe_runconf } +do_install_append() { + if [ -f "${D}${bindir}/ndiff" ]; then + sed -i 's@^#!.*$@#!/usr/bin/env python3@g' ${D}${bindir}/ndiff + fi +} + FILES_${PN} += "${PYTHON_SITEPACKAGES_DIR} ${datadir}/ncat" -RDEPENDS_${PN} = "python" +RDEPENDS_${PN} += "python3-core" |