Skip to content

Commit 7b66e04

Browse files
author
Dariusz Suchojad
committed
SESPRINGPYTHONPY-155: Adding docs.
1 parent 01ac92d commit 7b66e04

1 file changed

Lines changed: 194 additions & 1 deletion

File tree

docs/sphinx/source/remoting.rst

Lines changed: 194 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,197 @@ index to increment and roll over. If a service doesn't appear to be reachable,
450450
it is deleted from the list and attempted again. A little more sophisticated
451451
error handling should be added in case there are no services available. And
452452
there needs to be a way to grow the services. But this gets us off to a good
453-
start.
453+
start.
454+
455+
Secure XML-RPC
456+
--------------
457+
458+
.. highlight:: python
459+
460+
Spring Python extends Python’s built-in XML-RPC mechanims by adding the
461+
support for securing the communications path. You can choose whether to:
462+
463+
* simply encrypt the link,
464+
* have server require a client certificate signed off by a given CA or a chain of CAs,
465+
* validate the client certificate’s fields, for instance you can configure the server
466+
to only allow requests if a commonName is equal to an upon agreed value
467+
468+
Encrypted connection only
469+
+++++++++++++++++++++++++
470+
471+
.. image:: gfx/sslxmlrpc-01.png
472+
:align: center
473+
474+
The most basic setup which requires the server to have a private key and
475+
a certificate and the client to have a list (possibly consisting of one
476+
element only) of Certificate Authorities it is allowed to trust. Client will
477+
connect to server only if the server’s certificate has been signed off by given
478+
CAs. This is the most common way of performing SSL akin to what browsers do when
479+
connecting to secure online sites that don’t require a client certificate such
480+
as the majority of online banking sites.
481+
482+
In the code below the server exposes a Python’s built-in pow function over
483+
encrypted XML-RPC link and the client invokes it to get the result. Server
484+
uses its private key and a certificate which must have been signed off by
485+
one of CAs the client is aware of::
486+
487+
# -*- coding: utf-8 -*-
488+
489+
# Spring Python
490+
from springpython.remoting.xmlrpc import SSLXMLRPCServer
491+
492+
class MySSLServer(SSLXMLRPCServer):
493+
def __init__(self, *args, **kwargs):
494+
super(MySSLServer, self).__init__(*args, **kwargs)
495+
496+
def register_functions(self):
497+
self.register_function(pow)
498+
499+
host = "localhost"
500+
port = 8000
501+
key = "./server-key.pem"
502+
cert = "./server-cert.pem"
503+
504+
server = MySSLServer(host, port, key, cert)
505+
server.serve_forever()
506+
507+
::
508+
509+
# -*- coding: utf-8 -*-
510+
511+
# Spring Python
512+
from springpython.remoting.xmlrpc import SSLXMLRPCClient
513+
514+
server_location = "https://localhost:8000/RPC2"
515+
ca_certs = "./cacert.pem"
516+
517+
client = SSLXMLRPCClient(server_location, ca_certs=ca_certs)
518+
519+
print client.pow(41, 3)
520+
521+
Server requires the client to have a certificate
522+
++++++++++++++++++++++++++++++++++++++++++++++++
523+
524+
.. image:: gfx/sslxmlrpc-02.png
525+
:align: center
526+
527+
Same as above but this time the client must authenticate itself using its
528+
own certificate which must have been signed off by one of CAs known to the server.
529+
Server is still required to have a certificate whose signing CAs need to be
530+
known to the client::
531+
532+
# -*- coding: utf-8 -*-
533+
534+
# Spring Python
535+
from springpython.remoting.xmlrpc import SSLXMLRPCServer
536+
537+
# PyOpenSSL
538+
from OpenSSL import SSL
539+
540+
class MySSLServer(SSLXMLRPCServer):
541+
def __init__(self, *args, **kwargs):
542+
super(MySSLServer, self).__init__(*args, **kwargs)
543+
544+
def register_functions(self):
545+
self.register_function(pow)
546+
547+
host = "localhost"
548+
port = 8000
549+
key = "./server-key.pem"
550+
cert = "./server-cert.pem"
551+
ca_certs = "./cacert.pem"
552+
553+
server = MySSLServer(host, port, key, cert, ca_certs, verify_options=SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT)
554+
server.serve_forever()
555+
556+
::
557+
558+
# -*- coding: utf-8 -*-
559+
560+
# Spring Python
561+
from springpython.remoting.xmlrpc import SSLXMLRPCClient
562+
563+
server_location = "https://localhost:8000/RPC2"
564+
key = "./client-key.pem"
565+
cert = "./client-cert.pem"
566+
ca_certs = "./cacert.pem"
567+
568+
client = SSLXMLRPCClient(server_location, key_file=key, cert_file=cert, ca_certs=ca_certs)
569+
570+
print client.pow(41, 3)
571+
572+
Server requires the client to have a certificate and checks its fields
573+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
574+
575+
.. image:: gfx/sslxmlrpc-03.png
576+
:align: center
577+
578+
Same as above (both sides need to have certificates signed off by trusted CAs)
579+
but this time the server inspects the client certificate’s fields and lets it
580+
in only they match the configuration it was fed with. In the example below
581+
*commonName* must be *Client*, *Organization* must be *The Sample Company* and the
582+
*State* must be *New York*. Server checks for both their existance and value and
583+
if there’s any mismatch the connection won’t be established in which case the
584+
error reason will be logged on the server side but no details of the error
585+
will be leaked to the client::
586+
587+
# -*- coding: utf-8 -*-
588+
589+
# Spring Python
590+
from springpython.remoting.xmlrpc import SSLXMLRPCServer
591+
592+
# PyOpenSSL
593+
from OpenSSL import SSL
594+
595+
class MySSLServer(SSLXMLRPCServer):
596+
def __init__(self, *args, **kwargs):
597+
super(MySSLServer, self).__init__(*args, **kwargs)
598+
599+
def register_functions(self):
600+
self.register_function(pow)
601+
602+
host = "localhost"
603+
port = 8000
604+
key = "./server-key.pem"
605+
cert = "./server-cert.pem"
606+
ca = "./chain.pem"
607+
608+
verify_fields = {"CN": "Client", "O":"The Sample Company", "ST":"New York"}
609+
610+
server = MySSLServer(host, port, key, cert, ca, verify_options=SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
611+
verify_fields=verify_fields)
612+
server.serve_forever()
613+
614+
::
615+
616+
# -*- coding: utf-8 -*-
617+
618+
# Spring Python
619+
from springpython.remoting.xmlrpc import SSLXMLRPCClient
620+
621+
server_location = "https://localhost:8000/RPC2"
622+
key = "./client-key.pem"
623+
624+
# Make sure the commonName is set to what the server requires.
625+
cert = "./client-cert.pem"
626+
627+
ca_certs = "./cacert.pem"
628+
629+
client = SSLXMLRPCClient(server_location, key_file=key, cert_file=cert, ca_certs=ca_certs)
630+
631+
print client.pow(41, 3)
632+
633+
More options
634+
++++++++++++
635+
636+
**ZzzzzZzz** All the config options go here..
637+
638+
Note that you can use both the client and the server with other XML-RPC
639+
implementations, there’s nothing preventing you from exposing secure XML-RPC to
640+
Java or .NET clients or from connecting with the secure client to XML-RPC servers
641+
implemented in other languages and technologies.
642+
643+
Logging
644+
+++++++
645+
646+
**ZzzzzZzz** Describe loggers used..

0 commit comments

Comments
 (0)