"""
SecureXMLRPCServer module using pyOpenSSL 0.5
Written 0907.2002
by Michal Wallace
http://www.sabren.net/

This acts exactly like SimpleXMLRPCServer
from the standard python library, but
uses secure connections. The technique
and classes should work for any SocketServer
style server. However, the code has not
been extensively tested.

This code is in the public domain.
It is provided AS-IS WITH NO WARRANTY WHATSOEVER.
"""

import SimpleXMLRPCServer
import SocketServer
import os
import socket

from OpenSSL import SSL


class SSLWrapper:
    """
    This whole class exists just to filter out a parameter
    passed in to the shutdown() method in SimpleXMLRPC.doPOST()
    """
    def __init__(self, conn):
        """
        Connection is not yet a new-style class,
        so I'm making a proxy instead of subclassing.
        """
        self.__dict__["conn"] = conn

    def __getattr__(self, name):
        return getattr(self.__dict__["conn"], name)

    def __setattr__(self, name, value):
        setattr(self.__dict__["conn"], name, value)

    def shutdown(self, how=1):
        """
        SimpleXMLRpcServer.doPOST calls shutdown(1),
        and Connection.shutdown() doesn't take
        an argument. So we just discard the argument.
        """
        self.__dict__["conn"].shutdown()

    def accept(self):
        """
        This is the other part of the shutdown() workaround.
        Since servers create new sockets, we have to infect
        them with our magic. :)
        """
        c, a = self.__dict__["conn"].accept()
        return (SSLWrapper(c), a)


class SecureTCPServer(SocketServer.TCPServer):
    """
    Just like TCPServer, but use a socket.
    This really ought to let you specify the key and certificate files.
    """
    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.BaseServer.__init__(
            self, server_address, RequestHandlerClass
        )

        # Same as normal, but make it secure:
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.set_options(SSL.OP_NO_SSLv2)

        dir = os.curdir
        ctx.use_privatekey_file(os.path.join(dir, 'server.pkey'))
        ctx.use_certificate_file(os.path.join(dir, 'server.cert'))

        self.socket = SSLWrapper(
            SSL.Connection(
                ctx, socket.socket(self.address_family, self.socket_type)
            )
        )
        self.server_bind()
        self.server_activate()


class SecureXMLRPCRequestHandler(
        SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
    def setup(self):
        """
        We need to use socket._fileobject Because SSL.Connection
        doesn't have a 'dup'. Not exactly sure WHY this is, but
        this is backed up by comments in socket.py and SSL/connection.c
        """
        self.connection = self.request  # for doPOST
        self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
        self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)


class SecureXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer,
                         SecureTCPServer):
    def __init__(self, addr,
                 requestHandler=SecureXMLRPCRequestHandler,
                 logRequests=1):
        """
        This is the exact same code as SimpleXMLRPCServer.__init__
        except it calls SecureTCPServer.__init__ instead of plain
        old TCPServer.__init__
        """
        self.funcs = {}
        self.logRequests = logRequests
        self.instance = None
        SecureTCPServer.__init__(self, addr, requestHandler)
