blob: f1e1092ac7dad9eea6798c4e32db052d80f341b8 [file] [log] [blame]
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +00001/* SSL socket module
2
3 SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
4
5 This module is imported by socket.py. It should *not* be used
6 directly.
7
8*/
9
10#include "Python.h"
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +000011enum 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};
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000025
26/* Include symbols from _socket module */
27#include "socketmodule.h"
28
Thomas Wouters0e3f5912006-08-11 14:57:12 +000029#if defined(HAVE_POLL_H)
30#include <poll.h>
31#elif defined(HAVE_SYS_POLL_H)
32#include <sys/poll.h>
33#endif
34
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000035/* Include OpenSSL header files */
36#include "openssl/rsa.h"
37#include "openssl/crypto.h"
38#include "openssl/x509.h"
39#include "openssl/pem.h"
40#include "openssl/ssl.h"
41#include "openssl/err.h"
42#include "openssl/rand.h"
43
44/* SSL error object */
45static PyObject *PySSLErrorObject;
46
47/* SSL socket object */
48
49#define X509_NAME_MAXLEN 256
50
51/* RAND_* APIs got added to OpenSSL in 0.9.5 */
52#if OPENSSL_VERSION_NUMBER >= 0x0090500fL
53# define HAVE_OPENSSL_RAND 1
54#else
55# undef HAVE_OPENSSL_RAND
56#endif
57
58typedef struct {
59 PyObject_HEAD
60 PySocketSockObject *Socket; /* Socket on which we're layered */
61 SSL_CTX* ctx;
62 SSL* ssl;
63 X509* server_cert;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000064 char server[X509_NAME_MAXLEN];
65 char issuer[X509_NAME_MAXLEN];
66
67} PySSLObject;
68
Jeremy Hylton938ace62002-07-17 16:30:39 +000069static PyTypeObject PySSL_Type;
70static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
71static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +000072static int check_socket_and_wait_for_timeout(PySocketSockObject *s,
73 int writing);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000074
75#define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type)
76
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +000077typedef enum {
78 SOCKET_IS_NONBLOCKING,
79 SOCKET_IS_BLOCKING,
80 SOCKET_HAS_TIMED_OUT,
81 SOCKET_HAS_BEEN_CLOSED,
Neal Norwitz389cea82006-02-13 00:35:21 +000082 SOCKET_TOO_LARGE_FOR_SELECT,
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +000083 SOCKET_OPERATION_OK
84} timeout_state;
85
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000086/* XXX It might be helpful to augment the error message generated
87 below with the name of the SSL function that generated the error.
88 I expect it's obvious most of the time.
89*/
90
91static PyObject *
92PySSL_SetError(PySSLObject *obj, int ret)
93{
94 PyObject *v, *n, *s;
95 char *errstr;
96 int err;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +000097 enum py_ssl_error p;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +000098
99 assert(ret <= 0);
100
101 err = SSL_get_error(obj->ssl, ret);
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000102
103 switch (err) {
104 case SSL_ERROR_ZERO_RETURN:
105 errstr = "TLS/SSL connection has been closed";
Jeremy Hylton4e547302002-07-02 18:25:00 +0000106 p = PY_SSL_ERROR_ZERO_RETURN;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000107 break;
108 case SSL_ERROR_WANT_READ:
109 errstr = "The operation did not complete (read)";
Jeremy Hylton4e547302002-07-02 18:25:00 +0000110 p = PY_SSL_ERROR_WANT_READ;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000111 break;
112 case SSL_ERROR_WANT_WRITE:
Jeremy Hylton4e547302002-07-02 18:25:00 +0000113 p = PY_SSL_ERROR_WANT_WRITE;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000114 errstr = "The operation did not complete (write)";
115 break;
116 case SSL_ERROR_WANT_X509_LOOKUP:
Jeremy Hylton4e547302002-07-02 18:25:00 +0000117 p = PY_SSL_ERROR_WANT_X509_LOOKUP;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000118 errstr = "The operation did not complete (X509 lookup)";
119 break;
120 case SSL_ERROR_WANT_CONNECT:
Jeremy Hylton4e547302002-07-02 18:25:00 +0000121 p = PY_SSL_ERROR_WANT_CONNECT;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000122 errstr = "The operation did not complete (connect)";
123 break;
124 case SSL_ERROR_SYSCALL:
125 {
126 unsigned long e = ERR_get_error();
Jeremy Hylton4e547302002-07-02 18:25:00 +0000127 if (e == 0) {
Neal Norwitza9002f82003-06-30 03:25:20 +0000128 if (ret == 0 || !obj->Socket) {
Jeremy Hylton4e547302002-07-02 18:25:00 +0000129 p = PY_SSL_ERROR_EOF;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000130 errstr = "EOF occurred in violation of protocol";
Jeremy Hylton4e547302002-07-02 18:25:00 +0000131 } else if (ret == -1) {
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000132 /* the underlying BIO reported an I/O error */
133 return obj->Socket->errorhandler();
Jeremy Hylton4e547302002-07-02 18:25:00 +0000134 } else { /* possible? */
135 p = PY_SSL_ERROR_SYSCALL;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000136 errstr = "Some I/O error occurred";
137 }
138 } else {
Jeremy Hylton4e547302002-07-02 18:25:00 +0000139 p = PY_SSL_ERROR_SYSCALL;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000140 /* XXX Protected by global interpreter lock */
141 errstr = ERR_error_string(e, NULL);
142 }
143 break;
144 }
145 case SSL_ERROR_SSL:
146 {
147 unsigned long e = ERR_get_error();
Jeremy Hylton4e547302002-07-02 18:25:00 +0000148 p = PY_SSL_ERROR_SSL;
149 if (e != 0)
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000150 /* XXX Protected by global interpreter lock */
151 errstr = ERR_error_string(e, NULL);
Jeremy Hylton4e547302002-07-02 18:25:00 +0000152 else { /* possible? */
153 errstr = "A failure in the SSL library occurred";
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000154 }
155 break;
156 }
157 default:
Jeremy Hylton4e547302002-07-02 18:25:00 +0000158 p = PY_SSL_ERROR_INVALID_ERROR_CODE;
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000159 errstr = "Invalid error code";
160 }
161 n = PyInt_FromLong((long) p);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000162 if (n == NULL)
163 return NULL;
164 v = PyTuple_New(2);
165 if (v == NULL) {
166 Py_DECREF(n);
167 return NULL;
168 }
169
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000170 s = PyString_FromString(errstr);
171 if (s == NULL) {
172 Py_DECREF(v);
173 Py_DECREF(n);
174 }
175 PyTuple_SET_ITEM(v, 0, n);
176 PyTuple_SET_ITEM(v, 1, s);
177 PyErr_SetObject(PySSLErrorObject, v);
Michael W. Hudson5910d812004-08-04 14:59:00 +0000178 Py_DECREF(v);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000179 return NULL;
180}
181
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000182static PySSLObject *
183newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
184{
185 PySSLObject *self;
186 char *errstr = NULL;
187 int ret;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000188 int err;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000189 int sockstate;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000190
191 self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000192 if (self == NULL)
193 return NULL;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000194 memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
195 memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
196 self->server_cert = NULL;
197 self->ssl = NULL;
198 self->ctx = NULL;
199 self->Socket = NULL;
200
201 if ((key_file && !cert_file) || (!key_file && cert_file)) {
202 errstr = "Both the key & certificate files must be specified";
203 goto fail;
204 }
205
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000206 Py_BEGIN_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000207 self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000208 Py_END_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000209 if (self->ctx == NULL) {
210 errstr = "SSL_CTX_new error";
211 goto fail;
212 }
213
214 if (key_file) {
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000215 Py_BEGIN_ALLOW_THREADS
216 ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
217 SSL_FILETYPE_PEM);
218 Py_END_ALLOW_THREADS
219 if (ret < 1) {
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000220 errstr = "SSL_CTX_use_PrivateKey_file error";
221 goto fail;
222 }
223
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000224 Py_BEGIN_ALLOW_THREADS
225 ret = SSL_CTX_use_certificate_chain_file(self->ctx,
226 cert_file);
227 Py_END_ALLOW_THREADS
Andrew M. Kuchling27d3dda2004-07-10 21:36:55 +0000228 SSL_CTX_set_options(self->ctx, SSL_OP_ALL); /* ssl compatibility */
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000229 if (ret < 1) {
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000230 errstr = "SSL_CTX_use_certificate_chain_file error";
231 goto fail;
232 }
233 }
234
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000235 Py_BEGIN_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000236 SSL_CTX_set_verify(self->ctx,
237 SSL_VERIFY_NONE, NULL); /* set verify lvl */
238 self->ssl = SSL_new(self->ctx); /* New ssl struct */
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000239 Py_END_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000240 SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000241
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000242 /* If the socket is in non-blocking mode or timeout mode, set the BIO
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000243 * to non-blocking mode (blocking is the default)
244 */
245 if (Sock->sock_timeout >= 0.0) {
246 /* Set both the read and write BIO's to non-blocking mode */
247 BIO_set_nbio(SSL_get_rbio(self->ssl), 1);
248 BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
249 }
250
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000251 Py_BEGIN_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000252 SSL_set_connect_state(self->ssl);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000253 Py_END_ALLOW_THREADS
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000254
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000255 /* Actually negotiate SSL connection */
256 /* XXX If SSL_connect() returns 0, it's also a failure. */
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000257 sockstate = 0;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000258 do {
259 Py_BEGIN_ALLOW_THREADS
260 ret = SSL_connect(self->ssl);
261 err = SSL_get_error(self->ssl, ret);
262 Py_END_ALLOW_THREADS
Martin v. Löwisafec8e32003-06-28 07:40:23 +0000263 if(PyErr_CheckSignals()) {
264 goto fail;
265 }
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000266 if (err == SSL_ERROR_WANT_READ) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000267 sockstate = check_socket_and_wait_for_timeout(Sock, 0);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000268 } else if (err == SSL_ERROR_WANT_WRITE) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000269 sockstate = check_socket_and_wait_for_timeout(Sock, 1);
270 } else {
271 sockstate = SOCKET_OPERATION_OK;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000272 }
Neal Norwitz19cbcad2006-02-07 06:59:20 +0000273 if (sockstate == SOCKET_HAS_TIMED_OUT) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000274 PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
Martin v. Löwisafec8e32003-06-28 07:40:23 +0000275 goto fail;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000276 } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
277 PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
278 goto fail;
Neal Norwitz389cea82006-02-13 00:35:21 +0000279 } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
Neal Norwitz082b2df2006-02-07 07:04:46 +0000280 PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
281 goto fail;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000282 } else if (sockstate == SOCKET_IS_NONBLOCKING) {
283 break;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000284 }
285 } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000286 if (ret <= 0) {
287 PySSL_SetError(self, ret);
288 goto fail;
289 }
290 self->ssl->debug = 1;
291
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000292 Py_BEGIN_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000293 if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
294 X509_NAME_oneline(X509_get_subject_name(self->server_cert),
295 self->server, X509_NAME_MAXLEN);
296 X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
297 self->issuer, X509_NAME_MAXLEN);
298 }
Martin v. Löwis09c35f72002-07-28 09:57:45 +0000299 Py_END_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000300 self->Socket = Sock;
301 Py_INCREF(self->Socket);
302 return self;
303 fail:
304 if (errstr)
305 PyErr_SetString(PySSLErrorObject, errstr);
306 Py_DECREF(self);
307 return NULL;
308}
309
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000310static PyObject *
311PySocket_ssl(PyObject *self, PyObject *args)
312{
313 PySSLObject *rv;
314 PySocketSockObject *Sock;
315 char *key_file = NULL;
316 char *cert_file = NULL;
317
318 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
319 PySocketModule.Sock_Type,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000320 &Sock,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000321 &key_file, &cert_file))
322 return NULL;
323
324 rv = newPySSLObject(Sock, key_file, cert_file);
325 if (rv == NULL)
326 return NULL;
327 return (PyObject *)rv;
328}
329
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000330PyDoc_STRVAR(ssl_doc,
331"ssl(socket, [keyfile, certfile]) -> sslobject");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000332
333/* SSL object methods */
334
335static PyObject *
336PySSL_server(PySSLObject *self)
337{
338 return PyString_FromString(self->server);
339}
340
341static PyObject *
342PySSL_issuer(PySSLObject *self)
343{
344 return PyString_FromString(self->issuer);
345}
346
347
348static void PySSL_dealloc(PySSLObject *self)
349{
350 if (self->server_cert) /* Possible not to have one? */
351 X509_free (self->server_cert);
352 if (self->ssl)
353 SSL_free(self->ssl);
354 if (self->ctx)
355 SSL_CTX_free(self->ctx);
356 Py_XDECREF(self->Socket);
357 PyObject_Del(self);
358}
359
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000360/* If the socket has a timeout, do a select()/poll() on the socket.
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000361 The argument writing indicates the direction.
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000362 Returns one of the possibilities in the timeout_state enum (above).
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000363 */
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000364
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000365static int
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000366check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing)
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000367{
368 fd_set fds;
369 struct timeval tv;
370 int rc;
371
372 /* Nothing to do unless we're in timeout mode (not non-blocking) */
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000373 if (s->sock_timeout < 0.0)
374 return SOCKET_IS_BLOCKING;
375 else if (s->sock_timeout == 0.0)
376 return SOCKET_IS_NONBLOCKING;
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000377
378 /* Guard against closed socket */
379 if (s->sock_fd < 0)
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000380 return SOCKET_HAS_BEEN_CLOSED;
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000381
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000382 /* Prefer poll, if available, since you can poll() any fd
383 * which can't be done with select(). */
384#ifdef HAVE_POLL
385 {
386 struct pollfd pollfd;
387 int timeout;
388
389 pollfd.fd = s->sock_fd;
390 pollfd.events = writing ? POLLOUT : POLLIN;
391
392 /* s->sock_timeout is in seconds, timeout in ms */
393 timeout = (int)(s->sock_timeout * 1000 + 0.5);
394 Py_BEGIN_ALLOW_THREADS
395 rc = poll(&pollfd, 1, timeout);
396 Py_END_ALLOW_THREADS
397
398 goto normal_return;
399 }
400#endif
401
Neal Norwitz082b2df2006-02-07 07:04:46 +0000402 /* Guard against socket too large for select*/
Martin v. Löwisf84d1b92006-02-11 09:27:05 +0000403#ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE
Neal Norwitz082b2df2006-02-07 07:04:46 +0000404 if (s->sock_fd >= FD_SETSIZE)
Neal Norwitz389cea82006-02-13 00:35:21 +0000405 return SOCKET_TOO_LARGE_FOR_SELECT;
Martin v. Löwisf84d1b92006-02-11 09:27:05 +0000406#endif
Neal Norwitz082b2df2006-02-07 07:04:46 +0000407
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000408 /* Construct the arguments to select */
409 tv.tv_sec = (int)s->sock_timeout;
410 tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
411 FD_ZERO(&fds);
412 FD_SET(s->sock_fd, &fds);
413
414 /* See if the socket is ready */
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000415 Py_BEGIN_ALLOW_THREADS
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000416 if (writing)
417 rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
418 else
419 rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000420 Py_END_ALLOW_THREADS
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000421
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000422normal_return:
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000423 /* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise
424 (when we are able to write or when there's something to read) */
425 return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK;
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000426}
427
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000428static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
429{
430 char *data;
431 int len;
Martin v. Löwis405a7952003-10-27 14:24:37 +0000432 int count;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000433 int sockstate;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000434 int err;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000435
Martin v. Löwis405a7952003-10-27 14:24:37 +0000436 if (!PyArg_ParseTuple(args, "s#:write", &data, &count))
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000437 return NULL;
438
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000439 sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
440 if (sockstate == SOCKET_HAS_TIMED_OUT) {
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000441 PyErr_SetString(PySSLErrorObject, "The write operation timed out");
442 return NULL;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000443 } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
444 PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
445 return NULL;
Neal Norwitz389cea82006-02-13 00:35:21 +0000446 } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
Neal Norwitz082b2df2006-02-07 07:04:46 +0000447 PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
448 return NULL;
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000449 }
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000450 do {
451 err = 0;
452 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis405a7952003-10-27 14:24:37 +0000453 len = SSL_write(self->ssl, data, count);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000454 err = SSL_get_error(self->ssl, len);
455 Py_END_ALLOW_THREADS
Martin v. Löwisafec8e32003-06-28 07:40:23 +0000456 if(PyErr_CheckSignals()) {
457 return NULL;
458 }
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000459 if (err == SSL_ERROR_WANT_READ) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000460 sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000461 } else if (err == SSL_ERROR_WANT_WRITE) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000462 sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
463 } else {
464 sockstate = SOCKET_OPERATION_OK;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000465 }
Neal Norwitz19cbcad2006-02-07 06:59:20 +0000466 if (sockstate == SOCKET_HAS_TIMED_OUT) {
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000467 PyErr_SetString(PySSLErrorObject, "The write operation timed out");
468 return NULL;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000469 } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
470 PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed.");
471 return NULL;
472 } else if (sockstate == SOCKET_IS_NONBLOCKING) {
473 break;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000474 }
475 } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000476 if (len > 0)
477 return PyInt_FromLong(len);
478 else
479 return PySSL_SetError(self, len);
480}
481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000482PyDoc_STRVAR(PySSL_SSLwrite_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000483"write(s) -> len\n\
484\n\
485Writes the string s into the SSL object. Returns the number\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000486of bytes written.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000487
488static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
489{
490 PyObject *buf;
491 int count = 0;
492 int len = 1024;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000493 int sockstate;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000494 int err;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000495
496 if (!PyArg_ParseTuple(args, "|i:read", &len))
497 return NULL;
498
499 if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
500 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000501
502 /* first check if there are bytes ready to be read */
503 Py_BEGIN_ALLOW_THREADS
504 count = SSL_pending(self->ssl);
505 Py_END_ALLOW_THREADS
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000506
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000507 if (!count) {
508 sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
509 if (sockstate == SOCKET_HAS_TIMED_OUT) {
510 PyErr_SetString(PySSLErrorObject, "The read operation timed out");
511 Py_DECREF(buf);
512 return NULL;
513 } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
514 PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
515 return NULL;
516 }
Guido van Rossum99d4abf2003-01-27 22:22:50 +0000517 }
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000518 do {
519 err = 0;
520 Py_BEGIN_ALLOW_THREADS
521 count = SSL_read(self->ssl, PyString_AsString(buf), len);
522 err = SSL_get_error(self->ssl, count);
523 Py_END_ALLOW_THREADS
Martin v. Löwisafec8e32003-06-28 07:40:23 +0000524 if(PyErr_CheckSignals()) {
525 Py_DECREF(buf);
526 return NULL;
527 }
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000528 if (err == SSL_ERROR_WANT_READ) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000529 sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000530 } else if (err == SSL_ERROR_WANT_WRITE) {
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000531 sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
532 } else {
533 sockstate = SOCKET_OPERATION_OK;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000534 }
Neal Norwitz19cbcad2006-02-07 06:59:20 +0000535 if (sockstate == SOCKET_HAS_TIMED_OUT) {
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000536 PyErr_SetString(PySSLErrorObject, "The read operation timed out");
Martin v. Löwisafec8e32003-06-28 07:40:23 +0000537 Py_DECREF(buf);
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000538 return NULL;
Andrew M. Kuchling9c3efe32004-07-10 21:15:17 +0000539 } else if (sockstate == SOCKET_IS_NONBLOCKING) {
540 break;
Guido van Rossum4f707ac2003-01-31 18:13:18 +0000541 }
542 } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000543 if (count <= 0) {
544 Py_DECREF(buf);
545 return PySSL_SetError(self, count);
546 }
Tim Peters5de98422002-04-27 18:44:32 +0000547 if (count != len)
548 _PyString_Resize(&buf, count);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000549 return buf;
550}
551
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000552PyDoc_STRVAR(PySSL_SSLread_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000553"read([len]) -> string\n\
554\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000555Read up to len bytes from the SSL socket.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000556
557static PyMethodDef PySSLMethods[] = {
558 {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
559 PySSL_SSLwrite_doc},
560 {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
561 PySSL_SSLread_doc},
562 {"server", (PyCFunction)PySSL_server, METH_NOARGS},
563 {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
564 {NULL, NULL}
565};
566
567static PyObject *PySSL_getattr(PySSLObject *self, char *name)
568{
569 return Py_FindMethod(PySSLMethods, (PyObject *)self, name);
570}
571
Jeremy Hylton938ace62002-07-17 16:30:39 +0000572static PyTypeObject PySSL_Type = {
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000573 PyObject_HEAD_INIT(NULL)
574 0, /*ob_size*/
575 "socket.SSL", /*tp_name*/
576 sizeof(PySSLObject), /*tp_basicsize*/
577 0, /*tp_itemsize*/
578 /* methods */
579 (destructor)PySSL_dealloc, /*tp_dealloc*/
580 0, /*tp_print*/
581 (getattrfunc)PySSL_getattr, /*tp_getattr*/
582 0, /*tp_setattr*/
583 0, /*tp_compare*/
584 0, /*tp_repr*/
585 0, /*tp_as_number*/
586 0, /*tp_as_sequence*/
587 0, /*tp_as_mapping*/
588 0, /*tp_hash*/
589};
590
591#ifdef HAVE_OPENSSL_RAND
592
593/* helper routines for seeding the SSL PRNG */
594static PyObject *
595PySSL_RAND_add(PyObject *self, PyObject *args)
596{
597 char *buf;
598 int len;
599 double entropy;
600
601 if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
602 return NULL;
603 RAND_add(buf, len, entropy);
604 Py_INCREF(Py_None);
605 return Py_None;
606}
607
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000608PyDoc_STRVAR(PySSL_RAND_add_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000609"RAND_add(string, entropy)\n\
610\n\
611Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000612bound on the entropy contained in string.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000613
614static PyObject *
615PySSL_RAND_status(PyObject *self)
616{
617 return PyInt_FromLong(RAND_status());
618}
619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000620PyDoc_STRVAR(PySSL_RAND_status_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000621"RAND_status() -> 0 or 1\n\
622\n\
623Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
624It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000625using the ssl() function.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000626
627static PyObject *
628PySSL_RAND_egd(PyObject *self, PyObject *arg)
629{
630 int bytes;
631
632 if (!PyString_Check(arg))
633 return PyErr_Format(PyExc_TypeError,
634 "RAND_egd() expected string, found %s",
635 arg->ob_type->tp_name);
636 bytes = RAND_egd(PyString_AS_STRING(arg));
637 if (bytes == -1) {
638 PyErr_SetString(PySSLErrorObject,
639 "EGD connection failed or EGD did not return "
640 "enough data to seed the PRNG");
641 return NULL;
642 }
643 return PyInt_FromLong(bytes);
644}
645
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000646PyDoc_STRVAR(PySSL_RAND_egd_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000647"RAND_egd(path) -> bytes\n\
648\n\
649Queries the entropy gather daemon (EGD) on socket path. Returns number\n\
650of bytes read. Raises socket.sslerror if connection to EGD fails or\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000651if it does provide enough data to seed PRNG.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000652
653#endif
654
655/* List of functions exported by this module. */
656
657static PyMethodDef PySSL_methods[] = {
658 {"ssl", PySocket_ssl,
659 METH_VARARGS, ssl_doc},
660#ifdef HAVE_OPENSSL_RAND
661 {"RAND_add", PySSL_RAND_add, METH_VARARGS,
662 PySSL_RAND_add_doc},
663 {"RAND_egd", PySSL_RAND_egd, METH_O,
664 PySSL_RAND_egd_doc},
665 {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS,
666 PySSL_RAND_status_doc},
667#endif
668 {NULL, NULL} /* Sentinel */
669};
670
671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000672PyDoc_STRVAR(module_doc,
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000673"Implementation module for SSL socket operations. See the socket module\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000674for documentation.");
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000675
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000676PyMODINIT_FUNC
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000677init_ssl(void)
678{
679 PyObject *m, *d;
680
681 PySSL_Type.ob_type = &PyType_Type;
682
683 m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000684 if (m == NULL)
685 return;
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000686 d = PyModule_GetDict(m);
687
688 /* Load _socket module and its C API */
689 if (PySocketModule_ImportModuleAndAPI())
690 return;
691
692 /* Init OpenSSL */
693 SSL_load_error_strings();
694 SSLeay_add_ssl_algorithms();
695
696 /* Add symbols to module dict */
Brett Cannon06c34792004-03-23 23:16:54 +0000697 PySSLErrorObject = PyErr_NewException("socket.sslerror",
698 PySocketModule.error,
699 NULL);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000700 if (PySSLErrorObject == NULL)
701 return;
702 PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
703 if (PyDict_SetItemString(d, "SSLType",
704 (PyObject *)&PySSL_Type) != 0)
705 return;
706 PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000707 PY_SSL_ERROR_ZERO_RETURN);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000708 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000709 PY_SSL_ERROR_WANT_READ);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000710 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000711 PY_SSL_ERROR_WANT_WRITE);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000712 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000713 PY_SSL_ERROR_WANT_X509_LOOKUP);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000714 PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000715 PY_SSL_ERROR_SYSCALL);
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000716 PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
Martin v. Löwis6af3e2d2002-04-20 07:47:40 +0000717 PY_SSL_ERROR_SSL);
718 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
719 PY_SSL_ERROR_WANT_CONNECT);
720 /* non ssl.h errorcodes */
721 PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
722 PY_SSL_ERROR_EOF);
723 PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
724 PY_SSL_ERROR_INVALID_ERROR_CODE);
725
Marc-André Lemburga5d2b4c2002-02-16 18:23:30 +0000726}