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

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