source: trunk/server/common/oursrc/whoisd/whoisd.tac @ 2756

Last change on this file since 2756 was 2756, checked in by andersk, 8 years ago
whoisd: Ignore Apache configuration files There is no relevant information there as of r2731.
File size: 3.0 KB
Line 
1from twisted.application import internet, service
2from twisted.internet import protocol, reactor, defer
3from twisted.protocols import basic
4import ldap, ldap.filter
5import pwd
6
7class WhoisProtocol(basic.LineReceiver):
8    def lineReceived(self, hostname):
9        (key, hostname) = hostname.split('=',2)
10        if key != self.factory.key:
11            self.transport.write("Unauthorized to use whois"+"\r\n")
12            self.transport.loseConnection()
13        else:
14            self.factory.getWhois(hostname
15            ).addErrback(lambda _: "Internal error in server"
16            ).addCallback(lambda m:
17                          (self.transport.write(m+"\r\n"),
18                           self.transport.loseConnection()))
19class WhoisFactory(protocol.ServerFactory):
20    protocol = WhoisProtocol
21    def __init__(self, ldap_URL, ldap_base, keyFile):
22        self.ldap_URL = ldap_URL
23        self.ldap = ldap.initialize(self.ldap_URL)
24        self.ldap_base = ldap_base
25        self.key = file(keyFile).read()
26    def canonicalize(self, vhost):
27        vhost = vhost.lower().rstrip(".")
28        return vhost
29#        if vhost.endswith(".mit.edu"):
30#            return vhost
31#        else:
32#            return vhost + ".mit.edu"
33    def searchLDAP(self, vhost):
34        results = self.ldap.search_st(self.ldap_base, ldap.SCOPE_SUBTREE,
35            ldap.filter.filter_format(
36                '(|(apacheServername=%s)(apacheServerAlias=%s))', (vhost,)*2),
37                timeout=5)
38        if len(results) >= 1:
39            result = results[0]
40            attrs = result[1]
41            for attr in ('apacheServerName','apacheDocumentRoot', 'apacheSuexecUid', 'apacheSuexecGid'):
42                attrs[attr] = attrs[attr][0]
43            user = pwd.getpwuid(int(attrs['apacheSuexecUid']))
44            if user:
45                attrs['locker'] = user.pw_name
46            else:
47                attrs['locker'] = None
48            return attrs
49        else:
50            return None
51    def getWhois(self, vhost):
52        vhost = self.canonicalize(vhost)
53        info = None
54        tries = 0
55        while (tries < 3) and not info:
56            tries += 1
57            try:
58                info = self.searchLDAP(vhost)
59                break
60            except (ldap.TIMEOUT, ldap.SERVER_DOWN):
61                self.ldap.unbind()
62                self.ldap = ldap.initialize(self.ldap_URL)
63        if info:
64            ret = "Hostname: %s\nAlias: %s\nLocker: %s\nDocument Root: %s" % \
65                (info['apacheServerName'], vhost, info['locker'], info['apacheDocumentRoot'])
66        elif tries == 3:
67            ret = "The whois server is experiencing problems looking up LDAP records.\nPlease contact scripts@mit.edu for help if this problem persists."
68        else:
69            ret = "No such hostname"
70        return defer.succeed(ret)
71
72application = service.Application('whois', uid=99, gid=99)
73factory = WhoisFactory(
74    "ldap://localhost", "ou=VirtualHosts,dc=scripts,dc=mit,dc=edu", "/etc/whoisd-password")
75internet.TCPServer(43, factory).setServiceParent(
76    service.IServiceCollection(application))
Note: See TracBrowser for help on using the repository browser.