extras-buildsys/common FileDownloader.py, 1.3, 1.4 HTTPSURLopener.py, 1.2, 1.3 SSLCommon.py, 1.1, 1.2 SSLXMLRPCServerProxy.py, 1.2, 1.3 SimpleHTTPSServer.py, 1.3, 1.4 SimpleSSLXMLRPCServer.py, 1.2, 1.3
Daniel Williams (dcbw)
fedora-extras-commits at redhat.com
Tue Jun 14 01:16:32 UTC 2005
- Previous message (by thread): extras-buildsys/client buildclient.py,1.6,1.7
- Next message (by thread): extras-buildsys/server User.py, NONE, 1.1 CONFIG.py, 1.6, 1.7 buildmaster.py, 1.4, 1.5 buildserver.py, 1.4, 1.5 client_manager.py, 1.6, 1.7
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: dcbw
Update of /cvs/fedora/extras-buildsys/common
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv21732/common
Modified Files:
FileDownloader.py HTTPSURLopener.py SSLCommon.py
SSLXMLRPCServerProxy.py SimpleHTTPSServer.py
SimpleSSLXMLRPCServer.py
Log Message:
2005-06-13 Dan Williams <dcbw at redhat.com>
* client/buildclient.py
common/FileDownloader.py
common/HTTPSURLopener.py
common/SSLCommon.py
common/SSLXMLRPCServerProxy.py
common/SimpleHTTPSServer.py
common/SimpleSSLXMLRPCServer.py
server/client_manager.py
- Clean up cert handling by stuffing cert file paths into a dict
* common/SSLCommon.py
- QuietSSLServer: new class to quiet certain SSL errors we don't care about
* common/SimpleSSLXMLRPCServer.py
- Add an authorization framework. The actual request gets authorized
in SimpleSSLXMLRPCServer, but since we need to pass the authorization
object back up to the Instance class, we need to override a bunch
of functions in superclasses just to pass the object through. Subclasses
of SimpleSSLXMLRPCServer don't need to use authorization, they just don't
set an auth callback. If authorization is in use, the subclass is asked
to authorize the connection, and passes back an arbitrary authorization
object, which gets passed to each Handler method.
* server/buildmaster.py
server/buildserver.py
- Change buildmaster_db -> jobdb
* server/buildserver.py
- XMLRPCBuildMaster -> UserInterface
- Attach authorization to all public XMLRPC methods
- VerifiableSSLXMLRPCServer: new class to handle request authorization
- Add "guest" user support. If the user's cert checks out but they are not
in the user database, they have read-only permission to the server
* server/User.py
- New User object: encapsulates all permissions that a user might
have.
- New UserAuthentication object: looks up user authentication info in
a user database and creates User objects
* utils/user-manager.py
- Local user administration tool
* utils/package-builder.py
- New CLI front-end to the build system that support XMLRPC over SSL
* utils/certs/fedora-upload-ca.cert
- Fedora CVS Upload CA certificate, required to validate users
Index: FileDownloader.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/FileDownloader.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- FileDownloader.py 10 Jun 2005 01:35:40 -0000 1.3
+++ FileDownloader.py 14 Jun 2005 01:16:30 -0000 1.4
@@ -72,7 +72,7 @@
class FileDownloader(threading.Thread):
- def __init__(self, callback, cb_data, url, target_dir, legal_exts, certfile, keyfile, ca_certfile):
+ def __init__(self, callback, cb_data, url, target_dir, legal_exts, certs):
self._callback = callback
self._cb_data = cb_data
self._url = url
@@ -80,7 +80,7 @@
self._filename = get_base_filename_from_url(self._url, legal_exts)
if not self._filename:
print "Couldn't get base filename from url!! target_dir=%s, url=%s" % (target_dir, url)
- self._opener = HTTPSURLopener.HTTPSURLopener(certfile, keyfile, ca_certfile)
+ self._opener = HTTPSURLopener.HTTPSURLopener(certs)
threading.Thread.__init__(self)
def run(self):
Index: HTTPSURLopener.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/HTTPSURLopener.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- HTTPSURLopener.py 13 Jun 2005 05:12:09 -0000 1.2
+++ HTTPSURLopener.py 14 Jun 2005 01:16:30 -0000 1.3
@@ -23,8 +23,8 @@
import SSLCommon
class HTTPSURLopener(urllib.URLopener):
- def __init__(self, certfile, keyfile, ca_certfile):
- self.ctx = SSLCommon.getSSLContext(certfile, keyfile, ca_certfile)
+ def __init__(self, certs):
+ self.ctx = SSLCommon.getSSLContext(certs)
urllib.URLopener.__init__(self)
def open_https(self, url, data=None):
Index: SSLCommon.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/SSLCommon.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- SSLCommon.py 13 Jun 2005 05:12:09 -0000 1.1
+++ SSLCommon.py 14 Jun 2005 01:16:30 -0000 1.2
@@ -24,19 +24,23 @@
"""
return
-def getSSLContext(certfile, keyfile, ca_certfile, session_id='ssl_session'):
+def getSSLContext(certs, session_id='ssl_session'):
"""
Helper method for m2crypto's SSL libraries.
"""
- for f in certfile, keyfile, ca_certfile:
- if not os.access(f, os.R_OK):
+ cert = certs['cert']
+ key = certs['key']
+ ca_cert = certs['ca_cert']
+ peer_ca_cert = certs['peer_ca_cert']
+ for f in cert, key, ca_cert, peer_ca_cert:
+ if f and not os.access(f, os.R_OK):
print "%s does not exist or is not readable." % f
os._exit(1)
- ctx = SSL.Context('sslv3')
- ctx.load_cert(certfile, keyfile)
- ctx.load_client_ca(ca_certfile)
- ctx.load_verify_info(ca_certfile)
+ ctx = SSL.Context('sslv3') # SSLv3 only
+ ctx.load_cert(cert, key)
+ ctx.load_client_ca(ca_cert)
+ ctx.load_verify_info(peer_ca_cert)
ctx.set_allow_unknown_ca(False)
verify = SSL.verify_peer | SSL.verify_fail_if_no_peer_cert
ctx.set_verify(verify, 10)
@@ -44,3 +48,19 @@
ctx.set_info_callback(quietCallback)
return ctx
+
+class QuietSSLServer(SSL.SSLServer):
+ def handle_request(self):
+ request = None
+ client_address = None
+ try:
+ request, client_address = self.get_request()
+ if self.verify_request(request, client_address):
+ self.process_request(request, client_address)
+ except SSL.SSLError, e:
+ if e.args[0] == "no certificate returned":
+ pass
+ elif e.args[0] == "wrong version number":
+ pass
+ else:
+ self.handle_error(request, client_address)
Index: SSLXMLRPCServerProxy.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/SSLXMLRPCServerProxy.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SSLXMLRPCServerProxy.py 13 Jun 2005 05:12:09 -0000 1.2
+++ SSLXMLRPCServerProxy.py 14 Jun 2005 01:16:30 -0000 1.3
@@ -21,7 +21,7 @@
import SSLCommon
class SSLXMLRPCServerProxy(Server):
- def __init__(self, certfile, keyfile, ca_certfile, uri):
- self.ctx = SSLCommon.getSSLContext(certfile, keyfile, ca_certfile)
+ def __init__(self, certs, uri):
+ self.ctx = SSLCommon.getSSLContext(certs)
Server.__init__(self, uri, SSL_Transport(ssl_context=self.ctx))
Index: SimpleHTTPSServer.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/SimpleHTTPSServer.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SimpleHTTPSServer.py 13 Jun 2005 05:12:09 -0000 1.3
+++ SimpleHTTPSServer.py 14 Jun 2005 01:16:30 -0000 1.4
@@ -73,11 +73,11 @@
class ThreadingHTTPSServer(ThreadingSSLServer):
- def __init__(self, certfile, keyfile, ca_certfile, server_addr, http_dir):
+ def __init__(self, certs, server_addr, http_dir):
self.allow_reuse_address = 1
self.http_dir = http_dir
- self.ctx = SSLCommon.getSSLContext(certfile, keyfile, ca_certfile)
+ self.ctx = SSLCommon.getSSLContext(certs)
ThreadingSSLServer.__init__(self, server_addr, HttpRequestHandler, self.ctx)
self.server_name = server_addr[0]
@@ -91,8 +91,8 @@
class SimpleHTTPSServer(threading.Thread):
- def __init__(self, certfile, keyfile, ca_certfile, addr, http_dir):
- self._server = ThreadingHTTPSServer(certfile, keyfile, ca_certfile, addr, http_dir)
+ def __init__(self, certs, addr, http_dir):
+ self._server = ThreadingHTTPSServer(certs, addr, http_dir)
threading.Thread.__init__(self)
def run(self):
Index: SimpleSSLXMLRPCServer.py
===================================================================
RCS file: /cvs/fedora/extras-buildsys/common/SimpleSSLXMLRPCServer.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SimpleSSLXMLRPCServer.py 13 Jun 2005 05:12:09 -0000 1.2
+++ SimpleSSLXMLRPCServer.py 14 Jun 2005 01:16:30 -0000 1.3
@@ -17,34 +17,141 @@
import os, sys
from M2Crypto import SSL
-from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler, SimpleXMLRPCDispatcher
+import xmlrpclib
+import SimpleXMLRPCServer
import SSLCommon
-class VerifiableSimpleXMLRPCRequestHander(SimpleXMLRPCRequestHandler):
+class AuthedSimpleXMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
def do_POST(self):
"""
- Override request handling to provide the server a chance to verify the client
+ See documentation on SimpleXMLRPCRequestHandler. Modifications
+ include the ability to pass through local request-specific data,
+ and removal of code to deal with historical _dispatch methods.
"""
- accept = True
- if self.server.verify_callback:
- accept = self.server.verify_callback(self.request)
- if accept:
- SimpleXMLRPCRequestHandler.do_POST(self)
+
+ if 0:
+ # ONLY FOR DEBUGGING, so we can see exceptions on the console
+ # get arguments
+ data = self.rfile.read(int(self.headers["content-length"]))
+ authinfo = self.server.get_authinfo(self.request, self.client_address)
+ response = self.server._marshaled_dispatch(data, authinfo)
+
+ # got a valid XML RPC response
+ self.send_response(200)
+ self.send_header("Content-type", "text/xml")
+ self.send_header("Content-length", str(len(response)))
+ self.end_headers()
+ self.wfile.write(response)
+
+ # shut down the connection
+ self.wfile.flush()
+ self.connection.shutdown(1)
else:
- self.server.send_error(403, 'You are not authorized to access this resource.')
+ try:
+ # get arguments
+ data = self.rfile.read(int(self.headers["content-length"]))
+ authinfo = self.server.get_authinfo(self.request, self.client_address)
+ response = self.server._marshaled_dispatch(data, authinfo)
+ except: # This should only happen if the module is buggy
+ # internal error, report as HTTP server error
+ self.send_response(500)
+ self.end_headers()
+ else:
+ # got a valid XML RPC response
+ self.send_response(200)
+ self.send_header("Content-type", "text/xml")
+ self.send_header("Content-length", str(len(response)))
+ self.end_headers()
+ self.wfile.write(response)
+
+ # shut down the connection
+ self.wfile.flush()
+ self.connection.shutdown(1)
-class SimpleSSLXMLRPCServer(SSL.SSLServer, SimpleXMLRPCServer):
+class SimpleSSLXMLRPCServer(SSLCommon.QuietSSLServer, SimpleXMLRPCServer.SimpleXMLRPCServer):
"""
An extension of SimpleXMLRPCServer that allows SSL handling.
"""
- def __init__(self, certfile, keyfile, ca_certfile, address, verify_callback=None):
+ def __init__(self, certs, address, authinfo_callback=None):
self.allow_reuse_address = 1
self.logRequests = 0
- self.verify_callback = verify_callback
+ self.authinfo_callback = authinfo_callback
+
+ SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
+
+ ctx = SSLCommon.getSSLContext(certs)
+ SSLCommon.QuietSSLServer.__init__(self, address, AuthedSimpleXMLRPCRequestHandler, ctx)
+
+ def get_authinfo(self, request, client_address):
+ if self.authinfo_callback:
+ return self.authinfo_callback(request, client_address)
+ return None
- ctx = SSLCommon.getSSLContext(certfile, keyfile, ca_certfile)
- SSL.SSLServer.__init__(self, address, VerifiableSimpleXMLRPCRequestHander, ctx)
+ def verify_request(self, request, client_address):
+ """
+ Allow ourselves a chance to verify the client
+ """
+ if self.authinfo_callback:
+ authinfo = self.get_authinfo(request, client_address)
+ if authinfo:
+ return True
+ return False
- SimpleXMLRPCDispatcher.__init__(self)
+ # Allow all requests if there's no authinfo_callback
+ return True
+
+ def _marshaled_dispatch(self, data, authinfo):
+ """
+ Allow the ability to pass request-dependent objects into
+ the handler instance.
+ """
+ params, method = xmlrpclib.loads(data)
+
+ # generate response
+ try:
+ response = self._dispatch(authinfo, method, params)
+ # wrap response in a singleton tuple
+ response = (response,)
+ response = xmlrpclib.dumps(response, methodresponse=1)
+ except xmlrpclib.Fault, fault:
+ response = xmlrpclib.dumps(fault)
+ except:
+ # report exception back to server
+ response = xmlrpclib.dumps(
+ xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
+ )
+
+ return response
+
+ def _dispatch(self, authinfo, method, params):
+ """
+ Allow the ability to pass request-dependent objects into
+ the handler instance.
+ """
+ func = None
+ try:
+ # check to see if a matching function has been registered
+ func = self.funcs[method]
+ except KeyError:
+ if self.instance is not None:
+ # call instance method directly
+ try:
+ func = SimpleXMLRPCServer.resolve_dotted_attribute(
+ self.instance,
+ method,
+ self.allow_dotted_names
+ )
+ except AttributeError:
+ pass
+
+ if func is not None:
+ # Only pass authinfo into Instance if we have are set
+ # up to get authinfo
+ if self.authinfo_callback is not None:
+ return func(authinfo, *params)
+ else:
+ return func(*params)
+ else:
+ raise Exception('method "%s" is not supported' % method)
- Previous message (by thread): extras-buildsys/client buildclient.py,1.6,1.7
- Next message (by thread): extras-buildsys/server User.py, NONE, 1.1 CONFIG.py, 1.6, 1.7 buildmaster.py, 1.4, 1.5 buildserver.py, 1.4, 1.5 client_manager.py, 1.6, 1.7
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list