|
8 | 8 | */ |
9 | 9 |
|
10 | 10 | #include "Python.h" |
| 11 | +enum py_ssl_error { |
| 12 | + /* these mirror ssl.h */ |
| 13 | + PY_SSL_ERROR_NONE, |
| 14 | + PY_SSL_ERROR_SSL, |
| 15 | + PY_SSL_ERROR_WANT_READ, |
| 16 | + PY_SSL_ERROR_WANT_WRITE, |
| 17 | + PY_SSL_ERROR_WANT_X509_LOOKUP, |
| 18 | + PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */ |
| 19 | + PY_SSL_ERROR_ZERO_RETURN, |
| 20 | + PY_SSL_ERROR_WANT_CONNECT, |
| 21 | + /* start of non ssl.h errorcodes */ |
| 22 | + PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */ |
| 23 | + PY_SSL_ERROR_INVALID_ERROR_CODE |
| 24 | +}; |
11 | 25 |
|
12 | 26 | /* Include symbols from _socket module */ |
13 | 27 | #include "socketmodule.h" |
@@ -64,53 +78,79 @@ PySSL_SetError(PySSLObject *obj, int ret) |
64 | 78 | PyObject *v, *n, *s; |
65 | 79 | char *errstr; |
66 | 80 | int err; |
| 81 | + enum py_ssl_error p; |
67 | 82 |
|
68 | 83 | assert(ret <= 0); |
69 | 84 |
|
70 | 85 | err = SSL_get_error(obj->ssl, ret); |
71 | | - n = PyInt_FromLong(err); |
72 | | - if (n == NULL) |
73 | | - return NULL; |
74 | | - v = PyTuple_New(2); |
75 | | - if (v == NULL) { |
76 | | - Py_DECREF(n); |
77 | | - return NULL; |
78 | | - } |
79 | 86 |
|
80 | | - switch (SSL_get_error(obj->ssl, ret)) { |
| 87 | + switch (err) { |
81 | 88 | case SSL_ERROR_ZERO_RETURN: |
82 | 89 | errstr = "TLS/SSL connection has been closed"; |
| 90 | + p=PY_SSL_ERROR_ZERO_RETURN; |
83 | 91 | break; |
84 | 92 | case SSL_ERROR_WANT_READ: |
85 | 93 | errstr = "The operation did not complete (read)"; |
| 94 | + p=PY_SSL_ERROR_WANT_READ; |
86 | 95 | break; |
87 | 96 | case SSL_ERROR_WANT_WRITE: |
| 97 | + p=PY_SSL_ERROR_WANT_WRITE; |
88 | 98 | errstr = "The operation did not complete (write)"; |
89 | 99 | break; |
90 | 100 | case SSL_ERROR_WANT_X509_LOOKUP: |
| 101 | + p=PY_SSL_ERROR_WANT_X509_LOOKUP; |
91 | 102 | errstr = "The operation did not complete (X509 lookup)"; |
92 | 103 | break; |
| 104 | + case SSL_ERROR_WANT_CONNECT: |
| 105 | + p=PY_SSL_ERROR_WANT_CONNECT; |
| 106 | + errstr = "The operation did not complete (connect)"; |
| 107 | + break; |
93 | 108 | case SSL_ERROR_SYSCALL: |
94 | | - case SSL_ERROR_SSL: |
95 | 109 | { |
96 | 110 | unsigned long e = ERR_get_error(); |
97 | | - if (e == 0) { |
98 | | - /* an EOF was observed that violates the protocol */ |
99 | | - errstr = "EOF occurred in violation of protocol"; |
100 | | - } else if (e == -1) { |
101 | | - /* the underlying BIO reported an I/O error */ |
102 | | - Py_DECREF(v); |
103 | | - Py_DECREF(n); |
104 | | - return obj->Socket->errorhandler(); |
| 111 | + if(e==0){ |
| 112 | + if(ret==0){ |
| 113 | + p=PY_SSL_ERROR_EOF; |
| 114 | + errstr = "EOF occurred in violation of protocol"; |
| 115 | + }else if(ret==-1){ |
| 116 | + /* the underlying BIO reported an I/O error */ |
| 117 | + return obj->Socket->errorhandler(); |
| 118 | + }else{ /* possible? */ |
| 119 | + p=PY_SSL_ERROR_SYSCALL; |
| 120 | + errstr = "Some I/O error occurred"; |
| 121 | + } |
105 | 122 | } else { |
| 123 | + p=PY_SSL_ERROR_SYSCALL; |
| 124 | + /* XXX Protected by global interpreter lock */ |
| 125 | + errstr = ERR_error_string(e, NULL); |
| 126 | + } |
| 127 | + break; |
| 128 | + } |
| 129 | + case SSL_ERROR_SSL: |
| 130 | + { |
| 131 | + unsigned long e = ERR_get_error(); |
| 132 | + p=PY_SSL_ERROR_SSL; |
| 133 | + if (e !=0) { |
106 | 134 | /* XXX Protected by global interpreter lock */ |
107 | 135 | errstr = ERR_error_string(e, NULL); |
| 136 | + } else { /* possible? */ |
| 137 | + errstr="A failure in the SSL library occurred"; |
108 | 138 | } |
109 | 139 | break; |
110 | 140 | } |
111 | 141 | default: |
| 142 | + p=PY_SSL_ERROR_INVALID_ERROR_CODE; |
112 | 143 | errstr = "Invalid error code"; |
113 | 144 | } |
| 145 | + n = PyInt_FromLong((long) p); |
| 146 | + if (n == NULL) |
| 147 | + return NULL; |
| 148 | + v = PyTuple_New(2); |
| 149 | + if (v == NULL) { |
| 150 | + Py_DECREF(n); |
| 151 | + return NULL; |
| 152 | + } |
| 153 | + |
114 | 154 | s = PyString_FromString(errstr); |
115 | 155 | if (s == NULL) { |
116 | 156 | Py_DECREF(v); |
@@ -447,15 +487,23 @@ init_ssl(void) |
447 | 487 | (PyObject *)&PySSL_Type) != 0) |
448 | 488 | return; |
449 | 489 | PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", |
450 | | - SSL_ERROR_ZERO_RETURN); |
| 490 | + PY_SSL_ERROR_ZERO_RETURN); |
451 | 491 | PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", |
452 | | - SSL_ERROR_WANT_READ); |
| 492 | + PY_SSL_ERROR_WANT_READ); |
453 | 493 | PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", |
454 | | - SSL_ERROR_WANT_WRITE); |
| 494 | + PY_SSL_ERROR_WANT_WRITE); |
455 | 495 | PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", |
456 | | - SSL_ERROR_WANT_X509_LOOKUP); |
| 496 | + PY_SSL_ERROR_WANT_X509_LOOKUP); |
457 | 497 | PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", |
458 | | - SSL_ERROR_SYSCALL); |
| 498 | + PY_SSL_ERROR_SYSCALL); |
459 | 499 | PyModule_AddIntConstant(m, "SSL_ERROR_SSL", |
460 | | - SSL_ERROR_SSL); |
| 500 | + PY_SSL_ERROR_SSL); |
| 501 | + PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", |
| 502 | + PY_SSL_ERROR_WANT_CONNECT); |
| 503 | + /* non ssl.h errorcodes */ |
| 504 | + PyModule_AddIntConstant(m, "SSL_ERROR_EOF", |
| 505 | + PY_SSL_ERROR_EOF); |
| 506 | + PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", |
| 507 | + PY_SSL_ERROR_INVALID_ERROR_CODE); |
| 508 | + |
461 | 509 | } |
0 commit comments