Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
381e67a3
Commit
381e67a3
authored
Aug 19, 2017
by
David Johnson
Browse files
Ensure the SSL part of accept() does not block the main thread.
parent
e7f73e81
Changes
1
Hide whitespace changes
Inline
Side-by-side
xmlrpc/sslxmlrpc_server.py.in
View file @
381e67a3
...
...
@@ -30,7 +30,7 @@ import traceback
import
syslog
import
string
import
socket
import
SocketServer
import
BaseHTTPServer
from
SimpleXMLRPCServer
import
SimpleXMLRPCDispatcher
...
...
@@ -47,6 +47,7 @@ from libdb import *
try
:
from
M2Crypto
import
SSL
from
M2Crypto.SSL
import
SSLError
from
M2Crypto.SSL
import
Checker
except
ImportError
,
e
:
sys
.
stderr
.
write
(
"error: The py-m2crypto port is not installed
\n
"
)
sys
.
exit
(
1
)
...
...
@@ -65,6 +66,13 @@ ADDR = "0.0.0.0"
server_cert
=
"@prefix@/etc/server.pem"
ca_cert
=
"@prefix@/etc/emulab.pem"
# Set a timeout for the SSL_accept phase of the client session setup.
# This allows us to not block the main thread indefinitely if a non-SSL
# or malicious client connects to us and says nothing.
SSL_CLIENT_ACCEPT_TIMEOUT
=
2
# Set a timeout that is used for the client socket *after* SSL accept.
SSL_CLIENT_REQUEST_TIMEOUT
=
30
#
# By default, run a wrapper class that includes all off the modules.
# The client can invoke methods of the form experiment.swapexp when
...
...
@@ -157,6 +165,51 @@ class MyXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
if
self
.
server
.
logRequests
:
BaseHTTPServer
.
BaseHTTPRequestHandler
.
log_request
(
self
,
code
,
size
)
class
MyConnection
(
SSL
.
Connection
):
"""
A simple subclassing of the native SSL.Connection, because that
class does not give you the ability to set a timeout for the ssl
acceptance of a new client socket, once it has been accept()ed.
"""
def
accept
(
self
):
"""
(NB: this comes nearly directly from M2Crypto.SSL.Connection; it
is only slightly modified to allow a timeout during the SSL part
of the accept, once the socket accept has finished. Once that
succeeds, we restore a sane timeout for the client socket,
because we use a forking mixin, so all further work will happen
in the child.
Accept an SSL connection. The return value is a pair (ssl,
addr) where ssl is a new SSL connection object and addr is the
address bound to the other end of the SSL connection.
"""
sock
,
addr
=
self
.
socket
.
accept
()
# Use our subclass, not the default SSL.connection
ssl
=
MyConnection
(
self
.
ctx
,
sock
)
# Set non-blocking so that the M2Crypto openssl wrapper glue
# will honor the _timeout we're about to set; but only if the
# timeout is not None.
if
SSL_CLIENT_ACCEPT_TIMEOUT
is
not
None
:
sock
.
setblocking
(
False
)
# Set a timeout that gets used in the below call of ssl.accept_ssl()
ssl
.
_timeout
=
SSL_CLIENT_ACCEPT_TIMEOUT
ssl
.
addr
=
addr
ssl
.
setup_ssl
()
ssl
.
set_accept_state
()
ssl
.
accept_ssl
()
check
=
getattr
(
self
,
'postConnectionCheck'
,
self
.
serverPostConnectionCheck
)
if
check
is
not
None
:
if
not
check
(
ssl
.
get_peer_cert
(),
ssl
.
addr
[
0
]):
raise
Checker
.
SSLVerificationError
(
'post connection check failed'
)
# Make the socket blocking again.
sock
.
setblocking
(
True
)
# ... and undo our timeout.
ssl
.
_timeout
=
SSL_CLIENT_REQUEST_TIMEOUT
return
ssl
,
addr
#
# A simple server based on the forking version SSLServer. We fork cause
...
...
@@ -183,8 +236,19 @@ class MyServer(SSL.ForkingSSLServer, SimpleXMLRPCDispatcher):
dargs
=
(
self
,
False
,
None
)
pass
SimpleXMLRPCDispatcher
.
__init__
(
*
dargs
)
SSL
.
SSLServer
.
__init__
(
self
,
(
ADDR
,
PORT
),
MyXMLRPCRequestHandler
,
ctx
)
#
# Ugh -- duplicate the SSL.SSLServer constructor body, other
# than to use our little MyConnection wrapper instead of
# SSLConnection.
#
#SSL.SSLServer.__init__(self, (ADDR, PORT),
# MyXMLRPCRequestHandler, ctx)
SocketServer
.
BaseServer
.
__init__
(
self
,
(
ADDR
,
PORT
),
MyXMLRPCRequestHandler
)
self
.
ssl_ctx
=
ctx
self
.
socket
=
MyConnection
(
self
.
ssl_ctx
)
self
.
server_bind
()
self
.
server_activate
()
pass
##
...
...
David Johnson
@johnsond
mentioned in commit
fccfee60
·
Apr 19, 2019
mentioned in commit
fccfee60
mentioned in commit fccfee602ee35277b27238f47c6f2594a88786a1
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment