import socket
import traceback
import threading
-from Queue import Queue
-import SocketServer
-import BaseHTTPServer
-import SimpleXMLRPCServer
+from queue import Queue
+import socketserver
+import http.server
+import xmlrpc.server
from OpenSSL import SSL
from sfa.util.sfalogging import logger
from sfa.util.cache import Cache
from sfa.trust.certificate import Certificate
from sfa.trust.trustedroots import TrustedRoots
-from sfa.util.py23 import xmlrpc_client
+import xmlrpc.client
# don't hard code an api class anymore here
from sfa.generic import Generic
# if the cert has been preverified, then it is ok
if preverify:
# print " preverified"
- return 1
+ return True
# the certificate verification done by openssl checks a number of things
# that we aren't interested in, so we look out for those error messages
# and ignore them
# XXX SMBAKER: I don't know what this error is, but it's being returned
- # xxx thierry: this most likely means the cert has a validity range in the future
+ # xxx thierry: this most likely means the cert
+ # has a validity range in the future
# by newer pl nodes.
if err == 9:
# print " X509_V_ERR_CERT_NOT_YET_VALID"
- return 1
+ return True
# allow self-signed certificates
if err == 18:
# print " X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT"
- return 1
+ return False
# allow certs that don't have an issuer
if err == 20:
# print " X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY"
- return 1
+ return False
# allow chained certs with self-signed roots
if err == 19:
- return 1
+ return False
# allow certs that are untrusted
if err == 21:
# print " X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE"
- return 1
+ return False
# allow certs that are untrusted
if err == 27:
# print " X509_V_ERR_CERT_UNTRUSTED"
- return 1
+ return False
# ignore X509_V_ERR_CERT_SIGNATURE_FAILURE
if err == 7:
- return 1
+ return False
- logger.debug(" error %s in verify_callback" % err)
+ logger.debug(" unhandled error %s in verify_callback" % err)
- return 0
+ return False
##
# taken from the web (XXX find reference). Implements HTTPS xmlrpc request
# handler
+# python-2.7 http://code.activestate.com/recipes/442473-simple-http-server-supporting-ssl-secure-communica/
+# python-3.3 https://gist.github.com/ubershmekel/6194556
+class SecureXMLRpcRequestHandler(xmlrpc.server.SimpleXMLRPCRequestHandler):
+ """
+ Secure XML-RPC request handler class.
-class SecureXMLRpcRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
- """Secure XML-RPC request handler class.
-
- It it very similar to SimpleXMLRPCRequestHandler but it uses HTTPS for transporting XML data.
+ It it very similar to SimpleXMLRPCRequestHandler
+ but it uses HTTPS for transporting XML data.
"""
def setup(self):
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+# porting to python3
+# xmlrpc.server.SimpleXMLRPCRequestHandler inherits
+# http.server.BaseHTTPRequestHandler, that already has
+# the rfile and wfile attributes
def do_POST(self):
- """Handles the HTTPS POST request.
+ """
+ Handles the HTTPS POST request.
- It was copied out from SimpleXMLRPCServer.py and modified to shutdown
+ It was copied out from SimpleXMLRPCServer.py and modified to shutdown
the socket cleanly.
"""
try:
# Taken from the web (XXX find reference). Implements an HTTPS xmlrpc server
-class SecureXMLRPCServer(BaseHTTPServer.HTTPServer, SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
+class SecureXMLRPCServer(http.server.HTTPServer,
+ xmlrpc.server.SimpleXMLRPCDispatcher):
- def __init__(self, server_address, HandlerClass, key_file, cert_file, logRequests=True):
+ def __init__(self, server_address, HandlerClass,
+ key_file, cert_file, logRequests=True):
"""
Secure XML-RPC server.
- It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data.
+ It it very similar to SimpleXMLRPCServer
+ but it uses HTTPS for transporting XML data.
"""
- logger.debug("SecureXMLRPCServer.__init__, server_address=%s, "
- "cert_file=%s, key_file=%s" % (server_address, cert_file, key_file))
+ logger.debug(
+ f"SecureXMLRPCServer.__init__, server_address={server_address}, "
+ f"cert_file={cert_file}, key_file={key_file}")
self.logRequests = logRequests
self.interface = None
self.key_file = key_file
HandlerClass.cache = Cache()
# for compatibility with python 2.4 (centos53)
if sys.version_info < (2, 5):
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
+ xmlrpc.server.SimpleXMLRPCDispatcher.__init__(self)
else:
- SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(
+ xmlrpc.server.SimpleXMLRPCDispatcher.__init__(
self, True, None)
- SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
+ socketserver.BaseServer.__init__(self, server_address, HandlerClass)
ctx = SSL.Context(SSL.SSLv23_METHOD)
ctx.use_privatekey_file(key_file)
ctx.use_certificate_file(cert_file)
- # If you wanted to verify certs against known CAs.. this is how you would do it
+ # If you wanted to verify certs against known CAs..
+ # this is how you would do it
# ctx.load_verify_locations('/etc/sfa/trusted_roots/plc.gpo.gid')
config = Config()
trusted_cert_files = TrustedRoots(
def _dispatch(self, method, params):
logger.debug("SecureXMLRPCServer._dispatch, method=%s" % method)
try:
- return SimpleXMLRPCServer.SimpleXMLRPCDispatcher._dispatch(self, method, params)
+ return xmlrpc.server.SimpleXMLRPCDispatcher._dispatch(
+ self, method, params)
except:
# can't use format_exc() as it is not available in jython yet
# (even in trunk).
type, value, tb = sys.exc_info()
- raise xmlrpc_client.Fault(1, ''.join(
+ raise xmlrpc.client.Fault(1, ''.join(
traceback.format_exception(type, value, tb)))
# override this one from the python 2.7 code
# originally defined in class TCPServer
def shutdown_request(self, request):
- """Called to shutdown and close an individual request."""
+ """
+ Called to shutdown and close an individual request.
+ """
# ----------
- # the std python 2.7 code just attempts a request.shutdown(socket.SHUT_WR)
+ # the std python 2.7 code just attempts a
+ # request.shutdown(socket.SHUT_WR)
# this works fine with regular sockets
- # However we are dealing with an instance of OpenSSL.SSL.Connection instead
+ # However we are dealing with an instance of
+ # OpenSSL.SSL.Connection instead
# This one only supports shutdown(), and in addition this does not
# always perform as expected
# ---------- std python 2.7 code
# for each request, requests are processed by of pool of reusable threads.
-class ThreadPoolMixIn(SocketServer.ThreadingMixIn):
+class ThreadPoolMixIn(socketserver.ThreadingMixIn):
"""
use a thread pool instead of a new thread on every request
"""
# set up the threadpool
self.requests = Queue()
- for x in range(self.numThreads):
- t = threading.Thread(target=self.process_request_thread)
- t.setDaemon(1)
- t.start()
+ for _ in range(self.numThreads):
+ thread = threading.Thread(target=self.process_request_thread)
+ thread.setDaemon(1)
+ thread.start()
# server main loop
while True:
obtain request from queue instead of directly from server socket
"""
while True:
- SocketServer.ThreadingMixIn.process_request_thread(
+ socketserver.ThreadingMixIn.process_request_thread(
self, *self.requests.get())
def handle_request(self):