blob: 4151cec69d918b352fc5d7fd99fcfa3a12463e93 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Bryan Quigley <bryan.quigley@canonical.com>
2Date: Sat, 2 Nov 2019 21:06:44 -0700
3Subject: Python3 port of ndiff
4
5Ported all python scrips in ndiff/ except setup.py
6
7Some hints on cmp taken from #1484
8
9Minor tweaks to Makefile to support python3, but unsure if
10there is a better way to do that.
11
12Seperated .travis.yml commands for easier debugging where it breaks.
13
14This closes the easy half of #1176
15
16Resolves: #1484
17---
18 .travis.yml | 8 +-
19 Makefile.in | 6 +-
20 ndiff/ndiff.py | 495 +++++++++++++++++++++---------------------
21 ndiff/ndifftest.py | 94 ++++----
22 ndiff/scripts/ndiff | 14 +-
23 ndiff/setup.py | 34 +--
24 ndiff/test-scans/anonymize.py | 18 +-
25 7 files changed, 337 insertions(+), 332 deletions(-)
26 mode change 100644 => 100755 ndiff/setup.py
27
28--- a/.travis.yml
29+++ b/.travis.yml
30@@ -4,7 +4,13 @@ compiler:
31 - clang
32 # Change this to your needs
33 sudo: false
34-script: mkdir /tmp/n && ./configure $SSL_FLAG $LUA_FLAG --prefix=/tmp/n && make && make check && make install && /tmp/n/bin/nmap -A localhost
35+script:
36+ - "mkdir /tmp/n"
37+ - "./configure $SSL_FLAG $LUA_FLAG --prefix=/tmp/n"
38+ - "make"
39+ - "make check"
40+ - "make install"
41+ - "/tmp/n/bin/nmap -A localhost"
42
43 env:
44 - SSL_FLAG="--without-openssl" LUA_FLAG="--without-liblua"
45--- a/Makefile.in
46+++ b/Makefile.in
47@@ -35,6 +35,7 @@ ZENMAPDIR = @ZENMAPDIR@
48 NDIFFDIR = @NDIFFDIR@
49 NPINGDIR = @NPINGDIR@
50 PYTHON = @PYTHON@
51+PYTHON3 = /usr/bin/env python3
52 DEFS = @DEFS@ -DNMAP_PLATFORM=\"$(NMAP_PLATFORM)\" -DNMAPDATADIR=\"$(nmapdatadir)\"
53 # With GCC, add extra security checks to source code.
54 # http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
55@@ -368,6 +369,7 @@ tests/check_dns: $(OBJS)
56 # this as the location of the interpreter whenever we're not doing a
57 # local installation.
58 DEFAULT_PYTHON_PATH = /usr/bin/env python
59+DEFAULT_PYTHON3_PATH = /usr/bin/env python3
60
61 build-zenmap: $(ZENMAPDIR)/setup.py $(ZENMAPDIR)/zenmapCore/Version.py
62 # When DESTDIR is defined, assume we're building an executable
63@@ -388,7 +390,7 @@ install-zenmap: $(ZENMAPDIR)/setup.py
64 ln -sf zenmap $(DESTDIR)$(bindir)/xnmap
65
66 build-ndiff:
67- cd $(NDIFFDIR) && $(PYTHON) setup.py build $(if $(DESTDIR),--executable "$(DEFAULT_PYTHON_PATH)")
68+ cd $(NDIFFDIR) && $(PYTHON) setup.py build $(if $(DESTDIR),--executable "$(DEFAULT_PYTHON3_PATH)")
69
70 build-nping: $(NPINGDIR)/Makefile build-nbase build-nsock build-netutil $(NPINGDIR)/nping.h @DNET_BUILD@ @PCAP_BUILD@
71 @cd $(NPINGDIR) && $(MAKE)
72@@ -458,7 +460,7 @@ check-ncat:
73 @cd $(NCATDIR) && $(MAKE) check
74
75 check-ndiff:
76- @cd $(NDIFFDIR) && $(PYTHON) ndifftest.py
77+ @cd $(NDIFFDIR) && $(PYTHON3) ndifftest.py
78
79 check-nsock:
80 @cd $(NSOCKDIR)/src && $(MAKE) check
81--- a/ndiff/ndiff.py
82+++ b/ndiff/ndiff.py
83@@ -1,4 +1,4 @@
84-#!/usr/bin/env python
85+#!/usr/bin/env python3
86
87 # Ndiff
88 #
89@@ -26,11 +26,11 @@ xml.__path__ = [x for x in xml.__path__
90 import xml.sax
91 import xml.sax.saxutils
92 import xml.dom.minidom
93-from StringIO import StringIO
94+from io import StringIO
95
96 verbose = False
97
98-NDIFF_XML_VERSION = u"1"
99+NDIFF_XML_VERSION = "1"
100
101
102 class OverrideEntityResolver(xml.sax.handler.EntityResolver):
103@@ -78,35 +78,35 @@ class Scan(object):
104 def write_nmaprun_open(self, writer):
105 attrs = {}
106 if self.scanner is not None:
107- attrs[u"scanner"] = self.scanner
108+ attrs["scanner"] = self.scanner
109 if self.args is not None:
110- attrs[u"args"] = self.args
111+ attrs["args"] = self.args
112 if self.start_date is not None:
113- attrs[u"start"] = "%d" % time.mktime(self.start_date.timetuple())
114- attrs[u"startstr"] = self.start_date.strftime(
115+ attrs["start"] = "%d" % time.mktime(self.start_date.timetuple())
116+ attrs["startstr"] = self.start_date.strftime(
117 "%a %b %d %H:%M:%S %Y")
118 if self.version is not None:
119- attrs[u"version"] = self.version
120- writer.startElement(u"nmaprun", attrs)
121+ attrs["version"] = self.version
122+ writer.startElement("nmaprun", attrs)
123
124 def write_nmaprun_close(self, writer):
125- writer.endElement(u"nmaprun")
126+ writer.endElement("nmaprun")
127
128 def nmaprun_to_dom_fragment(self, document):
129 frag = document.createDocumentFragment()
130- elem = document.createElement(u"nmaprun")
131+ elem = document.createElement("nmaprun")
132 if self.scanner is not None:
133- elem.setAttribute(u"scanner", self.scanner)
134+ elem.setAttribute("scanner", self.scanner)
135 if self.args is not None:
136- elem.setAttribute(u"args", self.args)
137+ elem.setAttribute("args", self.args)
138 if self.start_date is not None:
139 elem.setAttribute(
140- u"start", "%d" % time.mktime(self.start_date.timetuple()))
141+ "start", "%d" % time.mktime(self.start_date.timetuple()))
142 elem.setAttribute(
143- u"startstr",
144+ "startstr",
145 self.start_date.strftime("%a %b %d %H:%M:%S %Y"))
146 if self.version is not None:
147- elem.setAttribute(u"version", self.version)
148+ elem.setAttribute("version", self.version)
149 frag.appendChild(elem)
150 return frag
151
152@@ -136,17 +136,17 @@ class Host(object):
153
154 def format_name(self):
155 """Return a human-readable identifier for this host."""
156- address_s = u", ".join(a.s for a in sorted(self.addresses))
157- hostname_s = u", ".join(sorted(self.hostnames))
158+ address_s = ", ".join(a.s for a in sorted(self.addresses))
159+ hostname_s = ", ".join(sorted(self.hostnames))
160 if len(hostname_s) > 0:
161 if len(address_s) > 0:
162- return u"%s (%s)" % (hostname_s, address_s)
163+ return "%s (%s)" % (hostname_s, address_s)
164 else:
165 return hostname_s
166 elif len(address_s) > 0:
167 return address_s
168 else:
169- return u"<no name>"
170+ return "<no name>"
171
172 def add_port(self, port):
173 self.ports[port.spec] = port
174@@ -163,46 +163,46 @@ class Host(object):
175 return state is None or state in self.extraports
176
177 def extraports_string(self):
178- list = [(count, state) for (state, count) in self.extraports.items()]
179+ locallist = [(count, state) for (state, count) in list(self.extraports.items())]
180 # Reverse-sort by count.
181- list.sort(reverse=True)
182- return u", ".join(
183- [u"%d %s ports" % (count, state) for (count, state) in list])
184+ locallist.sort(reverse=True)
185+ return ", ".join(
186+ ["%d %s ports" % (count, state) for (count, state) in locallist])
187
188 def state_to_dom_fragment(self, document):
189 frag = document.createDocumentFragment()
190 if self.state is not None:
191- elem = document.createElement(u"status")
192- elem.setAttribute(u"state", self.state)
193+ elem = document.createElement("status")
194+ elem.setAttribute("state", self.state)
195 frag.appendChild(elem)
196 return frag
197
198 def hostname_to_dom_fragment(self, document, hostname):
199 frag = document.createDocumentFragment()
200- elem = document.createElement(u"hostname")
201- elem.setAttribute(u"name", hostname)
202+ elem = document.createElement("hostname")
203+ elem.setAttribute("name", hostname)
204 frag.appendChild(elem)
205 return frag
206
207 def extraports_to_dom_fragment(self, document):
208 frag = document.createDocumentFragment()
209- for state, count in self.extraports.items():
210- elem = document.createElement(u"extraports")
211- elem.setAttribute(u"state", state)
212- elem.setAttribute(u"count", unicode(count))
213+ for state, count in list(self.extraports.items()):
214+ elem = document.createElement("extraports")
215+ elem.setAttribute("state", state)
216+ elem.setAttribute("count", str(count))
217 frag.appendChild(elem)
218 return frag
219
220 def os_to_dom_fragment(self, document, os):
221 frag = document.createDocumentFragment()
222- elem = document.createElement(u"osmatch")
223- elem.setAttribute(u"name", os)
224+ elem = document.createElement("osmatch")
225+ elem.setAttribute("name", os)
226 frag.appendChild(elem)
227 return frag
228
229 def to_dom_fragment(self, document):
230 frag = document.createDocumentFragment()
231- elem = document.createElement(u"host")
232+ elem = document.createElement("host")
233
234 if self.state is not None:
235 elem.appendChild(self.state_to_dom_fragment(document))
236@@ -211,13 +211,13 @@ class Host(object):
237 elem.appendChild(addr.to_dom_fragment(document))
238
239 if len(self.hostnames) > 0:
240- hostnames_elem = document.createElement(u"hostnames")
241+ hostnames_elem = document.createElement("hostnames")
242 for hostname in self.hostnames:
243 hostnames_elem.appendChild(
244 self.hostname_to_dom_fragment(document, hostname))
245 elem.appendChild(hostnames_elem)
246
247- ports_elem = document.createElement(u"ports")
248+ ports_elem = document.createElement("ports")
249 ports_elem.appendChild(self.extraports_to_dom_fragment(document))
250 for port in sorted(self.ports.values()):
251 if not self.is_extraports(port.state):
252@@ -226,13 +226,13 @@ class Host(object):
253 elem.appendChild(ports_elem)
254
255 if len(self.os) > 0:
256- os_elem = document.createElement(u"os")
257+ os_elem = document.createElement("os")
258 for os in self.os:
259 os_elem.appendChild(self.os_to_dom_fragment(document, os))
260 elem.appendChild(os_elem)
261
262 if len(self.script_results) > 0:
263- hostscript_elem = document.createElement(u"hostscript")
264+ hostscript_elem = document.createElement("hostscript")
265 for sr in self.script_results:
266 hostscript_elem.appendChild(sr.to_dom_fragment(document))
267 elem.appendChild(hostscript_elem)
268@@ -246,7 +246,7 @@ class Address(object):
269 self.s = s
270
271 def __eq__(self, other):
272- return self.__cmp__(other) == 0
273+ return self.sort_key() == other.sort_key()
274
275 def __ne__(self, other):
276 return not self.__eq__(other)
277@@ -254,8 +254,8 @@ class Address(object):
278 def __hash__(self):
279 return hash(self.sort_key())
280
281- def __cmp__(self, other):
282- return cmp(self.sort_key(), other.sort_key())
283+ def __lt__(self, other):
284+ return self.sort_key() < other.sort_key()
285
286 def __str__(self):
287 return str(self.s)
288@@ -264,21 +264,21 @@ class Address(object):
289 return self.s
290
291 def new(type, s):
292- if type == u"ipv4":
293+ if type == "ipv4":
294 return IPv4Address(s)
295- elif type == u"ipv6":
296+ elif type == "ipv6":
297 return IPv6Address(s)
298- elif type == u"mac":
299+ elif type == "mac":
300 return MACAddress(s)
301 else:
302- raise ValueError(u"Unknown address type %s." % type)
303+ raise ValueError("Unknown address type %s." % type)
304 new = staticmethod(new)
305
306 def to_dom_fragment(self, document):
307 frag = document.createDocumentFragment()
308- elem = document.createElement(u"address")
309- elem.setAttribute(u"addr", self.s)
310- elem.setAttribute(u"addrtype", self.type)
311+ elem = document.createElement("address")
312+ elem.setAttribute("addr", self.s)
313+ elem.setAttribute("addrtype", self.type)
314 frag.appendChild(elem)
315 return frag
316
317@@ -287,21 +287,21 @@ class Address(object):
318
319
320 class IPv4Address(Address):
321- type = property(lambda self: u"ipv4")
322+ type = property(lambda self: "ipv4")
323
324 def sort_key(self):
325 return (0, self.s)
326
327
328 class IPv6Address(Address):
329- type = property(lambda self: u"ipv6")
330+ type = property(lambda self: "ipv6")
331
332 def sort_key(self):
333 return (1, self.s)
334
335
336 class MACAddress(Address):
337- type = property(lambda self: u"mac")
338+ type = property(lambda self: "mac")
339
340 def sort_key(self):
341 return (2, self.s)
342@@ -320,28 +320,25 @@ class Port(object):
343
344 def state_string(self):
345 if self.state is None:
346- return u"unknown"
347+ return "unknown"
348 else:
349- return unicode(self.state)
350+ return str(self.state)
351
352 def spec_string(self):
353- return u"%d/%s" % self.spec
354+ return "%d/%s" % self.spec
355
356- def __cmp__(self, other):
357- d = cmp(self.spec, other.spec)
358- if d != 0:
359- return d
360- return cmp((self.spec, self.service, self.script_results),
361- (other.spec, other.service, other.script_results))
362+ def __lt__(self, other):
363+ return (self.spec, self.service, self.script_results) < (
364+ other.spec, other.service, other.script_results)
365
366 def to_dom_fragment(self, document):
367 frag = document.createDocumentFragment()
368- elem = document.createElement(u"port")
369- elem.setAttribute(u"portid", unicode(self.spec[0]))
370- elem.setAttribute(u"protocol", self.spec[1])
371+ elem = document.createElement("port")
372+ elem.setAttribute("portid", str(self.spec[0]))
373+ elem.setAttribute("protocol", self.spec[1])
374 if self.state is not None:
375- state_elem = document.createElement(u"state")
376- state_elem.setAttribute(u"state", self.state)
377+ state_elem = document.createElement("state")
378+ state_elem.setAttribute("state", self.state)
379 elem.appendChild(state_elem)
380 elem.appendChild(self.service.to_dom_fragment(document))
381 for sr in self.script_results:
382@@ -385,7 +382,7 @@ class Service(object):
383 if len(parts) == 0:
384 return None
385 else:
386- return u"/".join(parts)
387+ return "/".join(parts)
388
389 def version_string(self):
390 """Get a string like in the VERSION column of Nmap output."""
391@@ -395,17 +392,17 @@ class Service(object):
392 if self.version is not None:
393 parts.append(self.version)
394 if self.extrainfo is not None:
395- parts.append(u"(%s)" % self.extrainfo)
396+ parts.append("(%s)" % self.extrainfo)
397
398 if len(parts) == 0:
399 return None
400 else:
401- return u" ".join(parts)
402+ return " ".join(parts)
403
404 def to_dom_fragment(self, document):
405 frag = document.createDocumentFragment()
406- elem = document.createElement(u"service")
407- for attr in (u"name", u"product", u"version", u"extrainfo", u"tunnel"):
408+ elem = document.createElement("service")
409+ for attr in ("name", "product", "version", "extrainfo", "tunnel"):
410 v = getattr(self, attr)
411 if v is None:
412 continue
413@@ -435,53 +432,53 @@ class ScriptResult(object):
414 result = []
415 lines = self.output.splitlines()
416 if len(lines) > 0:
417- lines[0] = self.id + u": " + lines[0]
418+ lines[0] = self.id + ": " + lines[0]
419 for line in lines[:-1]:
420- result.append(u"| " + line)
421+ result.append("| " + line)
422 if len(lines) > 0:
423- result.append(u"|_ " + lines[-1])
424+ result.append("|_ " + lines[-1])
425 return result
426
427 def to_dom_fragment(self, document):
428 frag = document.createDocumentFragment()
429- elem = document.createElement(u"script")
430- elem.setAttribute(u"id", self.id)
431- elem.setAttribute(u"output", self.output)
432+ elem = document.createElement("script")
433+ elem.setAttribute("id", self.id)
434+ elem.setAttribute("output", self.output)
435 frag.appendChild(elem)
436 return frag
437
438
439 def format_banner(scan):
440 """Format a startup banner more or less like Nmap does."""
441- scanner = u"Nmap"
442- if scan.scanner is not None and scan.scanner != u"nmap":
443+ scanner = "Nmap"
444+ if scan.scanner is not None and scan.scanner != "nmap":
445 scanner = scan.scanner
446 parts = [scanner]
447 if scan.version is not None:
448 parts.append(scan.version)
449- parts.append(u"scan")
450+ parts.append("scan")
451 if scan.start_date is not None:
452- parts.append(u"initiated %s" % scan.start_date.strftime(
453+ parts.append("initiated %s" % scan.start_date.strftime(
454 "%a %b %d %H:%M:%S %Y"))
455 if scan.args is not None:
456- parts.append(u"as: %s" % scan.args)
457- return u" ".join(parts)
458+ parts.append("as: %s" % scan.args)
459+ return " ".join(parts)
460
461
462 def print_script_result_diffs_text(title, script_results_a, script_results_b,
463 script_result_diffs, f=sys.stdout):
464- table = Table(u"*")
465+ table = Table("*")
466 for sr_diff in script_result_diffs:
467 sr_diff.append_to_port_table(table)
468 if len(table) > 0:
469- print >> f
470+ print(file=f)
471 if len(script_results_b) == 0:
472- print >> f, u"-%s:" % title
473+ print("-%s:" % title, file=f)
474 elif len(script_results_a) == 0:
475- print >> f, u"+%s:" % title
476+ print("+%s:" % title, file=f)
477 else:
478- print >> f, u" %s:" % title
479- print >> f, table
480+ print(" %s:" % title, file=f)
481+ print(table, file=f)
482
483
484 def script_result_diffs_to_dom_fragment(elem, script_results_a,
485@@ -489,13 +486,13 @@ def script_result_diffs_to_dom_fragment(
486 if len(script_results_a) == 0 and len(script_results_b) == 0:
487 return document.createDocumentFragment()
488 elif len(script_results_b) == 0:
489- a_elem = document.createElement(u"a")
490+ a_elem = document.createElement("a")
491 for sr in script_results_a:
492 elem.appendChild(sr.to_dom_fragment(document))
493 a_elem.appendChild(elem)
494 return a_elem
495 elif len(script_results_a) == 0:
496- b_elem = document.createElement(u"b")
497+ b_elem = document.createElement("b")
498 for sr in script_results_b:
499 elem.appendChild(sr.to_dom_fragment(document))
500 b_elem.appendChild(elem)
501@@ -581,10 +578,10 @@ class ScanDiffText(ScanDiff):
502 banner_a = format_banner(self.scan_a)
503 banner_b = format_banner(self.scan_b)
504 if banner_a != banner_b:
505- print >> self.f, u"-%s" % banner_a
506- print >> self.f, u"+%s" % banner_b
507+ print("-%s" % banner_a, file=self.f)
508+ print("+%s" % banner_b, file=self.f)
509 elif verbose:
510- print >> self.f, u" %s" % banner_a
511+ print(" %s" % banner_a, file=self.f)
512
513 def output_pre_scripts(self, pre_script_result_diffs):
514 print_script_result_diffs_text("Pre-scan script results",
515@@ -597,7 +594,7 @@ class ScanDiffText(ScanDiff):
516 post_script_result_diffs, self.f)
517
518 def output_host_diff(self, h_diff):
519- print >> self.f
520+ print(file=self.f)
521 h_diff.print_text(self.f)
522
523 def output_ending(self):
524@@ -622,8 +619,8 @@ class ScanDiffXML(ScanDiff):
525
526 def output_beginning(self):
527 self.writer.startDocument()
528- self.writer.startElement(u"nmapdiff", {u"version": NDIFF_XML_VERSION})
529- self.writer.startElement(u"scandiff", {})
530+ self.writer.startElement("nmapdiff", {"version": NDIFF_XML_VERSION})
531+ self.writer.startElement("scandiff", {})
532
533 if self.nmaprun_differs():
534 self.writer.frag_a(
535@@ -636,7 +633,7 @@ class ScanDiffXML(ScanDiff):
536
537 def output_pre_scripts(self, pre_script_result_diffs):
538 if len(pre_script_result_diffs) > 0 or verbose:
539- prescript_elem = self.document.createElement(u"prescript")
540+ prescript_elem = self.document.createElement("prescript")
541 frag = script_result_diffs_to_dom_fragment(
542 prescript_elem, self.scan_a.pre_script_results,
543 self.scan_b.pre_script_results, pre_script_result_diffs,
544@@ -646,7 +643,7 @@ class ScanDiffXML(ScanDiff):
545
546 def output_post_scripts(self, post_script_result_diffs):
547 if len(post_script_result_diffs) > 0 or verbose:
548- postscript_elem = self.document.createElement(u"postscript")
549+ postscript_elem = self.document.createElement("postscript")
550 frag = script_result_diffs_to_dom_fragment(
551 postscript_elem, self.scan_a.post_script_results,
552 self.scan_b.post_script_results, post_script_result_diffs,
553@@ -660,8 +657,8 @@ class ScanDiffXML(ScanDiff):
554 frag.unlink()
555
556 def output_ending(self):
557- self.writer.endElement(u"scandiff")
558- self.writer.endElement(u"nmapdiff")
559+ self.writer.endElement("scandiff")
560+ self.writer.endElement("nmapdiff")
561 self.writer.endDocument()
562
563
564@@ -719,9 +716,9 @@ class HostDiff(object):
565 self.cost += os_cost
566
567 extraports_a = tuple((count, state)
568- for (state, count) in self.host_a.extraports.items())
569+ for (state, count) in list(self.host_a.extraports.items()))
570 extraports_b = tuple((count, state)
571- for (state, count) in self.host_b.extraports.items())
572+ for (state, count) in list(self.host_b.extraports.items()))
573 if extraports_a != extraports_b:
574 self.extraports_changed = True
575 self.cost += 1
576@@ -747,69 +744,69 @@ class HostDiff(object):
577 # Names and addresses.
578 if self.id_changed:
579 if host_a.state is not None:
580- print >> f, u"-%s:" % host_a.format_name()
581+ print("-%s:" % host_a.format_name(), file=f)
582 if self.host_b.state is not None:
583- print >> f, u"+%s:" % host_b.format_name()
584+ print("+%s:" % host_b.format_name(), file=f)
585 else:
586- print >> f, u" %s:" % host_a.format_name()
587+ print(" %s:" % host_a.format_name(), file=f)
588
589 # State.
590 if self.state_changed:
591 if host_a.state is not None:
592- print >> f, u"-Host is %s." % host_a.state
593+ print("-Host is %s." % host_a.state, file=f)
594 if host_b.state is not None:
595- print >> f, u"+Host is %s." % host_b.state
596+ print("+Host is %s." % host_b.state, file=f)
597 elif verbose:
598- print >> f, u" Host is %s." % host_b.state
599+ print(" Host is %s." % host_b.state, file=f)
600
601 # Extraports.
602 if self.extraports_changed:
603 if len(host_a.extraports) > 0:
604- print >> f, u"-Not shown: %s" % host_a.extraports_string()
605+ print("-Not shown: %s" % host_a.extraports_string(), file=f)
606 if len(host_b.extraports) > 0:
607- print >> f, u"+Not shown: %s" % host_b.extraports_string()
608+ print("+Not shown: %s" % host_b.extraports_string(), file=f)
609 elif verbose:
610 if len(host_a.extraports) > 0:
611- print >> f, u" Not shown: %s" % host_a.extraports_string()
612+ print(" Not shown: %s" % host_a.extraports_string(), file=f)
613
614 # Port table.
615- port_table = Table(u"** * * *")
616+ port_table = Table("** * * *")
617 if host_a.state is None:
618- mark = u"+"
619+ mark = "+"
620 elif host_b.state is None:
621- mark = u"-"
622+ mark = "-"
623 else:
624- mark = u" "
625- port_table.append((mark, u"PORT", u"STATE", u"SERVICE", u"VERSION"))
626+ mark = " "
627+ port_table.append((mark, "PORT", "STATE", "SERVICE", "VERSION"))
628
629 for port in self.ports:
630 port_diff = self.port_diffs[port]
631 port_diff.append_to_port_table(port_table, host_a, host_b)
632
633 if len(port_table) > 1:
634- print >> f, port_table
635+ print(port_table, file=f)
636
637 # OS changes.
638 if self.os_changed or verbose:
639 if len(host_a.os) > 0:
640 if len(host_b.os) > 0:
641- print >> f, u" OS details:"
642+ print(" OS details:", file=f)
643 else:
644- print >> f, u"-OS details:"
645+ print("-OS details:", file=f)
646 elif len(host_b.os) > 0:
647- print >> f, u"+OS details:"
648+ print("+OS details:", file=f)
649 # os_diffs is a list of 5-tuples returned by
650 # difflib.SequenceMatcher.
651 for op, i1, i2, j1, j2 in self.os_diffs:
652 if op == "replace" or op == "delete":
653 for i in range(i1, i2):
654- print >> f, "- %s" % host_a.os[i]
655+ print("- %s" % host_a.os[i], file=f)
656 if op == "replace" or op == "insert":
657 for i in range(j1, j2):
658- print >> f, "+ %s" % host_b.os[i]
659+ print("+ %s" % host_b.os[i], file=f)
660 if op == "equal":
661 for i in range(i1, i2):
662- print >> f, " %s" % host_a.os[i]
663+ print(" %s" % host_a.os[i], file=f)
664
665 print_script_result_diffs_text("Host script results",
666 host_a.script_results, host_b.script_results,
667@@ -820,32 +817,32 @@ class HostDiff(object):
668 host_b = self.host_b
669
670 frag = document.createDocumentFragment()
671- hostdiff_elem = document.createElement(u"hostdiff")
672+ hostdiff_elem = document.createElement("hostdiff")
673 frag.appendChild(hostdiff_elem)
674
675 if host_a.state is None or host_b.state is None:
676 # The host is missing in one scan. Output the whole thing.
677 if host_a.state is not None:
678- a_elem = document.createElement(u"a")
679+ a_elem = document.createElement("a")
680 a_elem.appendChild(host_a.to_dom_fragment(document))
681 hostdiff_elem.appendChild(a_elem)
682 elif host_b.state is not None:
683- b_elem = document.createElement(u"b")
684+ b_elem = document.createElement("b")
685 b_elem.appendChild(host_b.to_dom_fragment(document))
686 hostdiff_elem.appendChild(b_elem)
687 return frag
688
689- host_elem = document.createElement(u"host")
690+ host_elem = document.createElement("host")
691
692 # State.
693 if host_a.state == host_b.state:
694 if verbose:
695 host_elem.appendChild(host_a.state_to_dom_fragment(document))
696 else:
697- a_elem = document.createElement(u"a")
698+ a_elem = document.createElement("a")
699 a_elem.appendChild(host_a.state_to_dom_fragment(document))
700 host_elem.appendChild(a_elem)
701- b_elem = document.createElement(u"b")
702+ b_elem = document.createElement("b")
703 b_elem.appendChild(host_b.state_to_dom_fragment(document))
704 host_elem.appendChild(b_elem)
705
706@@ -854,31 +851,31 @@ class HostDiff(object):
707 addrset_b = set(host_b.addresses)
708 for addr in sorted(addrset_a.intersection(addrset_b)):
709 host_elem.appendChild(addr.to_dom_fragment(document))
710- a_elem = document.createElement(u"a")
711+ a_elem = document.createElement("a")
712 for addr in sorted(addrset_a - addrset_b):
713 a_elem.appendChild(addr.to_dom_fragment(document))
714 if a_elem.hasChildNodes():
715 host_elem.appendChild(a_elem)
716- b_elem = document.createElement(u"b")
717+ b_elem = document.createElement("b")
718 for addr in sorted(addrset_b - addrset_a):
719 b_elem.appendChild(addr.to_dom_fragment(document))
720 if b_elem.hasChildNodes():
721 host_elem.appendChild(b_elem)
722
723 # Host names.
724- hostnames_elem = document.createElement(u"hostnames")
725+ hostnames_elem = document.createElement("hostnames")
726 hostnameset_a = set(host_a.hostnames)
727 hostnameset_b = set(host_b.hostnames)
728 for hostname in sorted(hostnameset_a.intersection(hostnameset_b)):
729 hostnames_elem.appendChild(
730 host_a.hostname_to_dom_fragment(document, hostname))
731- a_elem = document.createElement(u"a")
732+ a_elem = document.createElement("a")
733 for hostname in sorted(hostnameset_a - hostnameset_b):
734 a_elem.appendChild(
735 host_a.hostname_to_dom_fragment(document, hostname))
736 if a_elem.hasChildNodes():
737 hostnames_elem.appendChild(a_elem)
738- b_elem = document.createElement(u"b")
739+ b_elem = document.createElement("b")
740 for hostname in sorted(hostnameset_b - hostnameset_a):
741 b_elem.appendChild(
742 host_b.hostname_to_dom_fragment(document, hostname))
743@@ -887,15 +884,15 @@ class HostDiff(object):
744 if hostnames_elem.hasChildNodes():
745 host_elem.appendChild(hostnames_elem)
746
747- ports_elem = document.createElement(u"ports")
748+ ports_elem = document.createElement("ports")
749 # Extraports.
750 if host_a.extraports == host_b.extraports:
751 ports_elem.appendChild(host_a.extraports_to_dom_fragment(document))
752 else:
753- a_elem = document.createElement(u"a")
754+ a_elem = document.createElement("a")
755 a_elem.appendChild(host_a.extraports_to_dom_fragment(document))
756 ports_elem.appendChild(a_elem)
757- b_elem = document.createElement(u"b")
758+ b_elem = document.createElement("b")
759 b_elem.appendChild(host_b.extraports_to_dom_fragment(document))
760 ports_elem.appendChild(b_elem)
761 # Port list.
762@@ -911,18 +908,18 @@ class HostDiff(object):
763
764 # OS changes.
765 if self.os_changed or verbose:
766- os_elem = document.createElement(u"os")
767+ os_elem = document.createElement("os")
768 # os_diffs is a list of 5-tuples returned by
769 # difflib.SequenceMatcher.
770 for op, i1, i2, j1, j2 in self.os_diffs:
771 if op == "replace" or op == "delete":
772- a_elem = document.createElement(u"a")
773+ a_elem = document.createElement("a")
774 for i in range(i1, i2):
775 a_elem.appendChild(host_a.os_to_dom_fragment(
776 document, host_a.os[i]))
777 os_elem.appendChild(a_elem)
778 if op == "replace" or op == "insert":
779- b_elem = document.createElement(u"b")
780+ b_elem = document.createElement("b")
781 for i in range(j1, j2):
782 b_elem.appendChild(host_b.os_to_dom_fragment(
783 document, host_b.os[i]))
784@@ -936,7 +933,7 @@ class HostDiff(object):
785
786 # Host script changes.
787 if len(self.script_result_diffs) > 0 or verbose:
788- hostscript_elem = document.createElement(u"hostscript")
789+ hostscript_elem = document.createElement("hostscript")
790 host_elem.appendChild(script_result_diffs_to_dom_fragment(
791 hostscript_elem, host_a.script_results,
792 host_b.script_results, self.script_result_diffs,
793@@ -989,38 +986,38 @@ class PortDiff(object):
794 self.port_b.service.version_string()]
795 if a_columns == b_columns:
796 if verbose or self.script_result_diffs > 0:
797- table.append([u" "] + a_columns)
798+ table.append([" "] + a_columns)
799 else:
800 if not host_a.is_extraports(self.port_a.state):
801- table.append([u"-"] + a_columns)
802+ table.append(["-"] + a_columns)
803 if not host_b.is_extraports(self.port_b.state):
804- table.append([u"+"] + b_columns)
805+ table.append(["+"] + b_columns)
806
807 for sr_diff in self.script_result_diffs:
808 sr_diff.append_to_port_table(table)
809
810 def to_dom_fragment(self, document):
811 frag = document.createDocumentFragment()
812- portdiff_elem = document.createElement(u"portdiff")
813+ portdiff_elem = document.createElement("portdiff")
814 frag.appendChild(portdiff_elem)
815 if (self.port_a.spec == self.port_b.spec and
816 self.port_a.state == self.port_b.state):
817- port_elem = document.createElement(u"port")
818- port_elem.setAttribute(u"portid", unicode(self.port_a.spec[0]))
819- port_elem.setAttribute(u"protocol", self.port_a.spec[1])
820+ port_elem = document.createElement("port")
821+ port_elem.setAttribute("portid", str(self.port_a.spec[0]))
822+ port_elem.setAttribute("protocol", self.port_a.spec[1])
823 if self.port_a.state is not None:
824- state_elem = document.createElement(u"state")
825- state_elem.setAttribute(u"state", self.port_a.state)
826+ state_elem = document.createElement("state")
827+ state_elem.setAttribute("state", self.port_a.state)
828 port_elem.appendChild(state_elem)
829 if self.port_a.service == self.port_b.service:
830 port_elem.appendChild(
831 self.port_a.service.to_dom_fragment(document))
832 else:
833- a_elem = document.createElement(u"a")
834+ a_elem = document.createElement("a")
835 a_elem.appendChild(
836 self.port_a.service.to_dom_fragment(document))
837 port_elem.appendChild(a_elem)
838- b_elem = document.createElement(u"b")
839+ b_elem = document.createElement("b")
840 b_elem.appendChild(
841 self.port_b.service.to_dom_fragment(document))
842 port_elem.appendChild(b_elem)
843@@ -1028,10 +1025,10 @@ class PortDiff(object):
844 port_elem.appendChild(sr_diff.to_dom_fragment(document))
845 portdiff_elem.appendChild(port_elem)
846 else:
847- a_elem = document.createElement(u"a")
848+ a_elem = document.createElement("a")
849 a_elem.appendChild(self.port_a.to_dom_fragment(document))
850 portdiff_elem.appendChild(a_elem)
851- b_elem = document.createElement(u"b")
852+ b_elem = document.createElement("b")
853 b_elem.appendChild(self.port_b.to_dom_fragment(document))
854 portdiff_elem.appendChild(b_elem)
855
856@@ -1086,13 +1083,13 @@ class ScriptResultDiff(object):
857 for op, i1, i2, j1, j2 in diffs.get_opcodes():
858 if op == "replace" or op == "delete":
859 for k in range(i1, i2):
860- table.append_raw(u"-" + a_lines[k])
861+ table.append_raw("-" + a_lines[k])
862 if op == "replace" or op == "insert":
863 for k in range(j1, j2):
864- table.append_raw(u"+" + b_lines[k])
865+ table.append_raw("+" + b_lines[k])
866 if op == "equal":
867 for k in range(i1, i2):
868- table.append_raw(u" " + a_lines[k])
869+ table.append_raw(" " + a_lines[k])
870
871 def to_dom_fragment(self, document):
872 frag = document.createDocumentFragment()
873@@ -1102,11 +1099,11 @@ class ScriptResultDiff(object):
874 frag.appendChild(self.sr_a.to_dom_fragment(document))
875 else:
876 if self.sr_a is not None:
877- a_elem = document.createElement(u"a")
878+ a_elem = document.createElement("a")
879 a_elem.appendChild(self.sr_a.to_dom_fragment(document))
880 frag.appendChild(a_elem)
881 if self.sr_b is not None:
882- b_elem = document.createElement(u"b")
883+ b_elem = document.createElement("b")
884 b_elem.appendChild(self.sr_b.to_dom_fragment(document))
885 frag.appendChild(b_elem)
886 return frag
887@@ -1120,7 +1117,7 @@ class Table(object):
888 copied to the output."""
889 self.widths = []
890 self.rows = []
891- self.prefix = u""
892+ self.prefix = ""
893 self.padding = []
894 j = 0
895 while j < len(template) and template[j] != "*":
896@@ -1145,7 +1142,7 @@ class Table(object):
897
898 for i in range(len(row)):
899 if row[i] is None:
900- s = u""
901+ s = ""
902 else:
903 s = str(row[i])
904 if i == len(self.widths):
905@@ -1167,7 +1164,7 @@ class Table(object):
906 for row in self.rows:
907 parts = [self.prefix]
908 i = 0
909- if isinstance(row, basestring):
910+ if isinstance(row, str):
911 # A raw string.
912 lines.append(row)
913 else:
914@@ -1176,13 +1173,13 @@ class Table(object):
915 if i < len(self.padding):
916 parts.append(self.padding[i])
917 i += 1
918- lines.append(u"".join(parts).rstrip())
919- return u"\n".join(lines)
920+ lines.append("".join(parts).rstrip())
921+ return "\n".join(lines)
922
923
924 def warn(str):
925 """Print a warning to stderr."""
926- print >> sys.stderr, str
927+ print(str, file=sys.stderr)
928
929
930 class NmapContentHandler(xml.sax.handler.ContentHandler):
931@@ -1200,22 +1197,22 @@ class NmapContentHandler(xml.sax.handler
932 self.current_port = None
933
934 self._start_elem_handlers = {
935- u"nmaprun": self._start_nmaprun,
936- u"host": self._start_host,
937- u"status": self._start_status,
938- u"address": self._start_address,
939- u"hostname": self._start_hostname,
940- u"extraports": self._start_extraports,
941- u"port": self._start_port,
942- u"state": self._start_state,
943- u"service": self._start_service,
944- u"script": self._start_script,
945- u"osmatch": self._start_osmatch,
946- u"finished": self._start_finished,
947+ "nmaprun": self._start_nmaprun,
948+ "host": self._start_host,
949+ "status": self._start_status,
950+ "address": self._start_address,
951+ "hostname": self._start_hostname,
952+ "extraports": self._start_extraports,
953+ "port": self._start_port,
954+ "state": self._start_state,
955+ "service": self._start_service,
956+ "script": self._start_script,
957+ "osmatch": self._start_osmatch,
958+ "finished": self._start_finished,
959 }
960 self._end_elem_handlers = {
961- u'host': self._end_host,
962- u'port': self._end_port,
963+ 'host': self._end_host,
964+ 'port': self._end_port,
965 }
966
967 def parent_element(self):
968@@ -1245,68 +1242,68 @@ class NmapContentHandler(xml.sax.handler
969 def _start_nmaprun(self, name, attrs):
970 assert self.parent_element() is None
971 if "start" in attrs:
972- start_timestamp = int(attrs.get(u"start"))
973+ start_timestamp = int(attrs.get("start"))
974 self.scan.start_date = datetime.datetime.fromtimestamp(
975 start_timestamp)
976- self.scan.scanner = attrs.get(u"scanner")
977- self.scan.args = attrs.get(u"args")
978- self.scan.version = attrs.get(u"version")
979+ self.scan.scanner = attrs.get("scanner")
980+ self.scan.args = attrs.get("args")
981+ self.scan.version = attrs.get("version")
982
983 def _start_host(self, name, attrs):
984- assert self.parent_element() == u"nmaprun"
985+ assert self.parent_element() == "nmaprun"
986 self.current_host = Host()
987 self.scan.hosts.append(self.current_host)
988
989 def _start_status(self, name, attrs):
990- assert self.parent_element() == u"host"
991+ assert self.parent_element() == "host"
992 assert self.current_host is not None
993- state = attrs.get(u"state")
994+ state = attrs.get("state")
995 if state is None:
996 warn(u'%s element of host %s is missing the "state" attribute; '
997- 'assuming \unknown\.' % (
998+ r'assuming \unknown\.' % (
999 name, self.current_host.format_name()))
1000 return
1001 self.current_host.state = state
1002
1003 def _start_address(self, name, attrs):
1004- assert self.parent_element() == u"host"
1005+ assert self.parent_element() == "host"
1006 assert self.current_host is not None
1007- addr = attrs.get(u"addr")
1008+ addr = attrs.get("addr")
1009 if addr is None:
1010- warn(u'%s element of host %s is missing the "addr" '
1011+ warn('%s element of host %s is missing the "addr" '
1012 'attribute; skipping.' % (
1013 name, self.current_host.format_name()))
1014 return
1015- addrtype = attrs.get(u"addrtype", u"ipv4")
1016+ addrtype = attrs.get("addrtype", "ipv4")
1017 self.current_host.add_address(Address.new(addrtype, addr))
1018
1019 def _start_hostname(self, name, attrs):
1020- assert self.parent_element() == u"hostnames"
1021+ assert self.parent_element() == "hostnames"
1022 assert self.current_host is not None
1023- hostname = attrs.get(u"name")
1024+ hostname = attrs.get("name")
1025 if hostname is None:
1026- warn(u'%s element of host %s is missing the "name" '
1027+ warn('%s element of host %s is missing the "name" '
1028 'attribute; skipping.' % (
1029 name, self.current_host.format_name()))
1030 return
1031 self.current_host.add_hostname(hostname)
1032
1033 def _start_extraports(self, name, attrs):
1034- assert self.parent_element() == u"ports"
1035+ assert self.parent_element() == "ports"
1036 assert self.current_host is not None
1037- state = attrs.get(u"state")
1038+ state = attrs.get("state")
1039 if state is None:
1040- warn(u'%s element of host %s is missing the "state" '
1041+ warn('%s element of host %s is missing the "state" '
1042 'attribute; assuming "unknown".' % (
1043 name, self.current_host.format_name()))
1044 state = None
1045 if state in self.current_host.extraports:
1046- warn(u'Duplicate extraports state "%s" in host %s.' % (
1047+ warn('Duplicate extraports state "%s" in host %s.' % (
1048 state, self.current_host.format_name()))
1049
1050- count = attrs.get(u"count")
1051+ count = attrs.get("count")
1052 if count is None:
1053- warn(u'%s element of host %s is missing the "count" '
1054+ warn('%s element of host %s is missing the "count" '
1055 'attribute; assuming 0.' % (
1056 name, self.current_host.format_name()))
1057 count = 0
1058@@ -1314,99 +1311,99 @@ class NmapContentHandler(xml.sax.handler
1059 try:
1060 count = int(count)
1061 except ValueError:
1062- warn(u"Can't convert extraports count \"%s\" "
1063+ warn("Can't convert extraports count \"%s\" "
1064 "to an integer in host %s; assuming 0." % (
1065- attrs[u"count"], self.current_host.format_name()))
1066+ attrs["count"], self.current_host.format_name()))
1067 count = 0
1068 self.current_host.extraports[state] = count
1069
1070 def _start_port(self, name, attrs):
1071- assert self.parent_element() == u"ports"
1072+ assert self.parent_element() == "ports"
1073 assert self.current_host is not None
1074- portid_str = attrs.get(u"portid")
1075+ portid_str = attrs.get("portid")
1076 if portid_str is None:
1077- warn(u'%s element of host %s missing the "portid" '
1078+ warn('%s element of host %s missing the "portid" '
1079 'attribute; skipping.' % (
1080 name, self.current_host.format_name()))
1081 return
1082 try:
1083 portid = int(portid_str)
1084 except ValueError:
1085- warn(u"Can't convert portid \"%s\" to an integer "
1086+ warn("Can't convert portid \"%s\" to an integer "
1087 "in host %s; skipping port." % (
1088 portid_str, self.current_host.format_name()))
1089 return
1090- protocol = attrs.get(u"protocol")
1091+ protocol = attrs.get("protocol")
1092 if protocol is None:
1093- warn(u'%s element of host %s missing the "protocol" '
1094+ warn('%s element of host %s missing the "protocol" '
1095 'attribute; skipping.' % (
1096 name, self.current_host.format_name()))
1097 return
1098 self.current_port = Port((portid, protocol))
1099
1100 def _start_state(self, name, attrs):
1101- assert self.parent_element() == u"port"
1102+ assert self.parent_element() == "port"
1103 assert self.current_host is not None
1104 if self.current_port is None:
1105 return
1106 if "state" not in attrs:
1107- warn(u'%s element of port %s is missing the "state" '
1108+ warn('%s element of port %s is missing the "state" '
1109 'attribute; assuming "unknown".' % (
1110 name, self.current_port.spec_string()))
1111 return
1112- self.current_port.state = attrs[u"state"]
1113+ self.current_port.state = attrs["state"]
1114 self.current_host.add_port(self.current_port)
1115
1116 def _start_service(self, name, attrs):
1117- assert self.parent_element() == u"port"
1118+ assert self.parent_element() == "port"
1119 assert self.current_host is not None
1120 if self.current_port is None:
1121 return
1122- self.current_port.service.name = attrs.get(u"name")
1123- self.current_port.service.product = attrs.get(u"product")
1124- self.current_port.service.version = attrs.get(u"version")
1125- self.current_port.service.extrainfo = attrs.get(u"extrainfo")
1126- self.current_port.service.tunnel = attrs.get(u"tunnel")
1127+ self.current_port.service.name = attrs.get("name")
1128+ self.current_port.service.product = attrs.get("product")
1129+ self.current_port.service.version = attrs.get("version")
1130+ self.current_port.service.extrainfo = attrs.get("extrainfo")
1131+ self.current_port.service.tunnel = attrs.get("tunnel")
1132
1133 def _start_script(self, name, attrs):
1134 result = ScriptResult()
1135- result.id = attrs.get(u"id")
1136+ result.id = attrs.get("id")
1137 if result.id is None:
1138- warn(u'%s element missing the "id" attribute; skipping.' % name)
1139+ warn('%s element missing the "id" attribute; skipping.' % name)
1140 return
1141
1142- result.output = attrs.get(u"output")
1143+ result.output = attrs.get("output")
1144 if result.output is None:
1145- warn(u'%s element missing the "output" attribute; skipping.'
1146+ warn('%s element missing the "output" attribute; skipping.'
1147 % name)
1148 return
1149- if self.parent_element() == u"prescript":
1150+ if self.parent_element() == "prescript":
1151 self.scan.pre_script_results.append(result)
1152- elif self.parent_element() == u"postscript":
1153+ elif self.parent_element() == "postscript":
1154 self.scan.post_script_results.append(result)
1155- elif self.parent_element() == u"hostscript":
1156+ elif self.parent_element() == "hostscript":
1157 self.current_host.script_results.append(result)
1158- elif self.parent_element() == u"port":
1159+ elif self.parent_element() == "port":
1160 self.current_port.script_results.append(result)
1161 else:
1162- warn(u"%s element not inside prescript, postscript, hostscript, "
1163+ warn("%s element not inside prescript, postscript, hostscript, "
1164 "or port element; ignoring." % name)
1165 return
1166
1167 def _start_osmatch(self, name, attrs):
1168- assert self.parent_element() == u"os"
1169+ assert self.parent_element() == "os"
1170 assert self.current_host is not None
1171 if "name" not in attrs:
1172- warn(u'%s element of host %s is missing the "name" '
1173+ warn('%s element of host %s is missing the "name" '
1174 'attribute; skipping.' % (
1175 name, self.current_host.format_name()))
1176 return
1177- self.current_host.os.append(attrs[u"name"])
1178+ self.current_host.os.append(attrs["name"])
1179
1180 def _start_finished(self, name, attrs):
1181- assert self.parent_element() == u"runstats"
1182+ assert self.parent_element() == "runstats"
1183 if "time" in attrs:
1184- end_timestamp = int(attrs.get(u"time"))
1185+ end_timestamp = int(attrs.get("time"))
1186 self.scan.end_date = datetime.datetime.fromtimestamp(end_timestamp)
1187
1188 def _end_host(self, name):
1189@@ -1425,23 +1422,23 @@ class XMLWriter (xml.sax.saxutils.XMLGen
1190
1191 def frag(self, frag):
1192 for node in frag.childNodes:
1193- node.writexml(self.f, newl=u"\n")
1194+ node.writexml(self.f, newl="\n")
1195
1196 def frag_a(self, frag):
1197- self.startElement(u"a", {})
1198+ self.startElement("a", {})
1199 for node in frag.childNodes:
1200- node.writexml(self.f, newl=u"\n")
1201- self.endElement(u"a")
1202+ node.writexml(self.f, newl="\n")
1203+ self.endElement("a")
1204
1205 def frag_b(self, frag):
1206- self.startElement(u"b", {})
1207+ self.startElement("b", {})
1208 for node in frag.childNodes:
1209- node.writexml(self.f, newl=u"\n")
1210- self.endElement(u"b")
1211+ node.writexml(self.f, newl="\n")
1212+ self.endElement("b")
1213
1214
1215 def usage():
1216- print u"""\
1217+ print("""\
1218 Usage: %s [option] FILE1 FILE2
1219 Compare two Nmap XML files and display a list of their differences.
1220 Differences include host state changes, port state changes, and changes to
1221@@ -1451,7 +1448,7 @@ service and OS detection.
1222 -v, --verbose also show hosts and ports that haven't changed.
1223 --text display output in text format (default)
1224 --xml display output in XML format\
1225-""" % sys.argv[0]
1226+""" % sys.argv[0])
1227
1228 EXIT_EQUAL = 0
1229 EXIT_DIFFERENT = 1
1230@@ -1459,8 +1456,8 @@ EXIT_ERROR = 2
1231
1232
1233 def usage_error(msg):
1234- print >> sys.stderr, u"%s: %s" % (sys.argv[0], msg)
1235- print >> sys.stderr, u"Try '%s -h' for help." % sys.argv[0]
1236+ print("%s: %s" % (sys.argv[0], msg), file=sys.stderr)
1237+ print("Try '%s -h' for help." % sys.argv[0], file=sys.stderr)
1238 sys.exit(EXIT_ERROR)
1239
1240
1241@@ -1471,7 +1468,7 @@ def main():
1242 try:
1243 opts, input_filenames = getopt.gnu_getopt(
1244 sys.argv[1:], "hv", ["help", "text", "verbose", "xml"])
1245- except getopt.GetoptError, e:
1246+ except getopt.GetoptError as e:
1247 usage_error(e.msg)
1248 for o, a in opts:
1249 if o == "-h" or o == "--help":
1250@@ -1481,15 +1478,15 @@ def main():
1251 verbose = True
1252 elif o == "--text":
1253 if output_format is not None and output_format != "text":
1254- usage_error(u"contradictory output format options.")
1255+ usage_error("contradictory output format options.")
1256 output_format = "text"
1257 elif o == "--xml":
1258 if output_format is not None and output_format != "xml":
1259- usage_error(u"contradictory output format options.")
1260+ usage_error("contradictory output format options.")
1261 output_format = "xml"
1262
1263 if len(input_filenames) != 2:
1264- usage_error(u"need exactly two input filenames.")
1265+ usage_error("need exactly two input filenames.")
1266
1267 if output_format is None:
1268 output_format = "text"
1269@@ -1502,8 +1499,8 @@ def main():
1270 scan_a.load_from_file(filename_a)
1271 scan_b = Scan()
1272 scan_b.load_from_file(filename_b)
1273- except IOError, e:
1274- print >> sys.stderr, u"Can't open file: %s" % str(e)
1275+ except IOError as e:
1276+ print("Can't open file: %s" % str(e), file=sys.stderr)
1277 sys.exit(EXIT_ERROR)
1278
1279 if output_format == "text":
1280--- a/ndiff/ndifftest.py
1281+++ b/ndiff/ndifftest.py
1282@@ -1,4 +1,4 @@
1283-#!/usr/bin/env python
1284+#!/usr/bin/env python3
1285
1286 # Unit tests for Ndiff.
1287
1288@@ -22,7 +22,7 @@ for x in dir(ndiff):
1289 sys.dont_write_bytecode = dont_write_bytecode
1290 del dont_write_bytecode
1291
1292-import StringIO
1293+import io
1294
1295
1296 class scan_test(unittest.TestCase):
1297@@ -52,7 +52,7 @@ class scan_test(unittest.TestCase):
1298 scan.load_from_file("test-scans/single.xml")
1299 host = scan.hosts[0]
1300 self.assertEqual(len(host.ports), 5)
1301- self.assertEqual(host.extraports.items(), [("filtered", 95)])
1302+ self.assertEqual(list(host.extraports.items()), [("filtered", 95)])
1303
1304 def test_extraports_multi(self):
1305 """Test that the correct number of known ports is returned when there
1306@@ -68,9 +68,9 @@ class scan_test(unittest.TestCase):
1307 """Test that nmaprun information is recorded."""
1308 scan = Scan()
1309 scan.load_from_file("test-scans/empty.xml")
1310- self.assertEqual(scan.scanner, u"nmap")
1311- self.assertEqual(scan.version, u"4.90RC2")
1312- self.assertEqual(scan.args, u"nmap -oX empty.xml -p 1-100")
1313+ self.assertEqual(scan.scanner, "nmap")
1314+ self.assertEqual(scan.version, "4.90RC2")
1315+ self.assertEqual(scan.args, "nmap -oX empty.xml -p 1-100")
1316
1317 def test_addresses(self):
1318 """Test that addresses are recorded."""
1319@@ -84,7 +84,7 @@ class scan_test(unittest.TestCase):
1320 scan = Scan()
1321 scan.load_from_file("test-scans/simple.xml")
1322 host = scan.hosts[0]
1323- self.assertEqual(host.hostnames, [u"scanme.nmap.org"])
1324+ self.assertEqual(host.hostnames, ["scanme.nmap.org"])
1325
1326 def test_os(self):
1327 """Test that OS information is recorded."""
1328@@ -99,7 +99,7 @@ class scan_test(unittest.TestCase):
1329 scan.load_from_file("test-scans/complex.xml")
1330 host = scan.hosts[0]
1331 self.assertTrue(len(host.script_results) > 0)
1332- self.assertTrue(len(host.ports[(22, u"tcp")].script_results) > 0)
1333+ self.assertTrue(len(host.ports[(22, "tcp")].script_results) > 0)
1334
1335 # This test is commented out because Nmap XML doesn't store any information
1336 # about down hosts, not even the fact that they are down. Recovering the list
1337@@ -128,16 +128,16 @@ class host_test(unittest.TestCase):
1338
1339 def test_format_name(self):
1340 h = Host()
1341- self.assertTrue(isinstance(h.format_name(), basestring))
1342- h.add_address(IPv4Address(u"127.0.0.1"))
1343- self.assertTrue(u"127.0.0.1" in h.format_name())
1344+ self.assertTrue(isinstance(h.format_name(), str))
1345+ h.add_address(IPv4Address("127.0.0.1"))
1346+ self.assertTrue("127.0.0.1" in h.format_name())
1347 h.add_address(IPv6Address("::1"))
1348- self.assertTrue(u"127.0.0.1" in h.format_name())
1349- self.assertTrue(u"::1" in h.format_name())
1350- h.add_hostname(u"localhost")
1351- self.assertTrue(u"127.0.0.1" in h.format_name())
1352- self.assertTrue(u"::1" in h.format_name())
1353- self.assertTrue(u"localhost" in h.format_name())
1354+ self.assertTrue("127.0.0.1" in h.format_name())
1355+ self.assertTrue("::1" in h.format_name())
1356+ h.add_hostname("localhost")
1357+ self.assertTrue("127.0.0.1" in h.format_name())
1358+ self.assertTrue("::1" in h.format_name())
1359+ self.assertTrue("localhost" in h.format_name())
1360
1361 def test_empty_get_port(self):
1362 h = Host()
1363@@ -197,8 +197,8 @@ class host_test(unittest.TestCase):
1364 h = s.hosts[0]
1365 self.assertEqual(len(h.ports), 5)
1366 self.assertEqual(len(h.extraports), 1)
1367- self.assertEqual(h.extraports.keys()[0], u"filtered")
1368- self.assertEqual(h.extraports.values()[0], 95)
1369+ self.assertEqual(list(h.extraports.keys())[0], "filtered")
1370+ self.assertEqual(list(h.extraports.values())[0], 95)
1371 self.assertEqual(h.state, "up")
1372
1373
1374@@ -241,13 +241,13 @@ class port_test(unittest.TestCase):
1375 """Test the Port class."""
1376 def test_spec_string(self):
1377 p = Port((10, "tcp"))
1378- self.assertEqual(p.spec_string(), u"10/tcp")
1379+ self.assertEqual(p.spec_string(), "10/tcp")
1380 p = Port((100, "ip"))
1381- self.assertEqual(p.spec_string(), u"100/ip")
1382+ self.assertEqual(p.spec_string(), "100/ip")
1383
1384 def test_state_string(self):
1385 p = Port((10, "tcp"))
1386- self.assertEqual(p.state_string(), u"unknown")
1387+ self.assertEqual(p.state_string(), "unknown")
1388
1389
1390 class service_test(unittest.TestCase):
1391@@ -255,47 +255,47 @@ class service_test(unittest.TestCase):
1392 def test_compare(self):
1393 """Test that services with the same contents compare equal."""
1394 a = Service()
1395- a.name = u"ftp"
1396- a.product = u"FooBar FTP"
1397- a.version = u"1.1.1"
1398- a.tunnel = u"ssl"
1399+ a.name = "ftp"
1400+ a.product = "FooBar FTP"
1401+ a.version = "1.1.1"
1402+ a.tunnel = "ssl"
1403 self.assertEqual(a, a)
1404 b = Service()
1405- b.name = u"ftp"
1406- b.product = u"FooBar FTP"
1407- b.version = u"1.1.1"
1408- b.tunnel = u"ssl"
1409+ b.name = "ftp"
1410+ b.product = "FooBar FTP"
1411+ b.version = "1.1.1"
1412+ b.tunnel = "ssl"
1413 self.assertEqual(a, b)
1414- b.name = u"http"
1415+ b.name = "http"
1416 self.assertNotEqual(a, b)
1417 c = Service()
1418 self.assertNotEqual(a, c)
1419
1420 def test_tunnel(self):
1421 serv = Service()
1422- serv.name = u"http"
1423- serv.tunnel = u"ssl"
1424- self.assertEqual(serv.name_string(), u"ssl/http")
1425+ serv.name = "http"
1426+ serv.tunnel = "ssl"
1427+ self.assertEqual(serv.name_string(), "ssl/http")
1428
1429 def test_version_string(self):
1430 serv = Service()
1431- serv.product = u"FooBar"
1432+ serv.product = "FooBar"
1433 self.assertTrue(len(serv.version_string()) > 0)
1434 serv = Service()
1435- serv.version = u"1.2.3"
1436+ serv.version = "1.2.3"
1437 self.assertTrue(len(serv.version_string()) > 0)
1438 serv = Service()
1439- serv.extrainfo = u"misconfigured"
1440+ serv.extrainfo = "misconfigured"
1441 self.assertTrue(len(serv.version_string()) > 0)
1442 serv = Service()
1443- serv.product = u"FooBar"
1444- serv.version = u"1.2.3"
1445+ serv.product = "FooBar"
1446+ serv.version = "1.2.3"
1447 # Must match Nmap output.
1448 self.assertEqual(serv.version_string(),
1449- u"%s %s" % (serv.product, serv.version))
1450- serv.extrainfo = u"misconfigured"
1451+ "%s %s" % (serv.product, serv.version))
1452+ serv.extrainfo = "misconfigured"
1453 self.assertEqual(serv.version_string(),
1454- u"%s %s (%s)" % (serv.product, serv.version, serv.extrainfo))
1455+ "%s %s (%s)" % (serv.product, serv.version, serv.extrainfo))
1456
1457
1458 class ScanDiffSub(ScanDiff):
1459@@ -703,7 +703,7 @@ class scan_diff_xml_test(unittest.TestCa
1460 a.load_from_file("test-scans/empty.xml")
1461 b = Scan()
1462 b.load_from_file("test-scans/simple.xml")
1463- f = StringIO.StringIO()
1464+ f = io.StringIO()
1465 self.scan_diff = ScanDiffXML(a, b, f)
1466 self.scan_diff.output()
1467 self.xml = f.getvalue()
1468@@ -712,8 +712,8 @@ class scan_diff_xml_test(unittest.TestCa
1469 def test_well_formed(self):
1470 try:
1471 document = xml.dom.minidom.parseString(self.xml)
1472- except Exception, e:
1473- self.fail(u"Parsing XML diff output caused the exception: %s"
1474+ except Exception as e:
1475+ self.fail("Parsing XML diff output caused the exception: %s"
1476 % str(e))
1477
1478
1479@@ -739,8 +739,8 @@ def host_apply_diff(host, diff):
1480 host.os = diff.host_b.os[:]
1481
1482 if diff.extraports_changed:
1483- for state in host.extraports.keys():
1484- for port in host.ports.values():
1485+ for state in list(host.extraports.keys()):
1486+ for port in list(host.ports.values()):
1487 if port.state == state:
1488 del host.ports[port.spec]
1489 host.extraports = diff.host_b.extraports.copy()
1490--- a/ndiff/scripts/ndiff
1491+++ b/ndiff/scripts/ndiff
1492@@ -1,4 +1,4 @@
1493-#!/usr/bin/env python
1494+#!/usr/bin/env python3
1495
1496 # Ndiff
1497 #
1498@@ -67,15 +67,15 @@ if INSTALL_LIB is not None and is_secure
1499
1500 try:
1501 import ndiff
1502-except ImportError, e:
1503- print >> sys.stderr, """\
1504+except ImportError as e:
1505+ print("""\
1506 Could not import the ndiff module: %s.
1507-I checked in these directories:""" % repr(e.message)
1508+I checked in these directories:""" % repr(e), file=sys.stderr)
1509 for dir in sys.path:
1510- print >> sys.stderr, " %s" % dir
1511- print >> sys.stderr, """\
1512+ print(" %s" % dir, file=sys.stderr)
1513+ print("""\
1514 If you installed Ndiff in another directory, you may have to add the
1515-modules directory to the PYTHONPATH environment variable."""
1516+modules directory to the PYTHONPATH environment variable.""", file=sys.stderr)
1517 sys.exit(1)
1518
1519 import ndiff
1520--- a/ndiff/setup.py
1521+++ b/ndiff/setup.py
1522@@ -94,7 +94,7 @@ class checked_install(distutils.command.
1523 self.saved_prefix = sys.prefix
1524 try:
1525 distutils.command.install.install.finalize_options(self)
1526- except distutils.errors.DistutilsPlatformError, e:
1527+ except distutils.errors.DistutilsPlatformError as e:
1528 raise distutils.errors.DistutilsPlatformError(str(e) + """
1529 Installing your distribution's python-dev package may solve this problem.""")
1530
1531@@ -155,13 +155,13 @@ Installing your distribution's python-de
1532 #!/usr/bin/env python
1533 import errno, os, os.path, sys
1534
1535-print 'Uninstall %(name)s'
1536+print('Uninstall %(name)s')
1537
1538 answer = raw_input('Are you sure that you want to uninstall '
1539 '%(name)s (yes/no) ')
1540
1541 if answer != 'yes' and answer != 'y':
1542- print 'Not uninstalling.'
1543+ print('Not uninstalling.')
1544 sys.exit(0)
1545
1546 """ % {'name': APP_NAME}
1547@@ -177,8 +177,8 @@ if answer != 'yes' and answer != 'y':
1548 # This should never happen (everything gets installed
1549 # inside the root), but if it does, be safe and don't
1550 # delete anything.
1551- uninstaller += ("print '%s was not installed inside "
1552- "the root %s; skipping.'\n" % (output, self.root))
1553+ uninstaller += ("print('%s was not installed inside "
1554+ "the root %s; skipping.')\n" % (output, self.root))
1555 continue
1556 output = path_strip_prefix(output, self.root)
1557 assert os.path.isabs(output)
1558@@ -202,24 +202,24 @@ for path in INSTALLED_FILES:
1559 dirs.append(path)
1560 # Delete the files.
1561 for file in files:
1562- print "Removing '%s'." % file
1563+ print("Removing '%s'." % file)
1564 try:
1565 os.remove(file)
1566- except OSError, e:
1567- print >> sys.stderr, ' Error: %s.' % str(e)
1568+ except OSError as e:
1569+ print(' Error: %s.' % str(e), file=sys.stderr)
1570 # Delete the directories. First reverse-sort the normalized paths by
1571 # length so that child directories are deleted before their parents.
1572 dirs = [os.path.normpath(dir) for dir in dirs]
1573 dirs.sort(key = len, reverse = True)
1574 for dir in dirs:
1575 try:
1576- print "Removing the directory '%s'." % dir
1577+ print("Removing the directory '%s'." % dir)
1578 os.rmdir(dir)
1579- except OSError, e:
1580+ except OSError as e:
1581 if e.errno == errno.ENOTEMPTY:
1582- print "Directory '%s' not empty; not removing." % dir
1583+ print("Directory '%s' not empty; not removing." % dir)
1584 else:
1585- print >> sys.stderr, str(e)
1586+ print(str(e), file=sys.stderr)
1587 """
1588
1589 uninstaller_file = open(uninstaller_filename, 'w')
1590@@ -227,7 +227,7 @@ for dir in dirs:
1591 uninstaller_file.close()
1592
1593 # Set exec bit for uninstaller
1594- mode = ((os.stat(uninstaller_filename)[ST_MODE]) | 0555) & 07777
1595+ mode = ((os.stat(uninstaller_filename)[ST_MODE]) | 0o555) & 0o7777
1596 os.chmod(uninstaller_filename, mode)
1597
1598 def write_installed_files(self):
1599@@ -242,7 +242,7 @@ for dir in dirs:
1600 try:
1601 for output in self.get_installed_files():
1602 assert "\n" not in output
1603- print >> f, output
1604+ print(output, file=f)
1605 finally:
1606 f.close()
1607
1608@@ -266,7 +266,7 @@ class my_uninstall(distutils.cmd.Command
1609 # Read the list of installed files.
1610 try:
1611 f = open(INSTALLED_FILES_NAME, "r")
1612- except IOError, e:
1613+ except IOError as e:
1614 if e.errno == errno.ENOENT:
1615 log.error("Couldn't open the installation record '%s'. "
1616 "Have you installed yet?" % INSTALLED_FILES_NAME)
1617@@ -289,7 +289,7 @@ class my_uninstall(distutils.cmd.Command
1618 try:
1619 if not self.dry_run:
1620 os.remove(file)
1621- except OSError, e:
1622+ except OSError as e:
1623 log.error(str(e))
1624 # Delete the directories. First reverse-sort the normalized paths by
1625 # length so that child directories are deleted before their parents.
1626@@ -300,7 +300,7 @@ class my_uninstall(distutils.cmd.Command
1627 log.info("Removing the directory '%s'." % dir)
1628 if not self.dry_run:
1629 os.rmdir(dir)
1630- except OSError, e:
1631+ except OSError as e:
1632 if e.errno == errno.ENOTEMPTY:
1633 log.info("Directory '%s' not empty; not removing." % dir)
1634 else:
1635--- a/ndiff/test-scans/anonymize.py
1636+++ b/ndiff/test-scans/anonymize.py
1637@@ -1,4 +1,4 @@
1638-#!/usr/bin/env python
1639+#!/usr/bin/env python3
1640
1641 # Anonymize an Nmap XML file, replacing host name and IP addresses with random
1642 # anonymous ones. Anonymized names will be consistent between runs of the
1643@@ -20,20 +20,20 @@ r = random.Random()
1644
1645
1646 def hash(s):
1647- digest = hashlib.sha512(s).hexdigest()
1648+ digest = hashlib.sha512(s.encode()).hexdigest()
1649 return int(digest, 16)
1650
1651
1652 def anonymize_mac_address(addr):
1653 r.seed(hash(addr))
1654 nums = (0, 0, 0) + tuple(r.randrange(256) for i in range(3))
1655- return u":".join(u"%02X" % x for x in nums)
1656+ return ":".join("%02X" % x for x in nums)
1657
1658
1659 def anonymize_ipv4_address(addr):
1660 r.seed(hash(addr))
1661 nums = (10,) + tuple(r.randrange(256) for i in range(3))
1662- return u".".join(unicode(x) for x in nums)
1663+ return ".".join(str(x) for x in nums)
1664
1665
1666 def anonymize_ipv6_address(addr):
1667@@ -41,7 +41,7 @@ def anonymize_ipv6_address(addr):
1668 # RFC 4193.
1669 nums = (0xFD00 + r.randrange(256),)
1670 nums = nums + tuple(r.randrange(65536) for i in range(7))
1671- return u":".join("%04X" % x for x in nums)
1672+ return ":".join("%04X" % x for x in nums)
1673
1674 # Maps to memoize address and host name conversions.
1675 hostname_map = {}
1676@@ -54,11 +54,11 @@ def anonymize_hostname(name):
1677 LETTERS = "acbdefghijklmnopqrstuvwxyz"
1678 r.seed(hash(name))
1679 length = r.randrange(5, 10)
1680- prefix = u"".join(r.sample(LETTERS, length))
1681+ prefix = "".join(r.sample(LETTERS, length))
1682 num = r.randrange(1000)
1683- hostname_map[name] = u"%s-%d.example.com" % (prefix, num)
1684+ hostname_map[name] = "%s-%d.example.com" % (prefix, num)
1685 if VERBOSE:
1686- print >> sys.stderr, "Replace %s with %s" % (name, hostname_map[name])
1687+ print("Replace %s with %s" % (name, hostname_map[name]), file=sys.stderr)
1688 return hostname_map[name]
1689
1690 mac_re = re.compile(r'\b([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}\b')
1691@@ -78,7 +78,7 @@ def anonymize_address(addr):
1692 else:
1693 assert False
1694 if VERBOSE:
1695- print >> sys.stderr, "Replace %s with %s" % (addr, address_map[addr])
1696+ print("Replace %s with %s" % (addr, address_map[addr]), file=sys.stderr)
1697 return address_map[addr]
1698
1699