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
, passwd_callback
=None):
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
40 ctx
.set_passwd_cb
= passwd_callback
42 ctx
.use_certificate_file(cert
)
43 ctx
.use_privatekey_file(pkey
)
44 ctx
.load_client_ca(ca_cert
)
45 ctx
.load_verify_locations(ca_cert
)
46 verify
= SSL
.VERIFY_PEER | SSL
.VERIFY_FAIL_IF_NO_PEER_CERT
47 ctx
.set_verify(verify
, our_verify
)
48 ctx
.set_verify_depth(10)
49 ctx
.set_options(SSL
.OP_NO_SSLv2 | SSL
.OP_NO_TLSv1
)
54 class BaseServer(SocketServer
.TCPServer
):
55 allow_reuse_address
= 1
57 def __init__(self
, server_addr
, req_handler
):
59 self
.allow_reuse_address
= 1
60 SocketServer
.TCPServer
.__init
__(self
, server_addr
, req_handler
)
65 def serve_forever(self
):
71 class BaseSSLServer(BaseServer
):
72 """ SSL-enabled variant """
74 def __init__(self
, server_address
, req_handler
, pkey
, cert
, ca_cert
, timeout
=None):
75 self
._timeout
= timeout
76 self
.ssl_ctx
= CreateSSLContext(pkey
, cert
, ca_cert
)
78 BaseServer
.__init
__(self
, server_address
, req_handler
)
80 sock
= socket
.socket(self
.address_family
, self
.socket_type
)
81 con
= SSL
.Connection(self
.ssl_ctx
, sock
)
82 self
.socket
= SSLConnection
.SSLConnection(con
)
83 if sys
.version_info
[:3] >= (2, 3, 0):
84 self
.socket
.settimeout(self
._timeout
)
86 self
.server_activate()
88 host
, port
= self
.socket
.getsockname()[:2]
89 self
.server_name
= socket
.getfqdn(host
)
90 self
.server_port
= port
93 class HTTPSConnection(httplib
.HTTPConnection
):
94 "This class allows communication via SSL."
96 response_class
= httplib
.HTTPResponse
98 def __init__(self
, host
, port
=None, ssl_context
=None, strict
=None, timeout
=None):
99 httplib
.HTTPConnection
.__init
__(self
, host
, port
, strict
)
100 self
.ssl_ctx
= ssl_context
101 self
._timeout
= timeout
104 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
105 con
= SSL
.Connection(self
.ssl_ctx
, sock
)
106 self
.sock
= SSLConnection
.SSLConnection(con
)
107 if sys
.version_info
[:3] >= (2, 3, 0):
108 self
.sock
.settimeout(self
._timeout
)
109 self
.sock
.connect((self
.host
, self
.port
))
112 class HTTPS(httplib
.HTTP
):
113 """Compatibility with 1.5 httplib interface
115 Python 1.5.2 did not have an HTTPS class, but it defined an
116 interface for sending http requests that is also useful for
120 _connection_class
= HTTPSConnection
122 def __init__(self
, host
='', port
=None, ssl_context
=None, strict
=None, timeout
=None):
123 self
._setup
(self
._connection
_class
(host
, port
, ssl_context
, strict
, timeout
))