blob: 96111aad7a0f7fddd13832f757ffd5d0706cf618 [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
759static char ssl_Connection_state_string_doc[] = "\n\
760Get a verbose state description\n\
761\n\
762Arguments: self - The Connection object\n\
763 args - The Python argument tuple, should be empty\n\
764Returns: A string representing the state\n\
765";
766static PyObject *
767ssl_Connection_state_string(ssl_ConnectionObj *self, PyObject *args)
768{
769 if (!PyArg_ParseTuple(args, ":state_string"))
770 return NULL;
771
772 return PyString_FromString(SSL_state_string_long(self->ssl));
773}
774
775static char ssl_Connection_sock_shutdown_doc[] = "\n\
776See shutdown(2)\n\
777\n\
778Arguments: self - The Connection object\n\
779 args - The Python argument tuple, should be whatever the\n\
780 socket's shutdown() method expects\n\
781Returns: What the socket's shutdown() method returns\n\
782";
783static PyObject *
784ssl_Connection_sock_shutdown(ssl_ConnectionObj *self, PyObject *args)
785{
786 PyObject *meth, *ret;
787
788 if ((meth = PyObject_GetAttrString(self->socket, "shutdown")) == NULL)
789 return NULL;
790 ret = PyEval_CallObject(meth, args);
791 Py_DECREF(meth);
792 return ret;
793}
794
795static char ssl_Connection_get_peer_certificate_doc[] = "\n\
796Retrieve the other side's certificate (if any)\n\
797\n\
798Arguments: self - The Connection object\n\
799 args - The Python argument tuple, should be empty\n\
800Returns: The peer's certificate\n\
801";
802static PyObject *
803ssl_Connection_get_peer_certificate(ssl_ConnectionObj *self, PyObject *args)
804{
805 X509 *cert;
806
807 if (!PyArg_ParseTuple(args, ":get_peer_certificate"))
808 return NULL;
809
810 cert = SSL_get_peer_certificate(self->ssl);
811 if (cert != NULL)
812 {
813 return (PyObject *)crypto_X509_New(cert, 1);
814 }
815 else
816 {
817 Py_INCREF(Py_None);
818 return Py_None;
819 }
820}
821
822static char ssl_Connection_want_read_doc[] = "\n\
823Checks if more data has to be read from the transport layer to complete an\n\
824operation.\n\
825\n\
826Arguments: self - The Connection object\n\
827 args - The Python argument tuple, should be empty\n\
828Returns: True iff more data has to be read\n\
829";
830static PyObject *
831ssl_Connection_want_read(ssl_ConnectionObj *self, PyObject *args)
832{
833 if (!PyArg_ParseTuple(args, ":want_read"))
834 return NULL;
835
836 return PyInt_FromLong((long)SSL_want_read(self->ssl));
837}
838
839static char ssl_Connection_want_write_doc[] = "\n\
840Checks if there is data to write to the transport layer to complete an\n\
841operation.\n\
842\n\
843Arguments: self - The Connection object\n\
844 args - The Python argument tuple, should be empty\n\
845Returns: True iff there is data to write\n\
846";
847static PyObject *
848ssl_Connection_want_write(ssl_ConnectionObj *self, PyObject *args)
849{
850 if (!PyArg_ParseTuple(args, ":want_write"))
851 return NULL;
852
853 return PyInt_FromLong((long)SSL_want_write(self->ssl));
854}
855
856/*
857 * Member methods in the Connection object
858 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
859 * { 'name', (PyCFunction)ssl_Connection_name, METH_VARARGS }
860 * for convenience
861 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Connection_real
862 * function with the name 'name'
863 */
864#define ADD_METHOD(name) \
865 { #name, (PyCFunction)ssl_Connection_##name, METH_VARARGS, ssl_Connection_##name##_doc }
866#define ADD_ALIAS(name,real) \
867 { #name, (PyCFunction)ssl_Connection_##real, METH_VARARGS, ssl_Connection_##real##_doc }
868static PyMethodDef ssl_Connection_methods[] =
869{
870 ADD_METHOD(get_context),
871 ADD_METHOD(pending),
872 ADD_METHOD(send),
873 ADD_ALIAS (write, send),
874 ADD_METHOD(sendall),
875 ADD_METHOD(recv),
876 ADD_ALIAS (read, recv),
877 ADD_METHOD(renegotiate),
878 ADD_METHOD(do_handshake),
879#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L
880 ADD_METHOD(renegotiate_pending),
881#endif
882 ADD_METHOD(total_renegotiations),
883 ADD_METHOD(connect),
884 ADD_METHOD(connect_ex),
885 ADD_METHOD(accept),
886 ADD_METHOD(shutdown),
887 ADD_METHOD(get_cipher_list),
888 ADD_METHOD(makefile),
889 ADD_METHOD(get_app_data),
890 ADD_METHOD(set_app_data),
891 ADD_METHOD(state_string),
892 ADD_METHOD(sock_shutdown),
893 ADD_METHOD(get_peer_certificate),
894 ADD_METHOD(want_read),
895 ADD_METHOD(want_write),
896 ADD_METHOD(set_accept_state),
897 ADD_METHOD(set_connect_state),
898 { NULL, NULL }
899};
900#undef ADD_ALIAS
901#undef ADD_METHOD
902
903
904/*
905 * Constructor for Connection objects
906 *
907 * Arguments: ctx - An SSL Context to use for this connection
908 * sock - The socket to use for transport layer
909 * Returns: The newly created Connection object
910 */
911ssl_ConnectionObj *
912ssl_Connection_New(ssl_ContextObj *ctx, PyObject *sock)
913{
914 ssl_ConnectionObj *self;
915 int fd;
916
917 self = PyObject_GC_New(ssl_ConnectionObj, &ssl_Connection_Type);
918 if (self == NULL)
919 return NULL;
920
921 Py_INCREF(ctx);
922 self->context = ctx;
923
924 Py_INCREF(sock);
925 self->socket = sock;
926
927 self->ssl = NULL;
928
929 Py_INCREF(Py_None);
930 self->app_data = Py_None;
931
932 self->tstate = NULL;
933
934 fd = PyObject_AsFileDescriptor(self->socket);
935 if (fd < 0)
936 {
937 Py_DECREF(self);
938 return NULL;
939 }
940
941 self->ssl = SSL_new(self->context->ctx);
942 SSL_set_app_data(self->ssl, self);
943 SSL_set_fd(self->ssl, (SOCKET_T)fd);
944
945 PyObject_GC_Track(self);
946
947 return self;
948}
949
950/*
951 * Find attribute
952 *
953 * Arguments: self - The Connection object
954 * name - The attribute name
955 * Returns: A Python object for the attribute, or NULL if something went
956 * wrong
957 */
958static PyObject *
959ssl_Connection_getattr(ssl_ConnectionObj *self, char *name)
960{
961 PyObject *meth;
962
963 meth = Py_FindMethod(ssl_Connection_methods, (PyObject *)self, name);
964
965 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError))
966 {
967 PyErr_Clear();
968 /* Try looking it up in the "socket" instead. */
969 meth = PyObject_GetAttrString(self->socket, name);
970 }
971
972 return meth;
973}
974
975/*
976 * Call the visitproc on all contained objects.
977 *
978 * Arguments: self - The Connection object
979 * visit - Function to call
980 * arg - Extra argument to visit
981 * Returns: 0 if all goes well, otherwise the return code from the first
982 * call that gave non-zero result.
983 */
984static int
985ssl_Connection_traverse(ssl_ConnectionObj *self, visitproc visit, void *arg)
986{
987 int ret = 0;
988
989 if (ret == 0 && self->context != NULL)
990 ret = visit((PyObject *)self->context, arg);
991 if (ret == 0 && self->socket != NULL)
992 ret = visit(self->socket, arg);
993 if (ret == 0 && self->app_data != NULL)
994 ret = visit(self->app_data, arg);
995 return ret;
996}
997
998/*
999 * Decref all contained objects and zero the pointers.
1000 *
1001 * Arguments: self - The Connection object
1002 * Returns: Always 0.
1003 */
1004static int
1005ssl_Connection_clear(ssl_ConnectionObj *self)
1006{
1007 Py_XDECREF(self->context);
1008 self->context = NULL;
1009 Py_XDECREF(self->socket);
1010 self->socket = NULL;
1011 Py_XDECREF(self->app_data);
1012 self->app_data = NULL;
1013 return 0;
1014}
1015
1016/*
1017 * Deallocate the memory used by the Connection object
1018 *
1019 * Arguments: self - The Connection object
1020 * Returns: None
1021 */
1022static void
1023ssl_Connection_dealloc(ssl_ConnectionObj *self)
1024{
1025 PyObject_GC_UnTrack(self);
1026 if (self->ssl != NULL)
1027 SSL_free(self->ssl);
1028 ssl_Connection_clear(self);
1029 PyObject_GC_Del(self);
1030}
1031
1032PyTypeObject ssl_Connection_Type = {
1033 PyObject_HEAD_INIT(NULL)
1034 0,
1035 "Connection",
1036 sizeof(ssl_ConnectionObj),
1037 0,
1038 (destructor)ssl_Connection_dealloc,
1039 NULL, /* print */
1040 (getattrfunc)ssl_Connection_getattr,
1041 NULL, /* setattr */
1042 NULL, /* compare */
1043 NULL, /* repr */
1044 NULL, /* as_number */
1045 NULL, /* as_sequence */
1046 NULL, /* as_mapping */
1047 NULL, /* hash */
1048 NULL, /* call */
1049 NULL, /* str */
1050 NULL, /* getattro */
1051 NULL, /* setattro */
1052 NULL, /* as_buffer */
1053 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1054 NULL, /* doc */
1055 (traverseproc)ssl_Connection_traverse,
1056 (inquiry)ssl_Connection_clear,
1057};
1058
1059
1060/*
1061 * Initiailze the Connection part of the SSL sub module
1062 *
1063 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1064 * Returns: 1 for success, 0 otherwise
1065 */
1066int
1067init_ssl_connection(PyObject *dict)
1068{
1069 ssl_Connection_Type.ob_type = &PyType_Type;
1070 Py_INCREF(&ssl_Connection_Type);
1071 if (PyDict_SetItemString(dict, "ConnectionType", (PyObject *)&ssl_Connection_Type) != 0)
1072 return 0;
1073
1074 return 1;
1075}
1076