[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[minion-cvs] Add code to setup serverinbox and serverlist and cache ...



Update of /home/minion/cvsroot/src/minion/lib/mixminion/directory
In directory moria.mit.edu:/tmp/cvs-serv4566/lib/mixminion/directory

Modified Files:
	Directory.py ServerInbox.py 
Log Message:
Add code to setup serverinbox and serverlist and cache files

(At first, I thought this code would be unnecessary, since I'd be able to
 get the directories right with just a few mkdirs and chowns and chmods.
 Judging by the time this stuff took to right, automating it may have been
 a good choice.)



Index: Directory.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/directory/Directory.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Directory.py	25 May 2003 21:57:05 -0000	1.1
+++ Directory.py	25 May 2003 23:11:43 -0000	1.2
@@ -7,16 +7,144 @@
 
    """
 
-__all__ = [ 'ServerList', 'MismatchedID' ]
+__all__ = [ 'ServerList', 'MismatchedID', 'DirectoryConfig', 'Directory' ]
 
 import os
+import stat
 
-import mixminion.Config
+import mixminion.Config as C
 import mixminion.Crypto
 
 from mixminion.Common import LOG, MixError, MixFatalError, UIError, \
      formatBase64, writePickled, readPickled
 
+class Directory:
+    def __init__(self, config):
+        self.config = config
+        self.location = config['Directory-Store']['Homedir']
+        self.inboxBase = os.path.join(self.location, "inbox")
+        self.directoryBase = os.path.join(self.location, "dir")
+        self.cacheFile = os.path.join(self.location, "identity_cache")
+        self.cache = None
+        self.inbox = None
+        self.serverList = None
+         
+    def setupDirectories(self):
+        me = os.getuid()
+        roledict = { 0: "root",
+                     self.config.dir_uid: "dir",
+                     self.config.cgi_uid: "cgi",
+                     }
+        role = roledict.get(me, "other")
+        if role in ("other","cgi"):
+            raise MixFatalError("Only the directory user or root can set up"
+                                " the directory.")
+
+        ib = self.inboxBase
+        join = os.path.join
+
+        dir_uid = self.config.dir_uid
+        dir_gid = self.config.dir_gid
+        cgi_gid = self.config.cgi_gid
+        
+        
+        for fn, uid, gid, mode, recurse in [
+            (self.location,       dir_uid, cgi_gid, 0750, 1),
+            (self.directoryBase,  dir_uid, dir_gid, 0700, 0),
+            (ib,                  dir_uid, cgi_gid, 0750, 0),
+            (join(ib, "new"),     dir_uid, cgi_gid, 0770, 0),
+            (join(ib, "reject"),  dir_uid, cgi_gid, 0770, 0),
+            (join(ib, "updates"), dir_uid, cgi_gid, 0770, 0), ]:
+
+            if not os.path.exists(fn):
+                if recurse:
+                    os.makedirs(fn, mode)
+                else:
+                    os.mkdir(fn, mode)
+            _set_uid_gid_mode(fn, dir_uid, cgi_gid, 0640)
+
+        if not os.path.exists(self.cacheFile):
+            self.cache = IDCache(self.cacheFile)
+            self.cache.emptyCache()
+            self.cache.save()
+
+        self._setCacheMode()
+
+    def getIDCache(self):
+        if not self.cache:
+            self.cache = IDCache(self.cacheFile)
+        return self.cache
+
+    def _setCacheMode(self):
+        _set_uid_gid_mode(self.cacheFile,
+                          self.config.dir_uid,
+                          self.config.cgi_gid,
+                          0640)
+
+    def getServerList(self):
+        if not self.serverList:
+            from mixminion.directory.ServerList import ServerList
+            self.serverList = ServerList(self.directoryBase, self.getIDCache())
+        return self.serverList
+
+    def getInbox(self):
+        if not self.inbox:
+            from mixminion.directory.ServerInbox import ServerInbox
+            self.inbox = ServerInbox(self.inboxBase, self.getIDCache())
+        return self.inbox
+            
+class DirectoryConfig(C._ConfigFile):
+    _restrictFormat = 1
+    _restrictKeys = 1
+    _syntax = {
+        'Host' : C.ClientConfig._syntax['Host'],
+        "Directory-Store" : {
+           "Homedir" : ('REQUIRE', None, None),
+           "DirUser" : ('REQUIRE', None, None),
+           "CGIUser" : ('REQUIRE', None, None),
+           "CGIGroup" : ('REQUIRE', None, None),
+        } }
+    def __init__(self, filename=None, string=None):
+        C._ConfigFile.__init__(self, filename, string)
+
+    def validate(self, lines, contents):
+        import pwd
+        import grp
+        ds_sec = self['Directory-Store']
+        diruser = ds_sec['DirUser'].strip()
+        cgiuser = ds_sec['CGIUser'].strip()
+        cgigrp = ds_sec['CGIGroup'].strip()
+
+        try:
+            dir_pwent = pwd.getpwname(diruser)
+        except KeyError:
+            raise C.ConfigError("No such user: %r"%diruser)
+        try:
+            cgi_pwent = pwd.getpwname(cgiuser)
+        except KeyError:
+            raise C.ConfigError("No such user: %r"%cgiuser)
+        try:
+            cgi_grpent = grp.getgrnam(cgigrp)
+        except KeyError:
+            raise C.ConfigError("No such group: %r"%cgigrp)
+
+        self.dir_uid = dir_pwent[2]
+        self.dir_grp = dir_pwent[3]
+        self.cgi_uid = cgi_pwent[2]
+        self.cgi_gid = cgi_grpent[2]
+
+        groupMembers = cgi_grpent[3][:]
+        for pwent in (dir_pwent, cgi_pwent):
+            if pwent[3] == self.cgi_gid:
+                groupMembers.append(pwent[0])
+
+        if self.dir_uid not in groupMembers:
+            raise C.ConfigError("User %s is not in group %s"
+                                %(diruser, cgigrp))
+        if self.cgi_uid not in groupMembers:
+            raise C.ConfigError("User %s is not in group %s"
+                                %(cgiuser, cgigrp))
+
 class MismatchedID(Exception):
     pass
 
@@ -27,6 +155,10 @@
         self.dirty = 0
         self.cache = None
 
+    def emptyCache(self):
+        self.dirty = 1
+        self.cache = {}
+
     def containsID(self, nickname, ID):
         nickname = nickname.lower()
         try:
@@ -64,7 +196,6 @@
         self.cache[lcnickname] = ID
 
     def insertServer(self, server):
-        key = server.getIdentity()
         nickname = server.getNickname()
         ID = getIDFingerprint(server)
         self.insertID(nickname, ID)
@@ -95,12 +226,19 @@
     def save(self):
         writePickled(self.location,
                      ("V0", self.cache),
-                     0644)
+                     0640)
         self.dirty = 0
             
 def getIDFingerprint(server):
     """DOCDOC"""
     ident = server.getIdentity()
-    return formatBase64(
-        mixminion.Crypto.sha1(
-             mixminion.Crypto.pk_encode_public_key(ident)))
+    return mixminion.Crypto.sha1(
+        mixminion.Crypto.pk_encode_public_key(ident))
+
+def _set_uid_gid_mode(fn, uid, gid, mode):
+    st = os.stat(fn)
+    if st[stat.ST_UID] != uid or st[stat.ST_GID] != gid:
+        os.chown(fn, uid, gid)
+    if (st[stat.ST_MODE] & 0777) != mode:
+        os.chmod(fn, mode)
+    

Index: ServerInbox.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/directory/ServerInbox.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ServerInbox.py	25 May 2003 21:57:05 -0000	1.1
+++ ServerInbox.py	25 May 2003 23:11:43 -0000	1.2
@@ -9,10 +9,12 @@
 
 __all__ = [ 'ServerInbox' ]
 
-from mixminion.Common import LOG, MixErrror, MixFatalError, UIError, \
-     readPickled, writePickled, 
+import os
 
-from mixminion.directory.Directory import getIDFingerprint
+from mixminion.Common import LOG, MixError, MixFatalError, UIError, \
+     readPickled, writePickled
+
+from mixminion.directory.Directory import getIDFingerprint, MismatchedID
 from mixminion.directory.ServerList import _writeServer, _readServer
 
 class ServerInbox:
@@ -39,7 +41,7 @@
 
         try:
             known = self.idCache.containsServer(nickname)
-        except mixminion.directory.Directory.MismatchedID:
+        except MismatchedID:
             LOG.warn("Rejected server with mismatched identity from %s",
                      source)
             self.updateQueue.queueRejectedServer(text,server)
@@ -64,7 +66,7 @@
                 serverList.importServerInfo(text,server=server,
                                             knownOnly=knownOnly)
                 accepted.append(fname)
-            except (MixError, config), e:
+            except MixError, e:
                 LOG.warn("ServerList refused to include server %s: %s",
                          fname, e)
                 reject.append((fname,server,text,fp))
@@ -178,7 +180,7 @@
             path = os.path.join(self.incomingDir,fname)
             try:
                 text, server = _readServer(path)
-            except (ConfigError, MixError),e:
+            except MixError, e:
                 os.unlink(path)
                 LOG.warn("Removed a bad server descriptor %s from incoming dir: %s",
                          fname, e)