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