Merge lp:~mgorven/ibid/port-numbers into lp:~ibid-core/ibid/old-trunk-1.6

Proposed by Michael Gorven
Status: Merged
Approved by: Stefano Rivera
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~mgorven/ibid/port-numbers
Merge into: lp:~ibid-core/ibid/old-trunk-1.6
Diff against target: 105 lines (+72/-2)
2 files modified
ibid/plugins/network.py (+71/-1)
ibid/plugins/sysadmin.py (+1/-1)
To merge this branch: bzr merge lp:~mgorven/ibid/port-numbers
Reviewer Review Type Date Requested Status
Stefano Rivera Approve
Keegan Carruthers-Smith Approve
marcog (community) Approve
Ibid Core Team Pending
Max Rabkin Pending
Review via email: mp+19260@code.launchpad.net

This proposal supersedes a proposal from 2010-02-09.

To post a comment you must log in.
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

Simple port/protocol lookup using /etc/services.

Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) wrote : Posted in a previous version of this proposal

Looks good

review: Approve
Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

Are comments in /etc/services guaranteed to be at the start of the
line or be preceded by whitespace? On Debian, /etc/services points to
/usr/share/nmap/nmap-services for a more complete list. Perhaps we
should use that if it's available? Unfortunately, it's in a slightly
different format from /etc/services (it has an open probability where
/etc/services has aliases).

If the answer to my questions are yes and no, then it looks good.

Review: Approve

Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) wrote : Posted in a previous version of this proposal

> Are comments in /etc/services guaranteed to be at the start of the
> line or be preceded by whitespace?
No, they also occur after an entry but the code correctly deals with that.

Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

Also, specifying a transport should be optional (bot should reply to
"port 25" with "smtp on TCP", or something like that.

Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

* Use Nmap's services file if it exists
* Make TCP/UDP optional when asking about port numbers
* Handle SCTP as well

Revision history for this message
Max Rabkin (max-rabkin) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

Moved to network plugin and tweaked portfor regex.

Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

> from collections import defaultdict

Get that from ibid.compat

More review coming when I look at it properly

Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

I'm not convinced that this needs to be cached from load time. Generating the dict on use would save memory. But that's a more general issue, not specific to this plugin.

ICMP ports?

Query: usage ports
Response: I don't know about that protocol
Query: help ports
Response: I don't know about that protocol

review: Needs Fixing
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

> ICMP ports?

The services files doesn't have that information, and it would be used
extremely rarely.

Revision history for this message
Michael Gorven (mgorven) wrote :

Fix masking of help plugin, and only load services file during first request.

Revision history for this message
marcog (marco-gallotta) wrote :

Query: port for http
Response: 80/tcp and 80/udp
Query: port 80
Response: http (TCP) and http (UDP)

Perhaps group them if the protocol is the same?

Query: port for http
Response: 80 (tcp and udp)
Query: port 80
Response: http (TCP and UDP)

The one response uses / and the other uses (), perhaps they should match. The case should also match.

Query: X11:1 port
Response: I don't know about that protocol
Query: port 6001
Response: X11:1 (TCP)

?

review: Needs Fixing
lp:~mgorven/ibid/port-numbers updated
893. By Michael Gorven

Fix case sensitivity in protocol name lookup.

894. By Michael Gorven

Display transport consistently.

Revision history for this message
Michael Gorven (mgorven) wrote :

> The one response uses / and the other uses (), perhaps they should match.
> The case should also match.

r894

> Query: X11:1 port
> Response: I don't know about that protocol

r893

Revision history for this message
Michael Gorven (mgorven) wrote :

> Perhaps group them if the protocol is the same?

Not really worth the effort IMHO.

Revision history for this message
marcog (marco-gallotta) :
review: Approve
Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) :
review: Approve
Revision history for this message
Stefano Rivera (stefanor) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ibid/plugins/network.py'
2--- ibid/plugins/network.py 2010-01-29 23:33:18 +0000
3+++ ibid/plugins/network.py 2010-02-13 09:40:30 +0000
4@@ -3,11 +3,13 @@
5
6 import re
7 import socket
8+from ibid.compat import defaultdict
9 from httplib import HTTPConnection, HTTPSConnection
10+from os.path import exists
11 from subprocess import Popen, PIPE
12+from sys import version_info
13 from urllib import getproxies_environment
14 from urlparse import urlparse
15-from sys import version_info
16
17 try:
18 from dns.resolver import Resolver, NoAnswer, NXDOMAIN
19@@ -431,4 +433,72 @@
20
21 event.addresponse(u"ISO doesn't know about any TLD for %s", location)
22
23+help['ports'] = u'Looks up port numbers for protocols'
24+class Ports(Processor):
25+ u"""port for <protocol>
26+ (tcp|udp) port <number>"""
27+ feature = 'ports'
28+ priority = 10
29+
30+ services = Option('services', 'Path to services file', '/etc/services')
31+ nmapservices = Option('nmap-services', "Path to Nmap's services file", '/usr/share/nmap/nmap-services')
32+ protocols = {}
33+ ports = {}
34+
35+ def setup(self):
36+ self.filename = None
37+ if exists(self.nmapservices):
38+ self.filename = self.nmapservices
39+ self.nmap = True
40+ elif exists(self.services):
41+ self.filename = self.services
42+ self.nmap = False
43+
44+ if not self.filename:
45+ raise Exception(u"Services file doesn't exist")
46+
47+ def _load_services(self):
48+ if self.protocols:
49+ return
50+
51+ self.protocols = defaultdict(list)
52+ self.ports = defaultdict(list)
53+ f = open(self.filename)
54+ for line in f.readlines():
55+ parts = line.split()
56+ if parts and not parts[0].startswith('#') and parts[0] != 'unknown':
57+ number, transport = parts[1].split('/')
58+ port = '%s (%s)' % (number, transport.upper())
59+ self.protocols[parts[0].lower()].append(port)
60+ self.ports[parts[1]].append(parts[0])
61+ if not self.nmap:
62+ for proto in parts[2:]:
63+ if proto.startswith('#'):
64+ break
65+ self.protocols[proto.lower()].append(port)
66+
67+ @match(r'^(?:(.+)\s+)?ports?(?:\s+numbers?)?(?(1)|\s+for\s+(.+))$')
68+ def portfor(self, event, proto1, proto2):
69+ self._load_services()
70+ protocol = (proto1 or proto2).lower()
71+ if protocol in self.protocols:
72+ event.addresponse(human_join(self.protocols[protocol]))
73+ else:
74+ event.addresponse(u"I don't know about that protocol")
75+
76+ @match(r'^(?:(udp|tcp|sctp)\s+)?port\s+(\d+)$')
77+ def port(self, event, transport, number):
78+ self._load_services()
79+ results = []
80+ if transport:
81+ results.extend(self.ports.get('%s/%s' % (number, transport.lower()), []))
82+ else:
83+ for transport in ('tcp', 'udp', 'sctp'):
84+ results.extend('%s (%s)' % (protocol, transport.upper()) for protocol in self.ports.get('%s/%s' % (number, transport.lower()), []))
85+
86+ if results:
87+ event.addresponse(human_join(results))
88+ else:
89+ event.addresponse(u"I don't know about any protocols using that port")
90+
91 # vi: set et sta sw=4 ts=4:
92
93=== modified file 'ibid/plugins/sysadmin.py'
94--- ibid/plugins/sysadmin.py 2010-01-18 23:20:33 +0000
95+++ ibid/plugins/sysadmin.py 2010-02-13 09:40:30 +0000
96@@ -1,8 +1,8 @@
97 # Copyright (c) 2009-2010, Michael Gorven, Stefano Rivera
98 # Released under terms of the MIT/X/Expat Licence. See COPYING for details.
99
100+import os
101 from subprocess import Popen, PIPE
102-import os
103
104 from ibid.plugins import Processor, match
105 from ibid.config import Option

Subscribers

People subscribed via source and target branches