From: Martin v. Löwis Date: Sat, 20 Apr 2002 07:45:25 +0000 (+0000) Subject: Patch #500311: Work around for buggy https servers. Fixes #494762. X-Git-Tag: v2.2.2b1~413 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b390f5f73b6b8fdc36c82e46460f8428c42cd1b7;p=thirdparty%2FPython%2Fcpython.git Patch #500311: Work around for buggy https servers. Fixes #494762. --- diff --git a/Lib/httplib.py b/Lib/httplib.py index d244351ef37e..cbe6e8ffee58 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -631,7 +631,8 @@ class FakeSocket: or err[0] == socket.SSL_ERROR_WANT_WRITE or 0): 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 raise except socket.error, err: diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 182496c2b173..47ddcd54141d 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -282,6 +282,20 @@ static PyObject *PyGAI_Error; #ifdef USE_SSL static PyObject *PySSLErrorObject; +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 +}; #endif /* USE_SSL */ @@ -2631,53 +2645,79 @@ PySSL_SetError(SSL *ssl, int ret) PyObject *v, *n, *s; char *errstr; int err; + enum py_ssl_error p; assert(ret <= 0); err = SSL_get_error(ssl, ret); - n = PyInt_FromLong(err); - if (n == NULL) - return NULL; - v = PyTuple_New(2); - if (v == NULL) { - Py_DECREF(n); - return NULL; - } - switch (SSL_get_error(ssl, ret)) { + 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: - 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 PySocket_Err(); + 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 PySocket_Err(); + }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) + return NULL; + v = PyTuple_New(2); + if (v == NULL) { + Py_DECREF(n); + return NULL; + } + s = PyString_FromString(errstr); if (s == NULL) { Py_DECREF(v); @@ -3175,17 +3215,25 @@ init_socket(void) (PyObject *)&PySSL_Type) != 0) return; PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", - SSL_ERROR_ZERO_RETURN); + PY_SSL_ERROR_ZERO_RETURN); PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", - SSL_ERROR_WANT_READ); + PY_SSL_ERROR_WANT_READ); PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", - SSL_ERROR_WANT_WRITE); + PY_SSL_ERROR_WANT_WRITE); 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", - SSL_ERROR_SYSCALL); + PY_SSL_ERROR_SYSCALL); 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); + #endif /* USE_SSL */ if (PyDict_SetItemString(d, "SocketType", (PyObject *)&PySocketSock_Type) != 0)