ZServerSSL 0.04

    SYNOPSIS

        **ZServerSSL** is a drop-in (well, almost) enhancement to Zope-2.1.6 
        to enable HTTPS, optionally with X.509 certificate-based 
        authentication. 

        The package also contains an encrypting monitor which provides
        Python-level access to a running Zope instance. 


    DESCRIPTION
        
        In standard operation, ZServerSSL simply provides an HTTPS server for 
        Zope: user names, passwords and data in transit are protected against 
        eavesdropping by SSL.

        With X.509 certificate-based authentication, ZServerSSL removes the 
        need for passwords. 
        
        The system administrator (that's you, the guy who installs/operates 
        Zope ;-) first creates a mapping from *X.509 subject distinguished 
        names* to Zope usernames. A tool is provided for this purpose.
        
        Zope is then started in *remote user mode*, with the HTTPS server 
        configured to *require* an X.509 certificate from the client. When 
        a client connects, the following happens:

            -   SSL handles certificate verification. If no certificate is 
            presented, or if the certificate cannot be verified (e.g., 
            because its CA is unknown), the connection is denied. 
        
            -   If verification is successful, ZServerSSL maps the 
            certificate's subject distinguished name to a Zope username and 
            sets REMOTE_USER accordingly. 

            -   Zope's REMOTE_USER machinery takes care of the rest.
        
        Given valid client certificates and mappings from certificates to
        Zope users, Zope no longer requires passwords. This improves site 
        security by removing the need to store passwords on the Zope site.

        This mode of operation can be adapted to other HTTPS servers like
        Apache+SSL, Roxen+SSL, etc. that perform certificate-based
        authentication.
        

    INSTALLATION

        First, install "M2Crypto":http://www.post1.com/home/ngps/m2. If you
        have the latest 0.05 snapshot, then you are all set. 
        
        If you have M2Crypto 0.04, please make the following fix to a silly 
        logic-reversal bug: at line 105 in M2Crypto/SSL/Connection.py, the 
        method setblocking() should look like this::

            def setblocking(self, mode):
                self.socket.setblocking(mode)
                if mode:
                    self.send = self.write = self._write_bio
                    self.recv = self.read = self._read_bio
                else:
                    self.send = self.write = self._write_nbio
                    self.recv = self.read = self._read_nbio

        In the buggy version, the use of *_bio and *_nbio methods are 
        reversed. This will result in a crash when callbacks are installed 
        while operating in asynchronous socket-I/O mode.

        Next, recursively copy the ZServerSSL files into Zope's top-level 
        directory. The following is a list of the program files in 
        ZServerSSL:

            -   starts: modified start script for Zope

            -   z2s.py: modified Python start-up program for Zope

            -   ZServer/__init__.py: replacement for ZServer's 
            standard __init__.py

            -   ZServer/HTTPS_Server.py: HTTPS server based on 
            HTTPServer.py

            -   ZServer/medusa/https_server.py: HTTPS plumbing for 
            HTTPS_Server.py

            -   ZServer/medusa/m2_monitor.py: encrypting monitor server

            -   ZServer/medusa/m2_monitor_client.py: encrypting monitor 
                client

            -   utilities/x509user.py: tool to manage X.509 to Zope name
                mappings


    RUNNING ZServerSSL

        To start ZServerSSL, use the Unix shell script "starts"::

            ./starts -w '' -m '' -f '' -M '' -W 8443 HTTPS=on

        (Windows users please improvise.)

        This starts a single HTTPS server on port 8443. Connect to it
        with your favourite browser: You are now accessing Zope over 
        SSL.

        Well, you can already do that with Apache+SSL, or IIS, or 
        Roxen+SSL. So now let's look at using X.509 certificate-based
        authentication.


    X.509 CERTIFICATES

        To facilitate testing, I've bundled several X.509 certificates 
        in various formats with the distribution:

            -   ca.pem: demo CA certificate

            -   server.pem: demo certification for the HTTPS server

            -   client.pem: demo user certificate

            -   client2.pem: another demo user certificate

            -   client.p12: client.pem in PKCS #12 format

            -   client2.p12: client2.pem in PKCS #12 format

        All certificates (except the CA certificate) include their 
        corresponding _unencrypted_ private keys. 
        
        The PKCS #12 files are for importing into Netscape Navigator. I 
        have yet to find out how to import user and CA certificates into 
        MSIE. Pointers to information on same are gladly accepted.

        To import the certificates into Navigator, do the following:
        
            -   Click on the "lock" icon at the bottom left corner; this 
            brings up the "Security Info" dialog box. 
            
            -   Click on "Yours" under "Certificates". 
            
            -   Select "Import a certificate", then pick 'client.p12' 
            from the ensuing file selection dialog box. When prompted
            for "import password", just click "Ok".

            -   Associate a local nickname with the certificate; let's 
            call it "superuser".

            -   Repeat for client2.p12; call it "bobo".


    X.509-TO-ZOPE MAPPING

        Now we create the X.509-to-Zope mapping using x509_user.py.

        To read the subject distinguished name from client.pem, invoke 
        'openssl' thusly::
                
            openssl x509 -subject -noout -in client.pem
                
        This produces the following output (broken into two lines
        for readability)::
                
            subject=/C=SG/O=M2Crypto Client/CN=M2Crypto Client/
            Email=ngps@post1.com
                
        If you don't have the 'openssl' binary installed, just execute 
        the following (all on one line)::
                
            x509_user.py -u superuser 
            -x "/C=SG/O=M2Crypto Client/CN=M2Crypto Client/
            Email=ngps@post1.com"
                
        This associates the identity in client.pem to the Zope user 
        'superuser'. The output is written to the file "access_x509".

        Repeat for client2.pem, but associate it with another Zope user, 
        say, 'bobo'. Here's the invocation for x509_user.py::

            x509_user.py -u bobo
            -x "/C=SG/O=M2Crypto/OU=M2Crypto QA/CN=M2Crypto Client 2/
            Email=ngps@post1.com"


    RUNNING ZServerSSL WITH X.509 CERTIFICATE-BASED AUTHENTICATION

        Before we restart Zope, configure it for "remote user" operation:
        Make a backup of Zope's "access" file. Then, change the 
        "superuser" entry in "access" to be as follows::

            superuser:

        Now start ZServerSSL with X.509 certificate-based authentication::

            ./starts -w '' -m '' -f '' -M '' -W 8443 -x access_x509 HTTPS=on

        Take note to provide the correct pathname to "access_x509".

        Connect to your Zope site. When prompted, select the certificate 
        called "superuser". Depending on how talkative your Navigator 
        configuration is, you clear one or more dialog boxes and are 
        presented with Zope's initial screen. Click on "management screen". 
        You should get in straight away. 
        
        To confirm your identity in Zope, invoke the following DTML 
        fragment:

            Who am I? You are <dtml-var AUTHENTICATED_USER>!

        Voila!

        Next create a Zope user called "bobo". Connect with the certificate 
        called "bobo". You are now the Zope AUTHENTICATED_USER "bobo".


    ENCRYPTING MONITOR

        The encrypting monitor (emonitor) is not SSL - it simply wraps the 
        regular monitor's socket I/O with a stream cipher, like Sam Rushing's 
        original encrypting monitor. Emonitor uses M2Crypto's (i.e., 
        OpenSSL's) cipher implementations; the default cipher is Blowfish 
        CFB.

        Emonitor is being deprecated; it hardcodes initialisation vectors 
        (IVs) for its cipher, a practice of dubious security value. 

        I intend to build an encrypting monitor based on SSL. Realistically, 
        this will only happen when I figure out what I can do with 
        monitor-access to a running Zope instance. Again, pointers to 
        HOW-TOs are welcome.

    
    BUGS

        ZServerSSL is very simple, since all the heavy lifting is done 
        by Zope and Medusa. Bugs are more likely to be found in the 
        crypto/SSL plumbing provided by M2Crypto.


    LICENSE

        ZServerSSL is based heavily on ZServer. I assert copyright on my 
        original code. The package is released under the ZPL; indeed, in 
        several files DC's boiler plate copyright notice remain.

    
    AUTHOR

        Ng Pheng Siong <ngps@post1.com>, 25 Apr 2000


