1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # Copyright 2005 Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
18 from OpenSSL
import SSL
24 def our_verify(connection
, x509
, errNum
, errDepth
, preverifyOK
):
25 # print "Verify: errNum = %s, errDepth = %s, preverifyOK = %s" % (errNum, errDepth, preverifyOK)
27 # preverifyOK should tell us whether or not the client's certificate
28 # correctly authenticates against the CA chain
32 def CreateSSLContext(pkey
, cert
, ca_cert
):
33 for f
in pkey
, cert
, ca_cert
:
34 if f
and not os
.access(f
, os
.R_OK
):
35 print "%s does not exist or is not readable." % f
38 ctx
= SSL
.Context(SSL
.SSLv3_METHOD
) # SSLv3 only
39 ctx
.use_certificate_file(cert
)
40 ctx
.use_privatekey_file(pkey
)
41 ctx
.load_client_ca(ca_cert
)
42 ctx
.load_verify_locations(ca_cert
)
43 verify
= SSL
.VERIFY_PEER | SSL
.VERIFY_FAIL_IF_NO_PEER_CERT
44 ctx
.set_verify(verify
, our_verify
)
45 ctx
.set_verify_depth(10)
46 ctx
.set_options(SSL
.OP_NO_SSLv2 | SSL
.OP_NO_TLSv1
)
51 class BaseServer(SocketServer
.TCPServer
):
52 allow_reuse_address
= 1
54 def __init__(self
, server_addr
, req_handler
):
56 self
.allow_reuse_address
= 1
57 SocketServer
.TCPServer
.__init
__(self
, server_addr
, req_handler
)
62 def serve_forever(self
):
68 class BaseSSLServer(BaseServer
):
69 """ SSL-enabled variant """
71 def __init__(self
, server_address
, req_handler
, pkey
, cert
, ca_cert
, timeout
=None):
72 self
._timeout
= timeout
73 self
.ssl_ctx
= CreateSSLContext(pkey
, cert
, ca_cert
)
75 BaseServer
.__init
__(self
, server_address
, req_handler
)
77 sock
= socket
.socket(self
.address_family
, self
.socket_type
)
78 con
= SSL
.Connection(self
.ssl_ctx
, sock
)
79 self
.socket
= SSLConnection
.SSLConnection(con
)
80 if sys
.version_info
[:3] >= (2, 3, 0):
81 self
.socket
.settimeout(self
._timeout
)
83 self
.server_activate()
85 host
, port
= self
.socket
.getsockname()[:2]
86 self
.server_name
= socket
.getfqdn(host
)
87 self
.server_port
= port
90 class HTTPSConnection(httplib
.HTTPConnection
):
91 "This class allows communication via SSL."
93 response_class
= httplib
.HTTPResponse
95 def __init__(self
, host
, port
=None, ssl_context
=None, strict
=None, timeout
=None):
96 httplib
.HTTPConnection
.__init
__(self
, host
, port
, strict
)
97 self
.ssl_ctx
= ssl_context
98 self
._timeout
= timeout
101 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
102 con
= SSL
.Connection(self
.ssl_ctx
, sock
)
103 self
.sock
= SSLConnection
.SSLConnection(con
)
104 if sys
.version_info
[:3] >= (2, 3, 0):
105 self
.sock
.settimeout(self
._timeout
)
106 self
.sock
.connect((self
.host
, self
.port
))
109 class HTTPS(httplib
.HTTP
):
110 """Compatibility with 1.5 httplib interface
112 Python 1.5.2 did not have an HTTPS class, but it defined an
113 interface for sending http requests that is also useful for
117 _connection_class
= HTTPSConnection
119 def __init__(self
, host
='', port
=None, ssl_context
=None, strict
=None, timeout
=None):
120 self
._setup
(self
._connection
_class
(host
, port
, ssl_context
, strict
, timeout
))