source: server/common/oursrc/whoisd/whoisd.tac @ 771

Last change on this file since 771 was 771, checked in by quentin, 16 years ago
Commit local changes from b-m to whoisd
File size: 3.8 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 os, sys, pwd, glob
6
7class WhoisProtocol(basic.LineReceiver):
8    def lineReceived(self, hostname):
9        (key, hostname) = hostname.split('=',2)
10        if key != '0xvVk043ZT61jR1bAlX0JSzM':
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, vhostDir, ldap_URL, ldap_base):
22        self.vhostDir = vhostDir
23        self.ldap_URL = ldap_URL
24        self.ldap = ldap.initialize(self.ldap_URL)
25        self.ldap_base = ldap_base
26        self.vhosts = {}
27        if vhostDir:
28            self.rescanVhosts()
29    def rescanVhosts(self):
30        newVhosts = {}
31        for f in glob.iglob(os.path.join(self.vhostDir, "*.conf")):
32            locker = os.path.splitext(os.path.basename(f))[0]
33            newVhosts.update(self.parseApacheConf(file(f)))
34        self.vhosts = newVhosts
35        self.vhostTime = os.stat(self.vhostDir).st_mtime
36    def parseApacheConf(self, f):
37        vhosts = {}
38        hostnames = []
39        locker = None
40        docroot = None
41        for l in f:
42            parts = l.split()
43            if not parts: continue
44            command = parts.pop(0)
45            if command in ("ServerName", "ServerAlias"):
46                hostnames.extend(parts)
47            elif command in ("SuExecUserGroup",):
48                locker = parts[0]
49            elif command in ("DocumentRoot",):
50                docroot = parts[0]
51            elif command == "</VirtualHost>":
52                d = {'locker': locker, 'apacheDocumentRoot': docroot, 'apacheServerName': hostnames[0]}
53                for h in hostnames: vhosts[h] = d
54                hostnames = []
55                locker = None
56                docroot = None
57        return vhosts
58    def canonicalize(self, vhost):
59        vhost = vhost.lower().rstrip(".")
60        return vhost
61#        if vhost.endswith(".mit.edu"):
62#            return vhost
63#        else:
64#            return vhost + ".mit.edu"
65    def searchLDAP(self, vhost):
66        results = self.ldap.search_s(self.ldap_base, ldap.SCOPE_SUBTREE,
67            ldap.filter.filter_format(
68                '(|(apacheServername=%s)(apacheServerAlias=%s))', (vhost,)*2))
69        if len(results) >= 1:
70            result = results[0]
71            attrs = result[1]
72            for attr in ('apacheServerName','apacheDocumentRoot', 'apacheSuexecUid', 'apacheSuexecGid'):
73                attrs[attr] = attrs[attr][0]
74            user = pwd.getpwuid(int(attrs['apacheSuexecUid']))
75            if user:
76                attrs['locker'] = user.pw_name
77            else:
78                attrs['locker'] = None
79            return attrs
80        else:
81            return None
82    def getWhois(self, vhost):
83        vhost = self.canonicalize(vhost)
84        info = self.vhosts.get(vhost)
85        if not info:
86            info = self.searchLDAP(vhost)
87        if info:
88            ret = "Hostname: %s\nAlias: %s\nLocker: %s\nDocument Root: %s" % \
89                (info['apacheServerName'], vhost, info['locker'], info['apacheDocumentRoot'])
90        else:
91            ret = "No such hostname"
92        return defer.succeed(ret)
93
94application = service.Application('whois', uid=99, gid=99)
95factory = WhoisFactory(None,
96    "ldap://localhost", "ou=VirtualHosts,dc=scripts,dc=mit,dc=edu")
97internet.TCPServer(43, factory).setServiceParent(
98    service.IServiceCollection(application))
Note: See TracBrowser for help on using the repository browser.