blob: 885f66d0eb771f7041554f764844d888a39172f5 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * connection.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * SSL Connection objects and methods.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
12#define SSL_MODULE
13#include <openssl/err.h>
14#include "ssl.h"
15
16#ifndef MS_WINDOWS
17# include <sys/socket.h>
18# include <netinet/in.h>
19# if !(defined(__BEOS__) || defined(__CYGWIN__))
20# include <netinet/tcp.h>
21# endif
22#else
23# include <winsock.h>
24#endif
25
26static char *CVSid = "@(#) $Id: connection.c,v 1.28 2004/08/06 10:21:56 martin Exp $";
27
28
29/**
30 * If we are on UNIX, fine, just use PyErr_SetFromErrno. If we are on Windows,
31 * apply some black winsock voodoo. This is basically just copied from Python's
32 * socketmodule.c
33 *
34 * Arguments: None
35 * Returns: None
36 */
37static void
38syscall_from_errno(void)
39{
40#ifdef MS_WINDOWS
41 int errnum = WSAGetLastError();
42 if (errnum)
43 {
44 static struct { int num; const char *msg; } *msgp, msgs[] = {
45 { WSAEINTR, "Interrupted system call" },
46 { WSAEBADF, "Bad file descriptor" },
47 { WSAEACCES, "Permission denied" },
48 { WSAEFAULT, "Bad address" },
49 { WSAEINVAL, "Invalid argument" },
50 { WSAEMFILE, "Too many open files" },
51 { WSAEWOULDBLOCK, "The socket operation could not complete "
52 "without blocking" },
53 { WSAEINPROGRESS, "Operation now in progress" },
54 { WSAEALREADY, "Operation already in progress" },
55 { WSAENOTSOCK, "Socket operation on non-socket" },
56 { WSAEDESTADDRREQ, "Destination address required" },
57 { WSAEMSGSIZE, "Message too long" },
58 { WSAEPROTOTYPE, "Protocol wrong type for socket" },
59 { WSAENOPROTOOPT, "Protocol not available" },
60 { WSAEPROTONOSUPPORT, "Protocol not supported" },
61 { WSAESOCKTNOSUPPORT, "Socket type not supported" },
62 { WSAEOPNOTSUPP, "Operation not supported" },
63 { WSAEPFNOSUPPORT, "Protocol family not supported" },
64 { WSAEAFNOSUPPORT, "Address family not supported" },
65 { WSAEADDRINUSE, "Address already in use" },
66 { WSAEADDRNOTAVAIL, "Can't assign requested address" },
67 { WSAENETDOWN, "Network is down" },
68 { WSAENETUNREACH, "Network is unreachable" },
69 { WSAENETRESET, "Network dropped connection on reset" },
70 { WSAECONNABORTED, "Software caused connection abort" },
71 { WSAECONNRESET, "Connection reset by peer" },
72 { WSAENOBUFS, "No buffer space available" },
73 { WSAEISCONN, "Socket is already connected" },
74 { WSAENOTCONN, "Socket is not connected" },
75 { WSAESHUTDOWN, "Can't send after socket shutdown" },
76 { WSAETOOMANYREFS, "Too many references: can't splice" },
77 { WSAETIMEDOUT, "Operation timed out" },
78 { WSAECONNREFUSED, "Connection refused" },
79 { WSAELOOP, "Too many levels of symbolic links" },
80 { WSAENAMETOOLONG, "File name too long" },
81 { WSAEHOSTDOWN, "Host is down" },
82 { WSAEHOSTUNREACH, "No route to host" },
83 { WSAENOTEMPTY, "Directory not empty" },
84 { WSAEPROCLIM, "Too many processes" },
85 { WSAEUSERS, "Too many users" },
86 { WSAEDQUOT, "Disc quota exceeded" },
87 { WSAESTALE, "Stale NFS file handle" },
88 { WSAEREMOTE, "Too many levels of remote in path" },
89 { WSASYSNOTREADY, "Network subsystem is unvailable" },
90 { WSAVERNOTSUPPORTED, "WinSock version is not supported" },
91 { WSANOTINITIALISED, "Successful WSAStartup() not yet performed" },
92 { WSAEDISCON, "Graceful shutdown in progress" },
93 /* Resolver errors */
94 { WSAHOST_NOT_FOUND, "No such host is known" },
95 { WSATRY_AGAIN, "Host not found, or server failed" },
96 { WSANO_RECOVERY, "Unexpected server error encountered" },
97 { WSANO_DATA, "Valid name without requested data" },
98 { WSANO_ADDRESS, "No address, look for MX record" },
99 { 0, NULL }
100 };
101 PyObject *v;
102 const char *msg = "winsock error";
103
104 for (msgp = msgs; msgp->msg; msgp++)
105 {
106 if (errnum == msgp->num)
107 {
108 msg = msgp->msg;
109 break;
110 }
111 }
112
113 v = Py_BuildValue("(is)", errnum, msg);
114 if (v != NULL)
115 {
116 PyErr_SetObject(ssl_SysCallError, v);
117 Py_DECREF(v);
118 }
119 return;
120 }
121#else
122 PyErr_SetFromErrno(ssl_SysCallError);
123#endif
124}
125
126/*
127 * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;)
128 *
129 * Arguments: ssl - The SSL object
130 * err - The return code from SSL_get_error
131 * ret - The return code from the SSL I/O function
132 * Returns: None, the calling function should return NULL
133 */
134static void
135handle_ssl_errors(SSL *ssl, int err, int ret)
136{
137 switch (err)
138 {
139 /*
140 * Strange as it may seem, ZeroReturn is not an error per se. It means
141 * that the SSL Connection has been closed correctly (note, not the
142 * transport layer!), i.e. closure alerts have been exchanged. This is
143 * an exception since
144 * + There's an SSL "error" code for it
145 * + You have to deal with it in any case, close the transport layer
146 * etc
147 */
148 case SSL_ERROR_ZERO_RETURN:
149 PyErr_SetNone(ssl_ZeroReturnError);
150 break;
151
152 /*
153 * The WantXYZ exceptions don't mean that there's an error, just that
154 * nothing could be read/written just now, maybe because the transport
155 * layer would block on the operation, or that there's not enough data
156 * available to fill an entire SSL record.
157 */
158 case SSL_ERROR_WANT_READ:
159 PyErr_SetNone(ssl_WantReadError);
160 break;
161
162 case SSL_ERROR_WANT_WRITE:
163 PyErr_SetNone(ssl_WantWriteError);
164 break;
165
166 case SSL_ERROR_WANT_X509_LOOKUP:
167 PyErr_SetNone(ssl_WantX509LookupError);
168 break;
169
170 case SSL_ERROR_SYSCALL:
171 if (ERR_peek_error() == 0)
172 {
173 if (ret < 0)
174 {
175 syscall_from_errno();
176 }
177 else
178 {
179 PyObject *v;
180
181 v = Py_BuildValue("(is)", -1, "Unexpected EOF");
182 if (v != NULL)
183 {
184 PyErr_SetObject(ssl_SysCallError, v);
185 Py_DECREF(v);
186 }
187 }
188 break;
189 }
190
191 /* NOTE: Fall-through here, we don't want to duplicate code, right? */
192
193 case SSL_ERROR_SSL:
194 ;
195 default:
196 exception_from_error_queue();
197 break;
198 }
199}
200
201/*
202 * Here be member methods of the Connection "class"
203 */
204
205static char ssl_Connection_get_context_doc[] = "\n\
206Get session context\n\
207\n\
208Arguments: self - The Connection object\n\
209 args - The Python argument tuple, should be empty\n\
210Returns: A Context object\n\
211";
212static PyObject *
213ssl_Connection_get_context(ssl_ConnectionObj *self, PyObject *args)
214{
215 if (!PyArg_ParseTuple(args, ":get_context"))
216 return NULL;
217
218 Py_INCREF(self->context);
219 return (PyObject *)self->context;
220}
221
222static char ssl_Connection_pending_doc[] = "\n\
223Get the number of bytes that can be safely read from the connection\n\
224\n\
225Arguments: self - The Connection object\n\
226 args - The Python argument tuple, should be empty\n\
227Returns: \n\
228";
229static PyObject *
230ssl_Connection_pending(ssl_ConnectionObj *self, PyObject *args)
231{
232 int ret;
233
234 if (!PyArg_ParseTuple(args, ":pending"))
235 return NULL;
236
237 ret = SSL_pending(self->ssl);
238 return PyInt_FromLong((long)ret);
239}
240
241static char ssl_Connection_send_doc[] = "\n\
242Send data on the connection. NOTE: If you get one of the WantRead,\n\
243WantWrite or WantX509Lookup exceptions on this, you have to call the\n\
244method again with the SAME buffer.\n\
245\n\
246Arguments: self - The Connection object\n\
247 args - The Python argument tuple, should be:\n\
248 buf - The string to send\n\
249 flags - (optional) Included for compatability with the socket\n\
250 API, the value is ignored\n\
251Returns: The number of bytes written\n\
252";
253static PyObject *
254ssl_Connection_send(ssl_ConnectionObj *self, PyObject *args)
255{
256 char *buf;
257 int len, ret, err, flags;
258
259 if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags))
260 return NULL;
261
262 MY_BEGIN_ALLOW_THREADS(self->tstate)
263 ret = SSL_write(self->ssl, buf, len);
264 MY_END_ALLOW_THREADS(self->tstate)
265
266 if (PyErr_Occurred())
267 {
268 flush_error_queue();
269 return NULL;
270 }
271
272 err = SSL_get_error(self->ssl, ret);
273 if (err == SSL_ERROR_NONE)
274 {
275 return PyInt_FromLong((long)ret);
276 }
277 else
278 {
279 handle_ssl_errors(self->ssl, err, ret);
280 return NULL;
281 }
282}
283
284static char ssl_Connection_sendall_doc[] = "\n\
285Send \"all\" data on the connection. This calls send() repeatedly until\n\
286all data is sent. If an error occurs, it's impossible to tell how much data\n\
287has been sent.\n\
288\n\
289Arguments: self - The Connection object\n\
290 args - The Python argument tuple, should be:\n\
291 buf - The string to send\n\
292 flags - (optional) Included for compatability with the socket\n\
293 API, the value is ignored\n\
294Returns: The number of bytes written\n\
295";
296static PyObject *
297ssl_Connection_sendall(ssl_ConnectionObj *self, PyObject *args)
298{
299 char *buf;
300 int len, ret, err, flags;
301 PyObject *pyret = Py_None;
302
303 if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags))
304 return NULL;
305
306 do {
307 MY_BEGIN_ALLOW_THREADS(self->tstate)
308 ret = SSL_write(self->ssl, buf, len);
309 MY_END_ALLOW_THREADS(self->tstate)
310 if (PyErr_Occurred())
311 {
312 flush_error_queue();
313 pyret = NULL;
314 break;
315 }
316 err = SSL_get_error(self->ssl, ret);
317 if (err == SSL_ERROR_NONE)
318 {
319 buf += ret;
320 len -= ret;
321 }
322 else if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL ||
323 err == SSL_ERROR_ZERO_RETURN)
324 {
325 handle_ssl_errors(self->ssl, err, ret);
326 pyret = NULL;
327 break;
328 }
329 } while (len > 0);
330
331 Py_XINCREF(pyret);
332 return pyret;
333}
334
335static char ssl_Connection_recv_doc[] = "\n\
336Receive data on the connection. NOTE: If you get one of the WantRead,\n\
337WantWrite or WantX509Lookup exceptions on this, you have to call the\n\
338method again with the SAME buffer.\n\
339\n\
340Arguments: self - The Connection object\n\
341 args - The Python argument tuple, should be:\n\
342 bufsiz - The maximum number of bytes to read\n\
343 flags - (optional) Included for compatability with the socket\n\
344 API, the value is ignored\n\
345Returns: The number of bytes read\n\
346";
347static PyObject *
348ssl_Connection_recv(ssl_ConnectionObj *self, PyObject *args)
349{
350 int bufsiz, ret, err, flags;
351 PyObject *buf;
352
353 if (!PyArg_ParseTuple(args, "i|i:recv", &bufsiz, &flags))
354 return NULL;
355
356 buf = PyString_FromStringAndSize(NULL, bufsiz);
357 if (buf == NULL)
358 return NULL;
359
360 MY_BEGIN_ALLOW_THREADS(self->tstate)
361 ret = SSL_read(self->ssl, PyString_AsString(buf), bufsiz);
362 MY_END_ALLOW_THREADS(self->tstate)
363
364 if (PyErr_Occurred())
365 {
366 Py_DECREF(buf);
367 flush_error_queue();
368 return NULL;
369 }
370
371 err = SSL_get_error(self->ssl, ret);
372 if (err == SSL_ERROR_NONE)
373 {
374 if (ret != bufsiz && _PyString_Resize(&buf, ret) < 0)
375 return NULL;
376 return buf;
377 }
378 else
379 {
380 handle_ssl_errors(self->ssl, err, ret);
381 Py_DECREF(buf);
382 return NULL;
383 }
384}
385
386static char ssl_Connection_renegotiate_doc[] = "\n\
387Renegotiate the session\n\
388\n\
389Arguments: self - The Connection object\n\
390 args - The Python argument tuple, should be empty\n\
391Returns: True if the renegotiation can be started, false otherwise\n\
392";
393static PyObject *
394ssl_Connection_renegotiate(ssl_ConnectionObj *self, PyObject *args)
395{
396 int ret;
397
398 if (!PyArg_ParseTuple(args, ":renegotiate"))
399 return NULL;
400
401 MY_BEGIN_ALLOW_THREADS(self->tstate);
402 ret = SSL_renegotiate(self->ssl);
403 MY_END_ALLOW_THREADS(self->tstate);
404
405 if (PyErr_Occurred())
406 {
407 flush_error_queue();
408 return NULL;
409 }
410
411 return PyInt_FromLong((long)ret);
412}
413
414static char ssl_Connection_do_handshake_doc[] = "\n\
415Perform an SSL handshake (usually called after renegotiate() or one of\n\
416set_*_state()). This can raise the same exceptions as send and recv.\n\
417\n\
418Arguments: self - The Connection object\n\
419 args - The Python argument tuple, should be empty\n\
420Returns: None.\n\
421";
422static PyObject *
423ssl_Connection_do_handshake(ssl_ConnectionObj *self, PyObject *args)
424{
425 int ret, err;
426
427 if (!PyArg_ParseTuple(args, ":do_handshake"))
428 return NULL;
429
430 MY_BEGIN_ALLOW_THREADS(self->tstate);
431 ret = SSL_do_handshake(self->ssl);
432 MY_END_ALLOW_THREADS(self->tstate);
433
434 if (PyErr_Occurred())
435 {
436 flush_error_queue();
437 return NULL;
438 }
439
440 err = SSL_get_error(self->ssl, ret);
441 if (err == SSL_ERROR_NONE)
442 {
443 Py_INCREF(Py_None);
444 return Py_None;
445 }
446 else
447 {
448 handle_ssl_errors(self->ssl, err, ret);
449 return NULL;
450 }
451}
452
453#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L
454static char ssl_Connection_renegotiate_pending_doc[] = "\n\
455Check if there's a renegotiation in progress, it will return false once\n\
456a renegotiation is finished.\n\
457\n\
458Arguments: self - The Connection object\n\
459 args - The Python argument tuple, should be empty\n\
460Returns: Whether there's a renegotiation in progress\n\
461";
462static PyObject *
463ssl_Connection_renegotiate_pending(ssl_ConnectionObj *self, PyObject *args)
464{
465 if (!PyArg_ParseTuple(args, ":renegotiate_pending"))
466 return NULL;
467
468 return PyInt_FromLong((long)SSL_renegotiate_pending(self->ssl));
469}
470#endif
471
472static char ssl_Connection_total_renegotiations_doc[] = "\n\
473Find out the total number of renegotiations.\n\
474\n\
475Arguments: self - The Connection object\n\
476 args - The Python argument tuple, should be empty\n\
477Returns: The number of renegotiations.\n\
478";
479static PyObject *
480ssl_Connection_total_renegotiations(ssl_ConnectionObj *self, PyObject *args)
481{
482 if (!PyArg_ParseTuple(args, ":total_renegotiations"))
483 return NULL;
484
485 return PyInt_FromLong(SSL_total_renegotiations(self->ssl));
486}
487
488static char ssl_Connection_set_accept_state_doc[] = "\n\
489Set the connection to work in server mode. The handshake will be handled\n\
490automatically by read/write.\n\
491\n\
492Arguments: self - The Connection object\n\
493 args - The Python argument tuple, should be empty\n\
494Returns: None\n\
495";
496static PyObject *
497ssl_Connection_set_accept_state(ssl_ConnectionObj *self, PyObject *args)
498{
499 if (!PyArg_ParseTuple(args, ":set_accept_state"))
500 return NULL;
501
502 SSL_set_accept_state(self->ssl);
503
504 Py_INCREF(Py_None);
505 return Py_None;
506}
507
508static char ssl_Connection_set_connect_state_doc[] = "\n\
509Set the connection to work in client mode. The handshake will be handled\n\
510automatically by read/write.\n\
511\n\
512Arguments: self - The Connection object\n\
513 args - The Python argument tuple, should be empty\n\
514Returns: None\n\
515";
516static PyObject *
517ssl_Connection_set_connect_state(ssl_ConnectionObj *self, PyObject *args)
518{
519 if (!PyArg_ParseTuple(args, ":set_connect_state"))
520 return NULL;
521
522 SSL_set_connect_state(self->ssl);
523
524 Py_INCREF(Py_None);
525 return Py_None;
526}
527
528static char ssl_Connection_connect_doc[] = "\n\
529Connect to remote host and set up client-side SSL\n\
530\n\
531Arguments: self - The Connection object\n\
532 args - The Python argument tuple, should be:\n\
533 addr - A remote address\n\
534Returns: What the socket's connect method returns\n\
535";
536static PyObject *
537ssl_Connection_connect(ssl_ConnectionObj *self, PyObject *args)
538{
539 PyObject *meth, *ret;
540
541 if ((meth = PyObject_GetAttrString(self->socket, "connect")) == NULL)
542 return NULL;
543
544 SSL_set_connect_state(self->ssl);
545
546 ret = PyEval_CallObject(meth, args);
547 Py_DECREF(meth);
548 if (ret == NULL)
549 return NULL;
550
551 return ret;
552}
553
554static char ssl_Connection_connect_ex_doc[] = "\n\
555Connect to remote host and set up client-side SSL. Note that if the socket's\n\
556connect_ex method doesn't return 0, SSL won't be initialized.\n\
557\n\
558Arguments: self - The Connection object\n\
559 args - The Python argument tuple, should be:\n\
560 addr - A remove address\n\
561Returns: What the socket's connect_ex method returns\n\
562";
563static PyObject *
564ssl_Connection_connect_ex(ssl_ConnectionObj *self, PyObject *args)
565{
566 PyObject *meth, *ret;
567
568 if ((meth = PyObject_GetAttrString(self->socket, "connect_ex")) == NULL)
569 return NULL;
570
571 SSL_set_connect_state(self->ssl);
572
573 ret = PyEval_CallObject(meth, args);
574 Py_DECREF(meth);
575 if (ret == NULL)
576 return NULL;
577 if (PyInt_Check(ret) && PyInt_AsLong(ret) != 0)
578 return ret;
579
580 return ret;
581}
582
583static char ssl_Connection_accept_doc[] = "\n\
584Accept incoming connection and set up SSL on it\n\
585\n\
586Arguments: self - The Connection object\n\
587 args - The Python argument tuple, should be empty\n\
588Returns: A (conn,addr) pair where conn is a Connection and addr is an\n\
589 address\n\
590";
591static PyObject *
592ssl_Connection_accept(ssl_ConnectionObj *self, PyObject *args)
593{
594 PyObject *tuple, *socket, *address, *meth;
595 ssl_ConnectionObj *conn;
596
597 if ((meth = PyObject_GetAttrString(self->socket, "accept")) == NULL)
598 return NULL;
599 tuple = PyEval_CallObject(meth, args);
600 Py_DECREF(meth);
601 if (tuple == NULL)
602 return NULL;
603
604 socket = PyTuple_GetItem(tuple, 0);
605 Py_INCREF(socket);
606 address = PyTuple_GetItem(tuple, 1);
607 Py_INCREF(address);
608 Py_DECREF(tuple);
609
610 conn = ssl_Connection_New(self->context, socket);
611 Py_DECREF(socket);
612 if (conn == NULL)
613 {
614 Py_DECREF(address);
615 return NULL;
616 }
617
618 SSL_set_accept_state(conn->ssl);
619
620 tuple = Py_BuildValue("(OO)", conn, address);
621
622 Py_DECREF(conn);
623 Py_DECREF(address);
624
625 return tuple;
626}
627
628static char ssl_Connection_shutdown_doc[] = "\n\
629Send closure alert\n\
630\n\
631Arguments: self - The Connection object\n\
632 args - The Python argument tuple, should be empty\n\
633Returns: True if the shutdown completed successfully (i.e. both sides\n\
634 have sent closure alerts), false otherwise (i.e. you have to\n\
635 wait for a ZeroReturnError on a recv() method call\n\
636";
637static PyObject *
638ssl_Connection_shutdown(ssl_ConnectionObj *self, PyObject *args)
639{
640 int ret;
641
642 if (!PyArg_ParseTuple(args, ":shutdown"))
643 return NULL;
644
645 MY_BEGIN_ALLOW_THREADS(self->tstate)
646 ret = SSL_shutdown(self->ssl);
647 MY_END_ALLOW_THREADS(self->tstate)
648
649 if (PyErr_Occurred())
650 {
651 flush_error_queue();
652 return NULL;
653 }
654
655 if (ret < 0)
656 {
657 exception_from_error_queue();
658 return NULL;
659 }
660 else if (ret > 0)
661 {
662 Py_INCREF(Py_True);
663 return Py_True;
664 }
665 else
666 {
667 Py_INCREF(Py_False);
668 return Py_False;
669 }
670}
671
672static char ssl_Connection_get_cipher_list_doc[] = "\n\
673Get the session cipher list\n\
674WARNING: API change! This used to take an optional argument, and return a\n\
675string.\n\
676\n\
677Arguments: self - The Connection object\n\
678 args - The Python argument tuple, should be empty\n\
679Returns: A list of cipher strings\n\
680";
681static PyObject *
682ssl_Connection_get_cipher_list(ssl_ConnectionObj *self, PyObject *args)
683{
684 int idx = 0;
685 const char *ret;
686 PyObject *lst, *item;
687
688 if (!PyArg_ParseTuple(args, ":get_cipher_list"))
689 return NULL;
690
691 lst = PyList_New(0);
692 while ((ret = SSL_get_cipher_list(self->ssl, idx)) != NULL)
693 {
694 item = PyString_FromString(ret);
695 PyList_Append(lst, item);
696 Py_DECREF(item);
697 idx++;
698 }
699 return lst;
700}
701
702static char ssl_Connection_makefile_doc[] = "\n\
703The makefile() method is not implemented, since there is no dup semantics\n\
704for SSL connections\n\
705XXX: Return self instead?\n\
706\n\
707Arguments: self - The Connection object\n\
708 args - The Python argument tuple, should be empty\n\
709Returns: NULL\n\
710";
711static PyObject *
712ssl_Connection_makefile(ssl_ConnectionObj *self, PyObject *args)
713{
714 PyErr_SetString(PyExc_NotImplementedError, "Cannot make file object of SSL.Connection");
715 return NULL;
716}
717
718static char ssl_Connection_get_app_data_doc[] = "\n\
719Get application data\n\
720\n\
721Arguments: self - The Connection object\n\
722 args - The Python argument tuple, should be empty\n\
723Returns: The application data\n\
724";
725static PyObject *
726ssl_Connection_get_app_data(ssl_ConnectionObj *self, PyObject *args)
727{
728 if (!PyArg_ParseTuple(args, ":get_app_data"))
729 return NULL;
730
731 Py_INCREF(self->app_data);
732 return self->app_data;
733}
734
735static char ssl_Connection_set_app_data_doc[] = "\n\
736Set application data\n\
737\n\
738Arguments: self - The Connection object\n\
739 args - The Python argument tuple, should be\n\
740 data - The application data\n\
741Returns: None\n\
742";
743static PyObject *
744ssl_Connection_set_app_data(ssl_ConnectionObj *self, PyObject *args)
745{
746 PyObject *data;
747
748 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
749 return NULL;
750
751 Py_DECREF(self->app_data);
752 Py_INCREF(data);
753 self->app_data = data;
754
755 Py_INCREF(Py_None);
756 return Py_None;
757}
758
Jean-Paul Calderone72b8f0f2008-02-21 23:57:40 -0500759static char ssl_Connection_get_shutdown_doc[] = "\n\
760Get shutdown state\n\
761\n\
762Arguments: self - The Connection object\n\
763 args - The Python argument tuple, should be empty\n\
764Returns: The shutdown state, a bitmask of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.\n\
765";
766static PyObject *
767ssl_Connection_get_shutdown(ssl_ConnectionObj *self, PyObject *args)
768{
769 if (!PyArg_ParseTuple(args, ":get_shutdown"))
770 return NULL;
771
772 return PyInt_FromLong((long)SSL_get_shutdown(self->ssl));
773}
774
775static char ssl_Connection_set_shutdown_doc[] = "\n\
776Set shutdown state\n\
777\n\
778Arguments: self - The Connection object\n\
779 args - The Python argument tuple, should be\n\
780 shutdown state - bitmask of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.\n\
781Returns: None\n\
782";
783static PyObject *
784ssl_Connection_set_shutdown(ssl_ConnectionObj *self, PyObject *args)
785{
786 int shutdown;
787
788 if (!PyArg_ParseTuple(args, "i:set_shutdown", &shutdown))
789 return NULL;
790
791 SSL_set_shutdown(self->ssl, shutdown);
792 Py_INCREF(Py_None);
793 return Py_None;
794}
795
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500796static char ssl_Connection_state_string_doc[] = "\n\
797Get a verbose state description\n\
798\n\
799Arguments: self - The Connection object\n\
800 args - The Python argument tuple, should be empty\n\
801Returns: A string representing the state\n\
802";
803static PyObject *
804ssl_Connection_state_string(ssl_ConnectionObj *self, PyObject *args)
805{
806 if (!PyArg_ParseTuple(args, ":state_string"))
807 return NULL;
808
809 return PyString_FromString(SSL_state_string_long(self->ssl));
810}
811
812static char ssl_Connection_sock_shutdown_doc[] = "\n\
813See shutdown(2)\n\
814\n\
815Arguments: self - The Connection object\n\
816 args - The Python argument tuple, should be whatever the\n\
817 socket's shutdown() method expects\n\
818Returns: What the socket's shutdown() method returns\n\
819";
820static PyObject *
821ssl_Connection_sock_shutdown(ssl_ConnectionObj *self, PyObject *args)
822{
823 PyObject *meth, *ret;
824
825 if ((meth = PyObject_GetAttrString(self->socket, "shutdown")) == NULL)
826 return NULL;
827 ret = PyEval_CallObject(meth, args);
828 Py_DECREF(meth);
829 return ret;
830}
831
832static char ssl_Connection_get_peer_certificate_doc[] = "\n\
833Retrieve the other side's certificate (if any)\n\
834\n\
835Arguments: self - The Connection object\n\
836 args - The Python argument tuple, should be empty\n\
837Returns: The peer's certificate\n\
838";
839static PyObject *
840ssl_Connection_get_peer_certificate(ssl_ConnectionObj *self, PyObject *args)
841{
842 X509 *cert;
843
844 if (!PyArg_ParseTuple(args, ":get_peer_certificate"))
845 return NULL;
846
847 cert = SSL_get_peer_certificate(self->ssl);
848 if (cert != NULL)
849 {
850 return (PyObject *)crypto_X509_New(cert, 1);
851 }
852 else
853 {
854 Py_INCREF(Py_None);
855 return Py_None;
856 }
857}
858
859static char ssl_Connection_want_read_doc[] = "\n\
860Checks if more data has to be read from the transport layer to complete an\n\
861operation.\n\
862\n\
863Arguments: self - The Connection object\n\
864 args - The Python argument tuple, should be empty\n\
865Returns: True iff more data has to be read\n\
866";
867static PyObject *
868ssl_Connection_want_read(ssl_ConnectionObj *self, PyObject *args)
869{
870 if (!PyArg_ParseTuple(args, ":want_read"))
871 return NULL;
872
873 return PyInt_FromLong((long)SSL_want_read(self->ssl));
874}
875
876static char ssl_Connection_want_write_doc[] = "\n\
877Checks if there is data to write to the transport layer to complete an\n\
878operation.\n\
879\n\
880Arguments: self - The Connection object\n\
881 args - The Python argument tuple, should be empty\n\
882Returns: True iff there is data to write\n\
883";
884static PyObject *
885ssl_Connection_want_write(ssl_ConnectionObj *self, PyObject *args)
886{
887 if (!PyArg_ParseTuple(args, ":want_write"))
888 return NULL;
889
890 return PyInt_FromLong((long)SSL_want_write(self->ssl));
891}
892
893/*
894 * Member methods in the Connection object
895 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
896 * { 'name', (PyCFunction)ssl_Connection_name, METH_VARARGS }
897 * for convenience
898 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Connection_real
899 * function with the name 'name'
900 */
901#define ADD_METHOD(name) \
902 { #name, (PyCFunction)ssl_Connection_##name, METH_VARARGS, ssl_Connection_##name##_doc }
903#define ADD_ALIAS(name,real) \
904 { #name, (PyCFunction)ssl_Connection_##real, METH_VARARGS, ssl_Connection_##real##_doc }
905static PyMethodDef ssl_Connection_methods[] =
906{
907 ADD_METHOD(get_context),
908 ADD_METHOD(pending),
909 ADD_METHOD(send),
910 ADD_ALIAS (write, send),
911 ADD_METHOD(sendall),
912 ADD_METHOD(recv),
913 ADD_ALIAS (read, recv),
914 ADD_METHOD(renegotiate),
915 ADD_METHOD(do_handshake),
916#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L
917 ADD_METHOD(renegotiate_pending),
918#endif
919 ADD_METHOD(total_renegotiations),
920 ADD_METHOD(connect),
921 ADD_METHOD(connect_ex),
922 ADD_METHOD(accept),
923 ADD_METHOD(shutdown),
924 ADD_METHOD(get_cipher_list),
925 ADD_METHOD(makefile),
926 ADD_METHOD(get_app_data),
927 ADD_METHOD(set_app_data),
Jean-Paul Calderone72b8f0f2008-02-21 23:57:40 -0500928 ADD_METHOD(get_shutdown),
929 ADD_METHOD(set_shutdown),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500930 ADD_METHOD(state_string),
931 ADD_METHOD(sock_shutdown),
932 ADD_METHOD(get_peer_certificate),
933 ADD_METHOD(want_read),
934 ADD_METHOD(want_write),
935 ADD_METHOD(set_accept_state),
936 ADD_METHOD(set_connect_state),
937 { NULL, NULL }
938};
939#undef ADD_ALIAS
940#undef ADD_METHOD
941
942
943/*
944 * Constructor for Connection objects
945 *
946 * Arguments: ctx - An SSL Context to use for this connection
947 * sock - The socket to use for transport layer
948 * Returns: The newly created Connection object
949 */
950ssl_ConnectionObj *
951ssl_Connection_New(ssl_ContextObj *ctx, PyObject *sock)
952{
953 ssl_ConnectionObj *self;
954 int fd;
955
956 self = PyObject_GC_New(ssl_ConnectionObj, &ssl_Connection_Type);
957 if (self == NULL)
958 return NULL;
959
960 Py_INCREF(ctx);
961 self->context = ctx;
962
963 Py_INCREF(sock);
964 self->socket = sock;
965
966 self->ssl = NULL;
967
968 Py_INCREF(Py_None);
969 self->app_data = Py_None;
970
971 self->tstate = NULL;
972
973 fd = PyObject_AsFileDescriptor(self->socket);
974 if (fd < 0)
975 {
976 Py_DECREF(self);
977 return NULL;
978 }
979
980 self->ssl = SSL_new(self->context->ctx);
981 SSL_set_app_data(self->ssl, self);
982 SSL_set_fd(self->ssl, (SOCKET_T)fd);
983
984 PyObject_GC_Track(self);
985
986 return self;
987}
988
989/*
990 * Find attribute
991 *
992 * Arguments: self - The Connection object
993 * name - The attribute name
994 * Returns: A Python object for the attribute, or NULL if something went
995 * wrong
996 */
997static PyObject *
998ssl_Connection_getattr(ssl_ConnectionObj *self, char *name)
999{
1000 PyObject *meth;
1001
1002 meth = Py_FindMethod(ssl_Connection_methods, (PyObject *)self, name);
1003
1004 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError))
1005 {
1006 PyErr_Clear();
1007 /* Try looking it up in the "socket" instead. */
1008 meth = PyObject_GetAttrString(self->socket, name);
1009 }
1010
1011 return meth;
1012}
1013
1014/*
1015 * Call the visitproc on all contained objects.
1016 *
1017 * Arguments: self - The Connection object
1018 * visit - Function to call
1019 * arg - Extra argument to visit
1020 * Returns: 0 if all goes well, otherwise the return code from the first
1021 * call that gave non-zero result.
1022 */
1023static int
1024ssl_Connection_traverse(ssl_ConnectionObj *self, visitproc visit, void *arg)
1025{
1026 int ret = 0;
1027
1028 if (ret == 0 && self->context != NULL)
1029 ret = visit((PyObject *)self->context, arg);
1030 if (ret == 0 && self->socket != NULL)
1031 ret = visit(self->socket, arg);
1032 if (ret == 0 && self->app_data != NULL)
1033 ret = visit(self->app_data, arg);
1034 return ret;
1035}
1036
1037/*
1038 * Decref all contained objects and zero the pointers.
1039 *
1040 * Arguments: self - The Connection object
1041 * Returns: Always 0.
1042 */
1043static int
1044ssl_Connection_clear(ssl_ConnectionObj *self)
1045{
1046 Py_XDECREF(self->context);
1047 self->context = NULL;
1048 Py_XDECREF(self->socket);
1049 self->socket = NULL;
1050 Py_XDECREF(self->app_data);
1051 self->app_data = NULL;
1052 return 0;
1053}
1054
1055/*
1056 * Deallocate the memory used by the Connection object
1057 *
1058 * Arguments: self - The Connection object
1059 * Returns: None
1060 */
1061static void
1062ssl_Connection_dealloc(ssl_ConnectionObj *self)
1063{
1064 PyObject_GC_UnTrack(self);
1065 if (self->ssl != NULL)
1066 SSL_free(self->ssl);
1067 ssl_Connection_clear(self);
1068 PyObject_GC_Del(self);
1069}
1070
1071PyTypeObject ssl_Connection_Type = {
1072 PyObject_HEAD_INIT(NULL)
1073 0,
1074 "Connection",
1075 sizeof(ssl_ConnectionObj),
1076 0,
1077 (destructor)ssl_Connection_dealloc,
1078 NULL, /* print */
1079 (getattrfunc)ssl_Connection_getattr,
1080 NULL, /* setattr */
1081 NULL, /* compare */
1082 NULL, /* repr */
1083 NULL, /* as_number */
1084 NULL, /* as_sequence */
1085 NULL, /* as_mapping */
1086 NULL, /* hash */
1087 NULL, /* call */
1088 NULL, /* str */
1089 NULL, /* getattro */
1090 NULL, /* setattro */
1091 NULL, /* as_buffer */
1092 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1093 NULL, /* doc */
1094 (traverseproc)ssl_Connection_traverse,
1095 (inquiry)ssl_Connection_clear,
1096};
1097
1098
1099/*
1100 * Initiailze the Connection part of the SSL sub module
1101 *
1102 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1103 * Returns: 1 for success, 0 otherwise
1104 */
1105int
1106init_ssl_connection(PyObject *dict)
1107{
1108 ssl_Connection_Type.ob_type = &PyType_Type;
1109 Py_INCREF(&ssl_Connection_Type);
1110 if (PyDict_SetItemString(dict, "ConnectionType", (PyObject *)&ssl_Connection_Type) != 0)
1111 return 0;
1112
1113 return 1;
1114}
1115