[Zodb-checkins] CVS: ZODB3/ZEO/auth - base.py:1.1.2.1 auth_sha.py:1.1.2.3 auth_plaintext.py:1.1.2.3 auth_digest.py:1.1.2.4 __init__.py:1.1.2.3 database.py:NONE

Jeremy Hylton jeremy at zope.com
Fri May 23 18:13:51 EDT 2003


Update of /cvs-repository/ZODB3/ZEO/auth
In directory cvs.zope.org:/tmp/cvs-serv10540/ZEO/auth

Modified Files:
      Tag: ZODB3-auth-branch
	auth_sha.py auth_plaintext.py auth_digest.py __init__.py 
Added Files:
      Tag: ZODB3-auth-branch
	base.py 
Removed Files:
      Tag: ZODB3-auth-branch
	database.py 
Log Message:
A little refactoring, still needs work.

Simplify getExtensionMethods() so that it doesn't need __getattr__().

Create ZEO.auth.base module that defines Client and Database.  The
Client base class simplifies use of methods defined by the
protocol-specific storage class.



=== Added File ZODB3/ZEO/auth/base.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Base classes for defining an authentication protocol.

Database -- abstract base class for password database
Client -- abstract base class for authentication client
"""

import os
import sha

class Client:
    # Subclass should override to list the names of methods that
    # will be called on the server.
    extensions = []

    def __init__(self, stub):
        self.stub = stub
        for m in self.extensions:
            setattr(self.stub, m, self.stub.extensionMethod(m))
    
class Database:
    """Abstracts a password database.

    This class is used both in the authentication process (via
    get_password()) and by client scripts that manage the password
    database file. 

    The password file is a simple, colon-separated text file mapping
    usernames to password hashes. The hashes are SHA hex digests
    produced from the password string.
    """
    
    def __init__(self, filename):
        """Creates a new Database

           filename: a string containing the full pathname of
               the password database file. Must be readable by the user
               running ZEO. Must be writeable by any client script that
               accesses the database."""
        
        self._users = {}
        self.filename = filename
        self.load()
        
    def save(self, fd=None):
        filename = self.filename

        if not fd:
            fd = open(filename, 'w')
        
        for username, hash in self._users.items():
            fd.write('%s:%s\n' % (username, hash))
            
    def load(self):
        filename = self.filename
        if not filename:
            return

        if not os.path.exists(filename):
            return
        
        fd = open(filename)
        for line in fd.readlines():
            username, hash = line[:-1].split(':', 1)
            self._users[username] = hash

    def _store_password(self, username, password):
        self._users[username] = self.hash(password)

    def get_password(self, username):
        """Returns password hash for specified username.

        Callers must check for LookupError, which is raised in
        the case of a non-existent user specified."""
	if not self._users.has_key(username):
            raise LookupError, "No such user: %s" % username
        return self._users[username]
    
    def hash(self, s):
        return sha.new(s).hexdigest()

    def add_user(self, username, password):
        if self._users.has_key(username):
            raise LookupError, "User %s does already exist" % username
        self._store_password(username, password)

    def del_user(self, username):
	if not self._users.has_key(username):
            raise LookupError, "No such user: %s" % username
        del self._users[username]

    def change_password(self, username, password):
        if not self._users.has_key(username):
            raise LookupError, "No such user: %s" % username
        self._store_password(username, password)


=== ZODB3/ZEO/auth/auth_sha.py 1.1.2.2 => 1.1.2.3 ===
--- ZODB3/ZEO/auth/auth_sha.py:1.1.2.2	Mon May 19 13:46:06 2003
+++ ZODB3/ZEO/auth/auth_sha.py	Fri May 23 17:13:20 2003
@@ -11,17 +11,20 @@
 # FOR A PARTICULAR PURPOSE
 #
 ##############################################################################
-"""Implements simple hashed password authentication. The password is stored in
-an SHA hash in the Database. The client sends over the hashed password,
-which is verified by the server.
+"""Implements simple hashed password authentication.
+
+The password is stored in an SHA hash in the Database. The client
+sends over the hashed password, which is verified by the server.
  
 This mechanism offers *very weak network security*; the password
 hash is capturable and the mechanism is vulnerable to trivial replay
-attacks. (See the auth_srp module for a secure mechanism)"""
+attacks. (See the auth_srp module for a secure mechanism).
+"""
 
 import sha
 
 from ZEO.StorageServer import ZEOStorage
+from ZEO.auth.base import Client, Database
 
 class StorageClass(ZEOStorage):
     def auth(self, username, password):
@@ -31,10 +34,8 @@
             return 0
         return self.finish_auth(dbpw == password)
 
-class Client:
-    def __init__(self, stub):
-        self.stub = stub
+class SHAClient(Client):
+    extensions = ["auth"]
 
     def start(self, username, password):
-        method = self.stub.extensionMethod('auth')
-        return method(username, sha.new(password).hexdigest())
+        return self.stub.auth(username, sha.new(password).hexdigest())


=== ZODB3/ZEO/auth/auth_plaintext.py 1.1.2.2 => 1.1.2.3 ===
--- ZODB3/ZEO/auth/auth_plaintext.py:1.1.2.2	Mon May 19 13:46:06 2003
+++ ZODB3/ZEO/auth/auth_plaintext.py	Fri May 23 17:13:20 2003
@@ -20,10 +20,10 @@
 auth_srp module for a secure mechanism)"""
 
 import sha
-import sys
 
 from ZEO.StorageServer import ZEOStorage
 from ZEO.auth import register_module
+from ZEO.auth.base import Client, Database
 
 class StorageClass(ZEOStorage):
     def auth(self, username, password):
@@ -35,12 +35,10 @@
         password = sha.new(password).hexdigest()
         return self.finish_auth(dbpw == password)
     
-class Client:
-    def __init__(self, stub):
-        self.stub = stub
+class PlaintextClient(Client):
+    extensions = ["auth"]
 
     def start(self, username, password):
-        method = self.stub.extensionMethod('auth')
-        return method(username, password)
+        return self.stub.auth(username, password)
 
-register_module('plaintext', StorageClass, Client)
+register_module("plaintext", StorageClass, PlaintextClient, Database)


=== ZODB3/ZEO/auth/auth_digest.py 1.1.2.3 => 1.1.2.4 ===
--- ZODB3/ZEO/auth/auth_digest.py:1.1.2.3	Mon May 19 13:46:06 2003
+++ ZODB3/ZEO/auth/auth_digest.py	Fri May 23 17:13:20 2003
@@ -40,7 +40,7 @@
 import struct
 import time
 
-from ZEO.auth.database import Database
+from ZEO.auth.base import Database, Client
 from ZEO.StorageServer import ZEOStorage
 
 def get_random_bytes(n=8):
@@ -119,21 +119,14 @@
         check = hexdigest("%s:%s" % (h_up, nonce))
         return self.finish_auth(check == response)
 
-class Client:
-    def __init__(self, stub):
-        self.stub = stub
+    extensions = [auth_get_challenge, auth_response]
 
-    def auth_get_challenge(self):
-        m = self.stub.extensionMethod("auth_get_challenge")
-        return m()
+class DigestClient(Client):
+    extensions = ["auth_get_challenge", "auth_response"]
 
-    def auth_response(self, t):
-        m = self.stub.extensionMethod("auth_response")
-        return m(t)
-    
     def start(self, username, password):
         h_up = hexdigest("%s:%s" % (username, password))
-        nonce = self.auth_get_challenge()
+        nonce = self.stub.auth_get_challenge()
         
         resp_dig = hexdigest("%s:%s" % (h_up, nonce))
-        return self.auth_response((username, nonce, resp_dig))
+        return self.stub.auth_response((username, nonce, resp_dig))


=== ZODB3/ZEO/auth/__init__.py 1.1.2.2 => 1.1.2.3 ===
--- ZODB3/ZEO/auth/__init__.py:1.1.2.2	Mon May 19 13:46:06 2003
+++ ZODB3/ZEO/auth/__init__.py	Fri May 23 17:13:20 2003
@@ -12,21 +12,20 @@
 #
 ##############################################################################
 
-from ZEO.auth.database import Database
-
-auth_modules = {}
+_auth_modules = {}
 
 def get_module(name):
     if name == 'sha':
-        from auth_sha import StorageClass, Client
-        return StorageClass, Client, Database
+        from auth_sha import StorageClass, SHAClient, Database
+        return StorageClass, SHAClient, Database
     elif name == 'digest':
-        from auth_digest import StorageClass, Client, DigestDatabase
-        return StorageClass, Client, DigestDatabase
+        from auth_digest import StorageClass, DigestClient, DigestDatabase
+        return StorageClass, DigestClient, DigestDatabase
     else:
-        return auth_modules.get(name)
+        return _auth_modules.get(name)
 
-def register_module(name, storage_class, client, db=Database):
-    if auth_modules.has_key(name):
+def register_module(name, storage_class, client, db):
+    if _auth_modules.has_key(name):
         raise TypeError, "%s is already registred" % name
-    auth_modules[name] = storage_class, client, db
+    _auth_modules[name] = storage_class, client, db
+

=== Removed File ZODB3/ZEO/auth/database.py ===




More information about the Zodb-checkins mailing list