From 0c97a66c15226197468654b83e19c79015dcf5d7 Mon Sep 17 00:00:00 2001 From: Joey Hagedorn Date: Fri, 13 Jul 2007 17:41:12 +0000 Subject: adding new testing XML-RPC client/server code git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@3437 ce84e21b-d406-0410-9b95-82705330c041 --- src/lib/Server/Reports/reports/models.py | 29 +++++++++- src/lib/simpleclient.py | 32 +++++++++++ src/lib/simpleserver.py | 95 +++++++++++++++++++++++++++++++ src/lib/verifierDB | Bin 0 -> 12288 bytes 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/lib/simpleclient.py create mode 100644 src/lib/simpleserver.py create mode 100644 src/lib/verifierDB diff --git a/src/lib/Server/Reports/reports/models.py b/src/lib/Server/Reports/reports/models.py index b54d83912..6e56e6227 100644 --- a/src/lib/Server/Reports/reports/models.py +++ b/src/lib/Server/Reports/reports/models.py @@ -57,12 +57,39 @@ class Client(models.Model): class Admin: pass +#sql to add "profile" class Metadata(models.Model): - '''insert magical interface to client metadata here''' + '''This is a mirror of clients.xml file, versioned by time''' + '''Generally, you look for the latest timestamp for a given client''' client = models.ForeignKey(Client) + profile = models.ForeignKey(Group) timestamp = models.DateTimeField() + expiration = models.DateTimeField()#Set when group of given name disappears + + def __str__(self): + return self.timestamp + +#SQL to add everything here +class Group(models.Model): + '''this is a mirror of groups.xml''' + '''generally, look for latest timestampf for a givenname that is not expired''' + name = models.CharField(maxlength=128) + groups = models.ManyToManyField(Group, related_name="containing_groups") + bundles = models.ManyToManyField(Bundle, related_name="containing_groups") + timestamp = models.DateTimeField() + expiration = models.DateTimeField()#Set when group of given name disappears + is_profile = models.BooleanField() + def __str__(self): return self.timestamp + +#SQL to add all of this tooooo +class Bundle(models.Model): + name = models.CharField(maxlength=128) + def __str__(self): + return self.timestamp + + class Repository(models.Model): '''insert magical interface to subversioned repository here''' diff --git a/src/lib/simpleclient.py b/src/lib/simpleclient.py new file mode 100644 index 000000000..2840ea4eb --- /dev/null +++ b/src/lib/simpleclient.py @@ -0,0 +1,32 @@ +from tlslite.api import XMLRPCTransport +from xmlrpclib import ServerProxy +from tlslite.integration.ClientHelper import ClientHelper + +#Authenticate server based on its X.509 fingerprint +class DTXMLRPCTransport(XMLRPCTransport, ClientHelper): + def __init__(self, + username=None, password=None, sharedKey=None, + certChain=None, privateKey=None, + cryptoID=None, protocol=None, + x509Fingerprint=None, + x509TrustList=None, x509CommonName=None, + settings=None, + use_datetime=0): + self._use_datetime = use_datetime #this looks like a bug in tlslite. Perhaps just add this over there. + ClientHelper.__init__(self, + username, password, sharedKey, + certChain, privateKey, + cryptoID, protocol, + x509Fingerprint, + x509TrustList, x509CommonName, + settings) + +#sha1 fingerprint: ea38c8b6f73b5df8d77bf1e16652d9b8757a7310 +serverFingerprint = "ea38c8b6f73b5df8d77bf1e16652d9b8757a7310" + +transport = DTXMLRPCTransport(username="name", password="secret",x509Fingerprint=serverFingerprint.lower()) +server = ServerProxy("https://localhost:8505", transport) + +#print server.system.listMethods() + +print(server.silly("Kerbapp 1!")) \ No newline at end of file diff --git a/src/lib/simpleserver.py b/src/lib/simpleserver.py new file mode 100644 index 000000000..63f07d71d --- /dev/null +++ b/src/lib/simpleserver.py @@ -0,0 +1,95 @@ +from SocketServer import * +from SimpleXMLRPCServer import * +from tlslite.api import * +#from Bcfg2.tlslite.api import * + +s = open("./serverX509Cert.pem").read() +x509 = X509() +x509.parse(s) +certChain = X509CertChain([x509]) +s = open("./serverX509Key.pem").read() +privateKey = parsePEMKey(s, private=True) + +sessionCache = SessionCache() + +class MyHTTPServer(ThreadingMixIn, TLSSocketServerMixIn, SimpleXMLRPCServer): + db = VerifierDB("./verifierDB") + db.open() + + def handshake(self, tlsConnection): + try: + tlsConnection.handshakeServer(certChain=certChain, + privateKey=privateKey, + verifierDB=self.db, + sessionCache=sessionCache) + tlsConnection.ignoreAbruptClose = True + return True + except TLSError, error: + print "Handshake failure:", str(error) + return False + +class TLSXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): + '''TLSXMLRPCRequestHandler overrides SimpleXMLRPCRequestHandler to close + connections without causing problems. (just the do_POST() is broken)''' + def do_POST(self): + """Handles the HTTP POST request. + + Attempts to interpret all HTTP POST requests as XML-RPC calls, + which are forwarded to the server's _dispatch method for handling. + """ + + # Check that the path is legal + if not self.is_rpc_path_valid(): + self.report_404() + return + + try: + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + max_chunk_size = 10*1024*1024 + size_remaining = int(self.headers["content-length"]) + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + L.append(self.rfile.read(chunk_size)) + size_remaining -= len(L[-1]) + data = ''.join(L) + + # In previous versions of SimpleXMLRPCServer, _dispatch + # could be overridden in this class, instead of in + # SimpleXMLRPCDispatcher. To maintain backwards compatibility, + # check to see if a subclass implements _dispatch and dispatch + # using that method if present. + response = self.server._marshaled_dispatch( + data, getattr(self, '_dispatch', None) + ) + 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() + #THIS IS THE ONLY MODIFICATION FROM SimpleXMLRPCRequestHandler's IMPLEMENTATION: + #self.connection.shutdown(1) + self.connection.close() + + +def silly(arg="string"): + print arg + return arg[::-1] + + +httpd = MyHTTPServer(('localhost', 8505), TLSXMLRPCRequestHandler) +httpd.register_introspection_functions() +httpd.register_function(silly) +httpd.serve_forever() diff --git a/src/lib/verifierDB b/src/lib/verifierDB new file mode 100644 index 000000000..ef28f3912 Binary files /dev/null and b/src/lib/verifierDB differ -- cgit v1.2.3-1-g7c22