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