Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
934b16d0
Commit
934b16d0
authored
Jun 28, 2008
by
Bill Janssen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
various SSL fixes; issues 1251, 3162, 3212
parent
a27474c3
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
528 additions
and
348 deletions
+528
-348
Doc/library/ssl.rst
Doc/library/ssl.rst
+33
-1
Lib/ssl.py
Lib/ssl.py
+105
-256
Lib/test/test_ssl.py
Lib/test/test_ssl.py
+213
-33
Lib/test/wrongcert.pem
Lib/test/wrongcert.pem
+32
-0
Modules/_ssl.c
Modules/_ssl.c
+145
-58
No files found.
Doc/library/ssl.rst
View file @
934b16d0
...
@@ -54,7 +54,7 @@ Functions, Constants, and Exceptions
...
@@ -54,7 +54,7 @@ Functions, Constants, and Exceptions
network connection. This error is a subtype of :exc:`socket.error`, which
network connection. This error is a subtype of :exc:`socket.error`, which
in turn is a subtype of :exc:`IOError`.
in turn is a subtype of :exc:`IOError`.
.. function:: wrap_socket (sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None)
.. function:: wrap_socket (sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version={see docs}, ca_certs=None
, do_handshake_on_connect=True, suppress_ragged_eofs=True
)
Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance of :class:`ssl.SSLSocket`, a subtype
Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance of :class:`ssl.SSLSocket`, a subtype
of :class:`socket.socket`, which wraps the underlying socket in an SSL context.
of :class:`socket.socket`, which wraps the underlying socket in an SSL context.
...
@@ -122,6 +122,18 @@ Functions, Constants, and Exceptions
...
@@ -122,6 +122,18 @@ Functions, Constants, and Exceptions
In some older versions of OpenSSL (for instance, 0.9.7l on OS X 10.4),
In some older versions of OpenSSL (for instance, 0.9.7l on OS X 10.4),
an SSLv2 client could not connect to an SSLv23 server.
an SSLv2 client could not connect to an SSLv23 server.
The parameter ``do_handshake_on_connect`` specifies whether to do the SSL
handshake automatically after doing a :meth:`socket.connect`, or whether the
application program will call it explicitly, by invoking the :meth:`SSLSocket.do_handshake`
method. Calling :meth:`SSLSocket.do_handshake` explicitly gives the program control over
the blocking behavior of the socket I/O involved in the handshake.
The parameter ``suppress_ragged_eofs`` specifies how the :meth:`SSLSocket.read`
method should signal unexpected EOF from the other end of the connection. If specified
as :const:`True` (the default), it returns a normal EOF in response to unexpected
EOF errors raised from the underlying socket; if :const:`False`, it will raise
the exceptions back to the caller.
.. function:: RAND_status()
.. function:: RAND_status()
Returns True if the SSL pseudo-random number generator has been
Returns True if the SSL pseudo-random number generator has been
...
@@ -290,6 +302,25 @@ SSLSocket Objects
...
@@ -290,6 +302,25 @@ SSLSocket Objects
number of secret bits being used. If no connection has been
number of secret bits being used. If no connection has been
established, returns ``None``.
established, returns ``None``.
.. method:: SSLSocket.do_handshake()
Perform a TLS/SSL handshake. If this is used with a non-blocking socket,
it may raise :exc:`SSLError` with an ``arg[0]`` of :const:`SSL_ERROR_WANT_READ`
or :const:`SSL_ERROR_WANT_WRITE`, in which case it must be called again until it
completes successfully. For example, to simulate the behavior of a blocking socket,
one might write::
while True:
try:
s.do_handshake()
break
except ssl.SSLError, err:
if err.args[0] == ssl.SSL_ERROR_WANT_READ:
select.select([s], [], [])
elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
select.select([], [s], [])
else:
raise
.. index:: single: certificates
.. index:: single: certificates
...
@@ -367,6 +398,7 @@ certificate, you need to provide a "CA certs" file, filled with the certificate
...
@@ -367,6 +398,7 @@ certificate, you need to provide a "CA certs" file, filled with the certificate
chains for each issuer you are willing to trust. Again, this file just
chains for each issuer you are willing to trust. Again, this file just
contains these chains concatenated together. For validation, Python will
contains these chains concatenated together. For validation, Python will
use the first chain it finds in the file which matches.
use the first chain it finds in the file which matches.
Some "standard" root certificates are available from various certification
Some "standard" root certificates are available from various certification
authorities:
authorities:
`CACert.org <http://www.cacert.org/index.php?id=3>`_,
`CACert.org <http://www.cacert.org/index.php?id=3>`_,
...
...
Lib/ssl.py
View file @
934b16d0
This diff is collapsed.
Click to expand it.
Lib/test/test_ssl.py
View file @
934b16d0
This diff is collapsed.
Click to expand it.
Lib/test/wrongcert.pem
0 → 100644
View file @
934b16d0
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC89ZNxjTgWgq7Z1g0tJ65w+k7lNAj5IgjLb155UkUrz0XsHDnH
FlbsVUg2Xtk6+bo2UEYIzN7cIm5ImpmyW/2z0J1IDVDlvR2xJ659xrE0v5c2cB6T
f9lnNTwpSoeK24Nd7Jwq4j9vk95fLrdqsBq0/KVlsCXeixS/CaqqduXfvwIDAQAB
AoGAQFko4uyCgzfxr4Ezb4Mp5pN3Npqny5+Jey3r8EjSAX9Ogn+CNYgoBcdtFgbq
1yif/0sK7ohGBJU9FUCAwrqNBI9ZHB6rcy7dx+gULOmRBGckln1o5S1+smVdmOsW
7zUVLBVByKuNWqTYFlzfVd6s4iiXtAE2iHn3GCyYdlICwrECQQDhMQVxHd3EFbzg
SFmJBTARlZ2GKA3c1g/h9/XbkEPQ9/RwI3vnjJ2RaSnjlfoLl8TOcf0uOGbOEyFe
19RvCLXjAkEA1s+UE5ziF+YVkW3WolDCQ2kQ5WG9+ccfNebfh6b67B7Ln5iG0Sbg
ky9cjsO3jbMJQtlzAQnH1850oRD5Gi51dQJAIbHCDLDZU9Ok1TI+I2BhVuA6F666
lEZ7TeZaJSYq34OaUYUdrwG9OdqwZ9sy9LUav4ESzu2lhEQchCJrKMn23QJAReqs
ZLHUeTjfXkVk7dHhWPWSlUZ6AhmIlA/AQ7Payg2/8wM/JkZEJEPvGVykms9iPUrv
frADRr+hAGe43IewnQJBAJWKZllPgKuEBPwoEldHNS8nRu61D7HzxEzQ2xnfj+Nk
2fgf1MAzzTRsikfGENhVsVWeqOcijWb6g5gsyCmlRpc=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICsDCCAhmgAwIBAgIJAOqYOYFJfEEoMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMDgwNjI2MTgxNTUyWhcNMDkwNjI2MTgxNTUyWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
gQC89ZNxjTgWgq7Z1g0tJ65w+k7lNAj5IgjLb155UkUrz0XsHDnHFlbsVUg2Xtk6
+bo2UEYIzN7cIm5ImpmyW/2z0J1IDVDlvR2xJ659xrE0v5c2cB6Tf9lnNTwpSoeK
24Nd7Jwq4j9vk95fLrdqsBq0/KVlsCXeixS/CaqqduXfvwIDAQABo4GnMIGkMB0G
A1UdDgQWBBTctMtI3EO9OjLI0x9Zo2ifkwIiNjB1BgNVHSMEbjBsgBTctMtI3EO9
OjLI0x9Zo2ifkwIiNqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt
U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAOqYOYFJ
fEEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAQwa7jya/DfhaDn7E
usPkpgIX8WCL2B1SqnRTXEZfBPPVq/cUmFGyEVRVATySRuMwi8PXbVcOhXXuocA+
43W+iIsD9pXapCZhhOerCq18TC1dWK98vLUsoK8PMjB6e5H/O8bqojv0EeC+fyCw
eSHj5jpC8iZKjCHBn+mAi4cQ514=
-----END CERTIFICATE-----
Modules/_ssl.c
View file @
934b16d0
...
@@ -2,14 +2,15 @@
...
@@ -2,14 +2,15 @@
SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
Re-worked a bit by Bill Janssen to add server-side support and
Re-worked a bit by Bill Janssen to add server-side support and
certificate decoding.
certificate decoding. Chris Stawarz contributed some non-blocking
patches.
This module is imported by ssl.py. It should *not* be used
This module is imported by ssl.py. It should *not* be used
directly.
directly.
XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE?
XXX should partial writes be enabled, SSL_MODE_ENABLE_PARTIAL_WRITE?
XXX what about SSL_MODE_AUTO_RETRY
XXX what about SSL_MODE_AUTO_RETRY
?
*/
*/
#include "Python.h"
#include "Python.h"
...
@@ -265,8 +266,6 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
...
@@ -265,8 +266,6 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
PySSLObject
*
self
;
PySSLObject
*
self
;
char
*
errstr
=
NULL
;
char
*
errstr
=
NULL
;
int
ret
;
int
ret
;
int
err
;
int
sockstate
;
int
verification_mode
;
int
verification_mode
;
self
=
PyObject_New
(
PySSLObject
,
&
PySSL_Type
);
/* Create new object */
self
=
PyObject_New
(
PySSLObject
,
&
PySSL_Type
);
/* Create new object */
...
@@ -388,57 +387,6 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
...
@@ -388,57 +387,6 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file,
SSL_set_accept_state
(
self
->
ssl
);
SSL_set_accept_state
(
self
->
ssl
);
PySSL_END_ALLOW_THREADS
PySSL_END_ALLOW_THREADS
/* Actually negotiate SSL connection */
/* XXX If SSL_connect() returns 0, it's also a failure. */
sockstate
=
0
;
do
{
PySSL_BEGIN_ALLOW_THREADS
if
(
socket_type
==
PY_SSL_CLIENT
)
ret
=
SSL_connect
(
self
->
ssl
);
else
ret
=
SSL_accept
(
self
->
ssl
);
err
=
SSL_get_error
(
self
->
ssl
,
ret
);
PySSL_END_ALLOW_THREADS
if
(
PyErr_CheckSignals
())
{
goto
fail
;
}
if
(
err
==
SSL_ERROR_WANT_READ
)
{
sockstate
=
check_socket_and_wait_for_timeout
(
Sock
,
0
);
}
else
if
(
err
==
SSL_ERROR_WANT_WRITE
)
{
sockstate
=
check_socket_and_wait_for_timeout
(
Sock
,
1
);
}
else
{
sockstate
=
SOCKET_OPERATION_OK
;
}
if
(
sockstate
==
SOCKET_HAS_TIMED_OUT
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"The connect operation timed out"
));
goto
fail
;
}
else
if
(
sockstate
==
SOCKET_HAS_BEEN_CLOSED
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"Underlying socket has been closed."
));
goto
fail
;
}
else
if
(
sockstate
==
SOCKET_TOO_LARGE_FOR_SELECT
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"Underlying socket too large for select()."
));
goto
fail
;
}
else
if
(
sockstate
==
SOCKET_IS_NONBLOCKING
)
{
break
;
}
}
while
(
err
==
SSL_ERROR_WANT_READ
||
err
==
SSL_ERROR_WANT_WRITE
);
if
(
ret
<
1
)
{
PySSL_SetError
(
self
,
ret
,
__FILE__
,
__LINE__
);
goto
fail
;
}
self
->
ssl
->
debug
=
1
;
PySSL_BEGIN_ALLOW_THREADS
if
((
self
->
peer_cert
=
SSL_get_peer_certificate
(
self
->
ssl
)))
{
X509_NAME_oneline
(
X509_get_subject_name
(
self
->
peer_cert
),
self
->
server
,
X509_NAME_MAXLEN
);
X509_NAME_oneline
(
X509_get_issuer_name
(
self
->
peer_cert
),
self
->
issuer
,
X509_NAME_MAXLEN
);
}
PySSL_END_ALLOW_THREADS
self
->
Socket
=
Sock
;
self
->
Socket
=
Sock
;
Py_INCREF
(
self
->
Socket
);
Py_INCREF
(
self
->
Socket
);
return
self
;
return
self
;
...
@@ -488,6 +436,65 @@ PyDoc_STRVAR(ssl_doc,
...
@@ -488,6 +436,65 @@ PyDoc_STRVAR(ssl_doc,
/* SSL object methods */
/* SSL object methods */
static
PyObject
*
PySSL_SSLdo_handshake
(
PySSLObject
*
self
)
{
int
ret
;
int
err
;
int
sockstate
;
/* Actually negotiate SSL connection */
/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
sockstate
=
0
;
do
{
PySSL_BEGIN_ALLOW_THREADS
ret
=
SSL_do_handshake
(
self
->
ssl
);
err
=
SSL_get_error
(
self
->
ssl
,
ret
);
PySSL_END_ALLOW_THREADS
if
(
PyErr_CheckSignals
())
{
return
NULL
;
}
if
(
err
==
SSL_ERROR_WANT_READ
)
{
sockstate
=
check_socket_and_wait_for_timeout
(
self
->
Socket
,
0
);
}
else
if
(
err
==
SSL_ERROR_WANT_WRITE
)
{
sockstate
=
check_socket_and_wait_for_timeout
(
self
->
Socket
,
1
);
}
else
{
sockstate
=
SOCKET_OPERATION_OK
;
}
if
(
sockstate
==
SOCKET_HAS_TIMED_OUT
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"The handshake operation timed out"
));
return
NULL
;
}
else
if
(
sockstate
==
SOCKET_HAS_BEEN_CLOSED
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"Underlying socket has been closed."
));
return
NULL
;
}
else
if
(
sockstate
==
SOCKET_TOO_LARGE_FOR_SELECT
)
{
PyErr_SetString
(
PySSLErrorObject
,
ERRSTR
(
"Underlying socket too large for select()."
));
return
NULL
;
}
else
if
(
sockstate
==
SOCKET_IS_NONBLOCKING
)
{
break
;
}
}
while
(
err
==
SSL_ERROR_WANT_READ
||
err
==
SSL_ERROR_WANT_WRITE
);
if
(
ret
<
1
)
return
PySSL_SetError
(
self
,
ret
,
__FILE__
,
__LINE__
);
self
->
ssl
->
debug
=
1
;
if
(
self
->
peer_cert
)
X509_free
(
self
->
peer_cert
);
PySSL_BEGIN_ALLOW_THREADS
if
((
self
->
peer_cert
=
SSL_get_peer_certificate
(
self
->
ssl
)))
{
X509_NAME_oneline
(
X509_get_subject_name
(
self
->
peer_cert
),
self
->
server
,
X509_NAME_MAXLEN
);
X509_NAME_oneline
(
X509_get_issuer_name
(
self
->
peer_cert
),
self
->
issuer
,
X509_NAME_MAXLEN
);
}
PySSL_END_ALLOW_THREADS
Py_INCREF
(
Py_None
);
return
Py_None
;
}
static
PyObject
*
static
PyObject
*
PySSL_server
(
PySSLObject
*
self
)
PySSL_server
(
PySSLObject
*
self
)
{
{
...
@@ -1127,7 +1134,9 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
...
@@ -1127,7 +1134,9 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
rc
=
select
(
s
->
sock_fd
+
1
,
&
fds
,
NULL
,
NULL
,
&
tv
);
rc
=
select
(
s
->
sock_fd
+
1
,
&
fds
,
NULL
,
NULL
,
&
tv
);
PySSL_END_ALLOW_THREADS
PySSL_END_ALLOW_THREADS
#ifdef HAVE_POLL
normal_return:
normal_return:
#endif
/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
(when we are able to write or when there's something to read) */
(when we are able to write or when there's something to read) */
return
rc
==
0
?
SOCKET_HAS_TIMED_OUT
:
SOCKET_OPERATION_OK
;
return
rc
==
0
?
SOCKET_HAS_TIMED_OUT
:
SOCKET_OPERATION_OK
;
...
@@ -1140,10 +1149,16 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
...
@@ -1140,10 +1149,16 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
int
count
;
int
count
;
int
sockstate
;
int
sockstate
;
int
err
;
int
err
;
int
nonblocking
;
if
(
!
PyArg_ParseTuple
(
args
,
"s#:write"
,
&
data
,
&
count
))
if
(
!
PyArg_ParseTuple
(
args
,
"s#:write"
,
&
data
,
&
count
))
return
NULL
;
return
NULL
;
/* just in case the blocking state of the socket has been changed */
nonblocking
=
(
self
->
Socket
->
sock_timeout
>=
0
.
0
);
BIO_set_nbio
(
SSL_get_rbio
(
self
->
ssl
),
nonblocking
);
BIO_set_nbio
(
SSL_get_wbio
(
self
->
ssl
),
nonblocking
);
sockstate
=
check_socket_and_wait_for_timeout
(
self
->
Socket
,
1
);
sockstate
=
check_socket_and_wait_for_timeout
(
self
->
Socket
,
1
);
if
(
sockstate
==
SOCKET_HAS_TIMED_OUT
)
{
if
(
sockstate
==
SOCKET_HAS_TIMED_OUT
)
{
PyErr_SetString
(
PySSLErrorObject
,
PyErr_SetString
(
PySSLErrorObject
,
...
@@ -1200,6 +1215,25 @@ PyDoc_STRVAR(PySSL_SSLwrite_doc,
...
@@ -1200,6 +1215,25 @@ PyDoc_STRVAR(PySSL_SSLwrite_doc,
Writes the string s into the SSL object. Returns the number
\n
\
Writes the string s into the SSL object. Returns the number
\n
\
of bytes written."
);
of bytes written."
);
static
PyObject
*
PySSL_SSLpending
(
PySSLObject
*
self
)
{
int
count
=
0
;
PySSL_BEGIN_ALLOW_THREADS
count
=
SSL_pending
(
self
->
ssl
);
PySSL_END_ALLOW_THREADS
if
(
count
<
0
)
return
PySSL_SetError
(
self
,
count
,
__FILE__
,
__LINE__
);
else
return
PyInt_FromLong
(
count
);
}
PyDoc_STRVAR
(
PySSL_SSLpending_doc
,
"pending() -> count
\n
\
\n
\
Returns the number of already decrypted bytes available for read,
\n
\
pending on the connection.
\n
"
);
static
PyObject
*
PySSL_SSLread
(
PySSLObject
*
self
,
PyObject
*
args
)
static
PyObject
*
PySSL_SSLread
(
PySSLObject
*
self
,
PyObject
*
args
)
{
{
PyObject
*
buf
;
PyObject
*
buf
;
...
@@ -1207,6 +1241,7 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
...
@@ -1207,6 +1241,7 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
int
len
=
1024
;
int
len
=
1024
;
int
sockstate
;
int
sockstate
;
int
err
;
int
err
;
int
nonblocking
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:read"
,
&
len
))
if
(
!
PyArg_ParseTuple
(
args
,
"|i:read"
,
&
len
))
return
NULL
;
return
NULL
;
...
@@ -1214,6 +1249,11 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
...
@@ -1214,6 +1249,11 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
if
(
!
(
buf
=
PyString_FromStringAndSize
((
char
*
)
0
,
len
)))
if
(
!
(
buf
=
PyString_FromStringAndSize
((
char
*
)
0
,
len
)))
return
NULL
;
return
NULL
;
/* just in case the blocking state of the socket has been changed */
nonblocking
=
(
self
->
Socket
->
sock_timeout
>=
0
.
0
);
BIO_set_nbio
(
SSL_get_rbio
(
self
->
ssl
),
nonblocking
);
BIO_set_nbio
(
SSL_get_wbio
(
self
->
ssl
),
nonblocking
);
/* first check if there are bytes ready to be read */
/* first check if there are bytes ready to be read */
PySSL_BEGIN_ALLOW_THREADS
PySSL_BEGIN_ALLOW_THREADS
count
=
SSL_pending
(
self
->
ssl
);
count
=
SSL_pending
(
self
->
ssl
);
...
@@ -1232,9 +1272,18 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
...
@@ -1232,9 +1272,18 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
Py_DECREF
(
buf
);
Py_DECREF
(
buf
);
return
NULL
;
return
NULL
;
}
else
if
(
sockstate
==
SOCKET_HAS_BEEN_CLOSED
)
{
}
else
if
(
sockstate
==
SOCKET_HAS_BEEN_CLOSED
)
{
/* should contain a zero-length string */
if
(
SSL_get_shutdown
(
self
->
ssl
)
!=
_PyString_Resize
(
&
buf
,
0
);
SSL_RECEIVED_SHUTDOWN
)
return
buf
;
{
Py_DECREF
(
buf
);
PyErr_SetString
(
PySSLErrorObject
,
"Socket closed without SSL shutdown handshake"
);
return
NULL
;
}
else
{
/* should contain a zero-length string */
_PyString_Resize
(
&
buf
,
0
);
return
buf
;
}
}
}
}
}
do
{
do
{
...
@@ -1285,16 +1334,54 @@ PyDoc_STRVAR(PySSL_SSLread_doc,
...
@@ -1285,16 +1334,54 @@ PyDoc_STRVAR(PySSL_SSLread_doc,
\n
\
\n
\
Read up to len bytes from the SSL socket."
);
Read up to len bytes from the SSL socket."
);
static
PyObject
*
PySSL_SSLshutdown
(
PySSLObject
*
self
)
{
int
err
;
/* Guard against closed socket */
if
(
self
->
Socket
->
sock_fd
<
0
)
{
PyErr_SetString
(
PySSLErrorObject
,
"Underlying socket has been closed."
);
return
NULL
;
}
PySSL_BEGIN_ALLOW_THREADS
err
=
SSL_shutdown
(
self
->
ssl
);
if
(
err
==
0
)
{
/* we need to call it again to finish the shutdown */
err
=
SSL_shutdown
(
self
->
ssl
);
}
PySSL_END_ALLOW_THREADS
if
(
err
<
0
)
return
PySSL_SetError
(
self
,
err
,
__FILE__
,
__LINE__
);
else
{
Py_INCREF
(
self
->
Socket
);
return
(
PyObject
*
)
(
self
->
Socket
);
}
}
PyDoc_STRVAR
(
PySSL_SSLshutdown_doc
,
"shutdown(s) -> socket
\n
\
\n
\
Does the SSL shutdown handshake with the remote end, and returns
\n
\
the underlying socket object."
);
static
PyMethodDef
PySSLMethods
[]
=
{
static
PyMethodDef
PySSLMethods
[]
=
{
{
"do_handshake"
,
(
PyCFunction
)
PySSL_SSLdo_handshake
,
METH_NOARGS
},
{
"write"
,
(
PyCFunction
)
PySSL_SSLwrite
,
METH_VARARGS
,
{
"write"
,
(
PyCFunction
)
PySSL_SSLwrite
,
METH_VARARGS
,
PySSL_SSLwrite_doc
},
PySSL_SSLwrite_doc
},
{
"read"
,
(
PyCFunction
)
PySSL_SSLread
,
METH_VARARGS
,
{
"read"
,
(
PyCFunction
)
PySSL_SSLread
,
METH_VARARGS
,
PySSL_SSLread_doc
},
PySSL_SSLread_doc
},
{
"pending"
,
(
PyCFunction
)
PySSL_SSLpending
,
METH_NOARGS
,
PySSL_SSLpending_doc
},
{
"server"
,
(
PyCFunction
)
PySSL_server
,
METH_NOARGS
},
{
"server"
,
(
PyCFunction
)
PySSL_server
,
METH_NOARGS
},
{
"issuer"
,
(
PyCFunction
)
PySSL_issuer
,
METH_NOARGS
},
{
"issuer"
,
(
PyCFunction
)
PySSL_issuer
,
METH_NOARGS
},
{
"peer_certificate"
,
(
PyCFunction
)
PySSL_peercert
,
METH_VARARGS
,
{
"peer_certificate"
,
(
PyCFunction
)
PySSL_peercert
,
METH_VARARGS
,
PySSL_peercert_doc
},
PySSL_peercert_doc
},
{
"cipher"
,
(
PyCFunction
)
PySSL_cipher
,
METH_NOARGS
},
{
"cipher"
,
(
PyCFunction
)
PySSL_cipher
,
METH_NOARGS
},
{
"shutdown"
,
(
PyCFunction
)
PySSL_SSLshutdown
,
METH_NOARGS
,
PySSL_SSLshutdown_doc
},
{
NULL
,
NULL
}
{
NULL
,
NULL
}
};
};
...
...
Write
Preview
Markdown
is supported
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