mirror of
https://github.com/python/cpython.git
synced 2025-08-27 04:05:34 +00:00
Forward port of patch # 500311: Work around for buggy https servers.
Fixes #494762.
This commit is contained in:
parent
954aed8c8d
commit
6af3e2dc31
3 changed files with 92 additions and 42 deletions
|
@ -633,7 +633,8 @@ class FakeSocket:
|
||||||
if (err[0] == socket.SSL_ERROR_WANT_READ
|
if (err[0] == socket.SSL_ERROR_WANT_READ
|
||||||
or err[0] == socket.SSL_ERROR_WANT_WRITE):
|
or err[0] == socket.SSL_ERROR_WANT_WRITE):
|
||||||
continue
|
continue
|
||||||
if err[0] == socket.SSL_ERROR_ZERO_RETURN:
|
if (err[0] == socket.SSL_ERROR_ZERO_RETURN
|
||||||
|
or err[0] == socket.SSL_ERROR_EOF):
|
||||||
break
|
break
|
||||||
raise
|
raise
|
||||||
except socket.error, err:
|
except socket.error, err:
|
||||||
|
|
|
@ -38,6 +38,7 @@ Reimer Behrends
|
||||||
Thomas Bellman
|
Thomas Bellman
|
||||||
Juan M. Bello Rivas
|
Juan M. Bello Rivas
|
||||||
Andy Bensky
|
Andy Bensky
|
||||||
|
Michel Van den Bergh
|
||||||
Eric Beser
|
Eric Beser
|
||||||
Stephen Bevan
|
Stephen Bevan
|
||||||
Ron Bickers
|
Ron Bickers
|
||||||
|
|
130
Modules/_ssl.c
130
Modules/_ssl.c
|
@ -8,6 +8,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
enum py_ssl_error {
|
||||||
|
/* these mirror ssl.h */
|
||||||
|
PY_SSL_ERROR_NONE,
|
||||||
|
PY_SSL_ERROR_SSL,
|
||||||
|
PY_SSL_ERROR_WANT_READ,
|
||||||
|
PY_SSL_ERROR_WANT_WRITE,
|
||||||
|
PY_SSL_ERROR_WANT_X509_LOOKUP,
|
||||||
|
PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */
|
||||||
|
PY_SSL_ERROR_ZERO_RETURN,
|
||||||
|
PY_SSL_ERROR_WANT_CONNECT,
|
||||||
|
/* start of non ssl.h errorcodes */
|
||||||
|
PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */
|
||||||
|
PY_SSL_ERROR_INVALID_ERROR_CODE
|
||||||
|
};
|
||||||
|
|
||||||
/* Include symbols from _socket module */
|
/* Include symbols from _socket module */
|
||||||
#include "socketmodule.h"
|
#include "socketmodule.h"
|
||||||
|
@ -64,11 +78,71 @@ PySSL_SetError(PySSLObject *obj, int ret)
|
||||||
PyObject *v, *n, *s;
|
PyObject *v, *n, *s;
|
||||||
char *errstr;
|
char *errstr;
|
||||||
int err;
|
int err;
|
||||||
|
enum py_ssl_error p;
|
||||||
|
|
||||||
assert(ret <= 0);
|
assert(ret <= 0);
|
||||||
|
|
||||||
err = SSL_get_error(obj->ssl, ret);
|
err = SSL_get_error(obj->ssl, ret);
|
||||||
n = PyInt_FromLong(err);
|
|
||||||
|
switch (err) {
|
||||||
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
|
errstr = "TLS/SSL connection has been closed";
|
||||||
|
p=PY_SSL_ERROR_ZERO_RETURN;
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
errstr = "The operation did not complete (read)";
|
||||||
|
p=PY_SSL_ERROR_WANT_READ;
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
p=PY_SSL_ERROR_WANT_WRITE;
|
||||||
|
errstr = "The operation did not complete (write)";
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||||
|
p=PY_SSL_ERROR_WANT_X509_LOOKUP;
|
||||||
|
errstr = "The operation did not complete (X509 lookup)";
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_WANT_CONNECT:
|
||||||
|
p=PY_SSL_ERROR_WANT_CONNECT;
|
||||||
|
errstr = "The operation did not complete (connect)";
|
||||||
|
break;
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
{
|
||||||
|
unsigned long e = ERR_get_error();
|
||||||
|
if(e==0){
|
||||||
|
if(ret==0){
|
||||||
|
p=PY_SSL_ERROR_EOF;
|
||||||
|
errstr = "EOF occurred in violation of protocol";
|
||||||
|
}else if(ret==-1){
|
||||||
|
/* the underlying BIO reported an I/O error */
|
||||||
|
return obj->Socket->errorhandler();
|
||||||
|
}else{ /* possible? */
|
||||||
|
p=PY_SSL_ERROR_SYSCALL;
|
||||||
|
errstr = "Some I/O error occurred";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p=PY_SSL_ERROR_SYSCALL;
|
||||||
|
/* XXX Protected by global interpreter lock */
|
||||||
|
errstr = ERR_error_string(e, NULL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SSL_ERROR_SSL:
|
||||||
|
{
|
||||||
|
unsigned long e = ERR_get_error();
|
||||||
|
p=PY_SSL_ERROR_SSL;
|
||||||
|
if (e !=0) {
|
||||||
|
/* XXX Protected by global interpreter lock */
|
||||||
|
errstr = ERR_error_string(e, NULL);
|
||||||
|
} else { /* possible? */
|
||||||
|
errstr="A failure in the SSL library occurred";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
p=PY_SSL_ERROR_INVALID_ERROR_CODE;
|
||||||
|
errstr = "Invalid error code";
|
||||||
|
}
|
||||||
|
n = PyInt_FromLong((long) p);
|
||||||
if (n == NULL)
|
if (n == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
v = PyTuple_New(2);
|
v = PyTuple_New(2);
|
||||||
|
@ -77,40 +151,6 @@ PySSL_SetError(PySSLObject *obj, int ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (SSL_get_error(obj->ssl, ret)) {
|
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
|
||||||
errstr = "TLS/SSL connection has been closed";
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
errstr = "The operation did not complete (read)";
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
errstr = "The operation did not complete (write)";
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
|
||||||
errstr = "The operation did not complete (X509 lookup)";
|
|
||||||
break;
|
|
||||||
case SSL_ERROR_SYSCALL:
|
|
||||||
case SSL_ERROR_SSL:
|
|
||||||
{
|
|
||||||
unsigned long e = ERR_get_error();
|
|
||||||
if (e == 0) {
|
|
||||||
/* an EOF was observed that violates the protocol */
|
|
||||||
errstr = "EOF occurred in violation of protocol";
|
|
||||||
} else if (e == -1) {
|
|
||||||
/* the underlying BIO reported an I/O error */
|
|
||||||
Py_DECREF(v);
|
|
||||||
Py_DECREF(n);
|
|
||||||
return obj->Socket->errorhandler();
|
|
||||||
} else {
|
|
||||||
/* XXX Protected by global interpreter lock */
|
|
||||||
errstr = ERR_error_string(e, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
errstr = "Invalid error code";
|
|
||||||
}
|
|
||||||
s = PyString_FromString(errstr);
|
s = PyString_FromString(errstr);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
@ -447,15 +487,23 @@ init_ssl(void)
|
||||||
(PyObject *)&PySSL_Type) != 0)
|
(PyObject *)&PySSL_Type) != 0)
|
||||||
return;
|
return;
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
|
PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
|
||||||
SSL_ERROR_ZERO_RETURN);
|
PY_SSL_ERROR_ZERO_RETURN);
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
|
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
|
||||||
SSL_ERROR_WANT_READ);
|
PY_SSL_ERROR_WANT_READ);
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
|
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
|
||||||
SSL_ERROR_WANT_WRITE);
|
PY_SSL_ERROR_WANT_WRITE);
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
|
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
|
||||||
SSL_ERROR_WANT_X509_LOOKUP);
|
PY_SSL_ERROR_WANT_X509_LOOKUP);
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
|
PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
|
||||||
SSL_ERROR_SYSCALL);
|
PY_SSL_ERROR_SYSCALL);
|
||||||
PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
|
PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
|
||||||
SSL_ERROR_SSL);
|
PY_SSL_ERROR_SSL);
|
||||||
|
PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
|
||||||
|
PY_SSL_ERROR_WANT_CONNECT);
|
||||||
|
/* non ssl.h errorcodes */
|
||||||
|
PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
|
||||||
|
PY_SSL_ERROR_EOF);
|
||||||
|
PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
|
||||||
|
PY_SSL_ERROR_INVALID_ERROR_CODE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue