Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
snf-ganeti
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
itminedu
snf-ganeti
Commits
b14f759e
Commit
b14f759e
authored
16 years ago
by
Michael Hanselmann
Browse files
Options
Downloads
Patches
Plain Diff
ganeti.http: Move SSL socket creation into base class
The same code will be used by the HTTP client. Reviewed-by: iustinp
parent
b14b975f
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/http.py
+71
-37
71 additions, 37 deletions
lib/http.py
with
71 additions
and
37 deletions
lib/http.py
+
71
−
37
View file @
b14f759e
...
...
@@ -209,6 +209,70 @@ class HTTPJsonConverter:
return
serializer
.
LoadJson
(
data
)
class
_HttpSocketBase
(
object
):
"""
Base class for HTTP server and client.
"""
def
__init__
(
self
):
self
.
_using_ssl
=
None
self
.
_ssl_cert
=
None
self
.
_ssl_key
=
None
def
_CreateSocket
(
self
,
ssl_key_path
,
ssl_cert_path
,
ssl_verify_peer
):
"""
Creates a TCP socket and initializes SSL if needed.
@type ssl_key_path: string
@param ssl_key_path: Path to file containing SSL key in PEM format
@type ssl_cert_path: string
@param ssl_cert_path: Path to file containing SSL certificate in PEM format
@type ssl_verify_peer: bool
@param ssl_verify_peer: Whether to require client certificate and compare
it with our certificate
"""
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
# Should we enable SSL?
self
.
_using_ssl
=
(
ssl_cert_path
and
ssl_key_path
)
if
not
self
.
_using_ssl
:
return
sock
ctx
=
OpenSSL
.
SSL
.
Context
(
OpenSSL
.
SSL
.
SSLv23_METHOD
)
ctx
.
set_options
(
OpenSSL
.
SSL
.
OP_NO_SSLv2
)
ssl_key_pem
=
utils
.
ReadFile
(
ssl_key_path
)
ssl_cert_pem
=
utils
.
ReadFile
(
ssl_cert_path
)
cr
=
OpenSSL
.
crypto
self
.
_ssl_cert
=
cr
.
load_certificate
(
cr
.
FILETYPE_PEM
,
ssl_cert_pem
)
self
.
_ssl_key
=
cr
.
load_privatekey
(
cr
.
FILETYPE_PEM
,
ssl_key_pem
)
del
cr
ctx
.
use_privatekey
(
self
.
_ssl_key
)
ctx
.
use_certificate
(
self
.
_ssl_cert
)
ctx
.
check_privatekey
()
if
ssl_verify_peer
:
ctx
.
set_verify
(
OpenSSL
.
SSL
.
VERIFY_PEER
|
OpenSSL
.
SSL
.
VERIFY_FAIL_IF_NO_PEER_CERT
,
self
.
_SSLVerifyCallback
)
return
OpenSSL
.
SSL
.
Connection
(
ctx
,
sock
)
def
_SSLVerifyCallback
(
self
,
conn
,
cert
,
errnum
,
errdepth
,
ok
):
"""
Verify the certificate provided by the peer
We only compare fingerprints. The client must use the same certificate as
we do on our side.
"""
assert
self
.
_ssl_cert
and
self
.
_ssl_key
,
"
SSL not initialized
"
return
(
self
.
_ssl_cert
.
digest
(
"
sha1
"
)
==
cert
.
digest
(
"
sha1
"
)
and
self
.
_ssl_cert
.
digest
(
"
md5
"
)
==
cert
.
digest
(
"
md5
"
))
class
_HttpConnectionHandler
(
object
):
"""
Implements server side of HTTP
...
...
@@ -487,7 +551,7 @@ class _HttpConnectionHandler(object):
logging
.
debug
(
"
HTTP POST data: %s
"
,
self
.
request_post_data
)
class
HttpServer
(
object
):
class
HttpServer
(
_HttpSocketBase
):
"""
Generic HTTP server class
Users of this class must subclass it and override the HandleRequest function.
...
...
@@ -514,57 +578,27 @@ class HttpServer(object):
it with our certificate
"""
_HttpSocketBase
.
__init__
(
self
)
self
.
mainloop
=
mainloop
self
.
local_address
=
local_address
self
.
port
=
port
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
if
ssl_cert_path
and
ssl_key_path
:
ctx
=
OpenSSL
.
SSL
.
Context
(
OpenSSL
.
SSL
.
SSLv23_METHOD
)
ctx
.
set_options
(
OpenSSL
.
SSL
.
OP_NO_SSLv2
)
ssl_key_pem
=
utils
.
ReadFile
(
ssl_key_path
)
ssl_cert_pem
=
utils
.
ReadFile
(
ssl_cert_path
)
cr
=
OpenSSL
.
crypto
self
.
_ssl_cert
=
cr
.
load_certificate
(
cr
.
FILETYPE_PEM
,
ssl_cert_pem
)
self
.
_ssl_key
=
cr
.
load_privatekey
(
cr
.
FILETYPE_PEM
,
ssl_key_pem
)
del
cr
ctx
.
use_privatekey
(
self
.
_ssl_key
)
ctx
.
use_certificate
(
self
.
_ssl_cert
)
ctx
.
check_privatekey
()
self
.
socket
=
self
.
_CreateSocket
(
ssl_key_path
,
ssl_cert_path
,
ssl_verify_peer
)
if
ssl_verify_peer
:
ctx
.
set_verify
(
OpenSSL
.
SSL
.
VERIFY_PEER
|
OpenSSL
.
SSL
.
VERIFY_FAIL_IF_NO_PEER_CERT
,
self
.
_VerifyCallback
)
# Allow port to be reused
self
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
socket
=
OpenSSL
.
SSL
.
Connection
(
ctx
,
sock
)
if
self
.
_using_ssl
:
self
.
_fileio_class
=
_SSLFileObject
else
:
self
.
socket
=
sock
self
.
_fileio_class
=
socket
.
_fileobject
# Allow port to be reused
self
.
socket
.
setsockopt
(
socket
.
SOL_SOCKET
,
socket
.
SO_REUSEADDR
,
1
)
self
.
_children
=
[]
mainloop
.
RegisterIO
(
self
,
self
.
socket
.
fileno
(),
select
.
POLLIN
)
mainloop
.
RegisterSignal
(
self
)
def
_VerifyCallback
(
self
,
conn
,
cert
,
errno
,
errdepth
,
ok
):
"""
Verify the certificate provided by the peer
We only compare fingerprints. The client must use the same certificate as
we do on the server side.
"""
return
(
self
.
_ssl_cert
.
digest
(
"
sha1
"
)
==
cert
.
digest
(
"
sha1
"
)
and
self
.
_ssl_cert
.
digest
(
"
md5
"
)
==
cert
.
digest
(
"
md5
"
))
def
Start
(
self
):
self
.
socket
.
bind
((
self
.
local_address
,
self
.
port
))
self
.
socket
.
listen
(
5
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment