diff options
author | Jean-Paul Calderone <exarkun@twistedmatrix.com> | 2013-12-29 09:46:14 -0500 |
---|---|---|
committer | Jean-Paul Calderone <exarkun@twistedmatrix.com> | 2013-12-29 09:46:14 -0500 |
commit | ba4b6776f584913d1335f004f66ea5efe88e04ba (patch) | |
tree | 84d0dff15fdbfdb882dc8361f26707c052c84933 | |
parent | 3385ed23e32539190cd234aa763cf08880f6a918 (diff) | |
download | pyopenssl-ba4b6776f584913d1335f004f66ea5efe88e04ba.tar.gz |
Superceded
-rwxr-xr-x | OpenSSL/ssl/connection.c | 1725 | ||||
-rw-r--r-- | OpenSSL/ssl/connection.h | 53 | ||||
-rw-r--r-- | OpenSSL/ssl/context.c | 1501 | ||||
-rw-r--r-- | OpenSSL/ssl/context.h | 45 | ||||
-rw-r--r-- | OpenSSL/ssl/session.c | 159 | ||||
-rw-r--r-- | OpenSSL/ssl/session.h | 27 | ||||
-rw-r--r-- | OpenSSL/ssl/ssl.c | 326 | ||||
-rw-r--r-- | OpenSSL/ssl/ssl.h | 77 |
8 files changed, 0 insertions, 3913 deletions
diff --git a/OpenSSL/ssl/connection.c b/OpenSSL/ssl/connection.c deleted file mode 100755 index 9428376..0000000 --- a/OpenSSL/ssl/connection.c +++ /dev/null @@ -1,1725 +0,0 @@ -/* - * connection.c - * - * Copyright (C) AB Strakt - * Copyright (C) Jean-Paul Calderone - * See LICENSE for details. - * - * SSL Connection objects and methods. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - */ -#include <Python.h> - -#ifndef MS_WINDOWS -# include <sys/socket.h> -# include <netinet/in.h> -# if !(defined(__BEOS__) || defined(__CYGWIN__)) -# include <netinet/tcp.h> -# endif -#else -# include <winsock.h> -# include <wincrypt.h> -#endif - -#define SSL_MODULE -#include <openssl/bio.h> -#include <openssl/err.h> -#include "ssl.h" - -/** - * If we are on UNIX, fine, just use PyErr_SetFromErrno. If we are on Windows, - * apply some black winsock voodoo. This is basically just copied from Python's - * socketmodule.c - * - * Arguments: None - * Returns: None - */ -static void -syscall_from_errno(void) -{ -#ifdef MS_WINDOWS - int errnum = WSAGetLastError(); - if (errnum) - { - static struct { int num; const char *msg; } *msgp, msgs[] = { - { WSAEINTR, "Interrupted system call" }, - { WSAEBADF, "Bad file descriptor" }, - { WSAEACCES, "Permission denied" }, - { WSAEFAULT, "Bad address" }, - { WSAEINVAL, "Invalid argument" }, - { WSAEMFILE, "Too many open files" }, - { WSAEWOULDBLOCK, "The socket operation could not complete " - "without blocking" }, - { WSAEINPROGRESS, "Operation now in progress" }, - { WSAEALREADY, "Operation already in progress" }, - { WSAENOTSOCK, "Socket operation on non-socket" }, - { WSAEDESTADDRREQ, "Destination address required" }, - { WSAEMSGSIZE, "Message too long" }, - { WSAEPROTOTYPE, "Protocol wrong type for socket" }, - { WSAENOPROTOOPT, "Protocol not available" }, - { WSAEPROTONOSUPPORT, "Protocol not supported" }, - { WSAESOCKTNOSUPPORT, "Socket type not supported" }, - { WSAEOPNOTSUPP, "Operation not supported" }, - { WSAEPFNOSUPPORT, "Protocol family not supported" }, - { WSAEAFNOSUPPORT, "Address family not supported" }, - { WSAEADDRINUSE, "Address already in use" }, - { WSAEADDRNOTAVAIL, "Can't assign requested address" }, - { WSAENETDOWN, "Network is down" }, - { WSAENETUNREACH, "Network is unreachable" }, - { WSAENETRESET, "Network dropped connection on reset" }, - { WSAECONNABORTED, "Software caused connection abort" }, - { WSAECONNRESET, "Connection reset by peer" }, - { WSAENOBUFS, "No buffer space available" }, - { WSAEISCONN, "Socket is already connected" }, - { WSAENOTCONN, "Socket is not connected" }, - { WSAESHUTDOWN, "Can't send after socket shutdown" }, - { WSAETOOMANYREFS, "Too many references: can't splice" }, - { WSAETIMEDOUT, "Operation timed out" }, - { WSAECONNREFUSED, "Connection refused" }, - { WSAELOOP, "Too many levels of symbolic links" }, - { WSAENAMETOOLONG, "File name too long" }, - { WSAEHOSTDOWN, "Host is down" }, - { WSAEHOSTUNREACH, "No route to host" }, - { WSAENOTEMPTY, "Directory not empty" }, - { WSAEPROCLIM, "Too many processes" }, - { WSAEUSERS, "Too many users" }, - { WSAEDQUOT, "Disc quota exceeded" }, - { WSAESTALE, "Stale NFS file handle" }, - { WSAEREMOTE, "Too many levels of remote in path" }, - { WSASYSNOTREADY, "Network subsystem is unvailable" }, - { WSAVERNOTSUPPORTED, "WinSock version is not supported" }, - { WSANOTINITIALISED, "Successful WSAStartup() not yet performed" }, - { WSAEDISCON, "Graceful shutdown in progress" }, - /* Resolver errors */ - { WSAHOST_NOT_FOUND, "No such host is known" }, - { WSATRY_AGAIN, "Host not found, or server failed" }, - { WSANO_RECOVERY, "Unexpected server error encountered" }, - { WSANO_DATA, "Valid name without requested data" }, - { WSANO_ADDRESS, "No address, look for MX record" }, - { 0, NULL } - }; - PyObject *v; - const char *msg = "winsock error"; - - for (msgp = msgs; msgp->msg; msgp++) - { - if (errnum == msgp->num) - { - msg = msgp->msg; - break; - } - } - - v = Py_BuildValue("(is)", errnum, msg); - if (v != NULL) - { - PyErr_SetObject(ssl_SysCallError, v); - Py_DECREF(v); - } - return; - } -#else - PyErr_SetFromErrno(ssl_SysCallError); -#endif -} - -/* - * Handle errors raised by BIO functions. - * - * Arguments: bio - The BIO object - * ret - The return value of the BIO_ function. - * Returns: None, the calling function should return NULL; - */ -static void -handle_bio_errors(BIO* bio, int ret) -{ - if (BIO_should_retry(bio)) { - if (BIO_should_read(bio)) { - PyErr_SetNone(ssl_WantReadError); - } else if (BIO_should_write(bio)) { - PyErr_SetNone(ssl_WantWriteError); - } else if (BIO_should_io_special(bio)) { - /* - * It's somewhat unclear what this means. From the OpenSSL source, - * it seems like it should not be triggered by the memory BIO, so - * for the time being, this case shouldn't come up. The SSL BIO - * (which I think should be named the socket BIO) may trigger this - * case if its socket is not yet connected or it is busy doing - * something related to x509. - */ - PyErr_SetString(PyExc_ValueError, "BIO_should_io_special"); - } else { - /* - * I hope this is dead code. The BIO documentation suggests that - * one of the above three checks should always be true. - */ - PyErr_SetString(PyExc_ValueError, "unknown bio failure"); - } - } else { - /* - * If we aren't to retry, it's really an error, so fall back to the - * normal error reporting code. However, the BIO interface does not - * specify a uniform error reporting mechanism. We can only hope that - * the code which triggered the error also kindly pushed something onto - * the error stack. - */ - exception_from_error_queue(ssl_Error); - } -} - -/* - * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;) - * - * Arguments: ssl - The SSL object - * err - The return code from SSL_get_error - * ret - The return code from the SSL I/O function - * Returns: None, the calling function should return NULL - */ -static void -handle_ssl_errors(SSL *ssl, int err, int ret) -{ - switch (err) - { - /* - * Strange as it may seem, ZeroReturn is not an error per se. It means - * that the SSL Connection has been closed correctly (note, not the - * transport layer!), i.e. closure alerts have been exchanged. This is - * an exception since - * + There's an SSL "error" code for it - * + You have to deal with it in any case, close the transport layer - * etc - */ - case SSL_ERROR_ZERO_RETURN: - PyErr_SetNone(ssl_ZeroReturnError); - break; - - /* - * The WantXYZ exceptions don't mean that there's an error, just that - * nothing could be read/written just now, maybe because the transport - * layer would block on the operation, or that there's not enough data - * available to fill an entire SSL record. - */ - case SSL_ERROR_WANT_READ: - PyErr_SetNone(ssl_WantReadError); - break; - - case SSL_ERROR_WANT_WRITE: - PyErr_SetNone(ssl_WantWriteError); - break; - - case SSL_ERROR_WANT_X509_LOOKUP: - PyErr_SetNone(ssl_WantX509LookupError); - break; - - case SSL_ERROR_SYSCALL: - if (ERR_peek_error() == 0) - { - if (ret < 0) - { - syscall_from_errno(); - } - else - { - PyObject *v; - - v = Py_BuildValue("(is)", -1, "Unexpected EOF"); - if (v != NULL) - { - PyErr_SetObject(ssl_SysCallError, v); - Py_DECREF(v); - } - } - break; - } - - /* NOTE: Fall-through here, we don't want to duplicate code, right? */ - - case SSL_ERROR_SSL: - ; - default: - exception_from_error_queue(ssl_Error); - break; - } -} - -/* - * Here be member methods of the Connection "class" - */ - -static char ssl_Connection_get_context_doc[] = "\n\ -Get session context\n\ -\n\ -:return: A Context object\n\ -"; -static PyObject * -ssl_Connection_get_context(ssl_ConnectionObj *self, PyObject *args) { - if (!PyArg_ParseTuple(args, ":get_context")) { - return NULL; - } - - Py_INCREF(self->context); - return (PyObject *)self->context; -} - -static char ssl_Connection_set_context_doc[] = "\n\ -Switch this connection to a new session context\n\ -\n\ -:param context: A :py:class:`Context` instance giving the new session context to use.\n\ -\n\ -"; -static PyObject * -ssl_Connection_set_context(ssl_ConnectionObj *self, PyObject *args) { - ssl_ContextObj *ctx; - ssl_ContextObj *old; - - if (!PyArg_ParseTuple(args, "O!:set_context", &ssl_Context_Type, &ctx)) { - return NULL; - } - - /* This Connection will hold on to this context now. Make sure it stays - * alive. - */ - Py_INCREF(ctx); - - /* XXX The unit tests don't actually verify that this call is made. - * They're satisfied if self->context gets updated. - */ - SSL_set_SSL_CTX(self->ssl, ctx->ctx); - - /* Swap the old out and the new in. - */ - old = self->context; - self->context = ctx; - - /* XXX The unit tests don't verify that this reference is dropped. - */ - Py_DECREF(old); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Connection_get_servername_doc[] = "\n\ -Retrieve the servername extension value if provided in the client hello\n\ -message, or None if there wasn't one.\n\ -\n\ -:return: A byte string giving the server name or :py:data:`None`.\n\ -\n\ -"; -static PyObject * -ssl_Connection_get_servername(ssl_ConnectionObj *self, PyObject *args) { - int type = TLSEXT_NAMETYPE_host_name; - const char *name; - - if (!PyArg_ParseTuple(args, ":get_servername")) { - return NULL; - } - - name = SSL_get_servername(self->ssl, type); - - if (name == NULL) { - Py_INCREF(Py_None); - return Py_None; - } else { - return PyBytes_FromString(name); - } -} - - -static char ssl_Connection_set_tlsext_host_name_doc[] = "\n\ -Set the value of the servername extension to send in the client hello.\n\ -\n\ -:param name: A byte string giving the name.\n\ -\n\ -"; -static PyObject * -ssl_Connection_set_tlsext_host_name(ssl_ConnectionObj *self, PyObject *args) { - char *buf; - - if (!PyArg_ParseTuple(args, BYTESTRING_FMT ":set_tlsext_host_name", &buf)) { - return NULL; - } - - /* XXX I guess this can fail sometimes? */ - SSL_set_tlsext_host_name(self->ssl, buf); - - Py_INCREF(Py_None); - return Py_None; -} - - - -static char ssl_Connection_pending_doc[] = "\n\ -Get the number of bytes that can be safely read from the connection\n\ -\n\ -:return: The number of bytes available in the receive buffer.\n\ -"; -static PyObject * -ssl_Connection_pending(ssl_ConnectionObj *self, PyObject *args) { - int ret; - - if (!PyArg_ParseTuple(args, ":pending")) { - return NULL; - } - - ret = SSL_pending(self->ssl); - return PyLong_FromLong((long)ret); -} - -static char ssl_Connection_bio_write_doc[] = "\n\ -When using non-socket connections this function sends\n\ -\"dirty\" data that would have traveled in on the network.\n\ -\n\ -:param buf: The string to put into the memory BIO.\n\ -:return: The number of bytes written\n\ -"; -static PyObject * -ssl_Connection_bio_write(ssl_ConnectionObj *self, PyObject *args) -{ - char *buf; - int len, ret; - - if (self->into_ssl == NULL) - { - PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "s#|i:bio_write", &buf, &len)) - return NULL; - - ret = BIO_write(self->into_ssl, buf, len); - - if (PyErr_Occurred()) - { - flush_error_queue(); - return NULL; - } - - if (ret <= 0) { - /* - * There was a problem with the BIO_write of some sort. - */ - handle_bio_errors(self->into_ssl, ret); - return NULL; - } - - return PyLong_FromLong((long)ret); -} - -static char ssl_Connection_send_doc[] = "\n\ -Send data on the connection. NOTE: If you get one of the WantRead,\n\ -WantWrite or WantX509Lookup exceptions on this, you have to call the\n\ -method again with the SAME buffer.\n\ -\n\ -:param buf: The string to send\n\ -:param flags: (optional) Included for compatibility with the socket\n\ - API, the value is ignored\n\ -:return: The number of bytes written\n\ -"; -static PyObject * -ssl_Connection_send(ssl_ConnectionObj *self, PyObject *args) { - int len, ret, err, flags; - char *buf; - -#if PY_VERSION_HEX >= 0x02060000 - - /* - * Sit back and I'll tell you a story of intrigue and corruption, deceit and - * murder. - * - * A Py_buffer is used to hold any kind of byte-like data - a string, a - * memoryview, a buffer, etc. PyArg_ParseTuple takes whatever kind of - * object was supplied, notices the "s*" format specifier, and tries to copy - * the metadata for that object into the Py_buffer also passed in. - * - * According to the Python documentation: - * - * ... the caller is responsible for calling PyBuffer_Release with the - * structure after it has processed the data. - * - * Correct use of PyBuffer_Release is necessary due to the fact that - * Py_buffer must hold a reference to the original Python object from which - * it was initialized. PyBuffer_Release will decrement the reference count - * of that original object, allowing it to eventually be deallocated - but - * only after the Py_buffer is no longer in use. - * - * To support failures partway through parsing a format string, - * PyArg_ParseTuple maintains an internal PyListObject of PyCObjects it has - * created so far. This allows it to easily clean up these objects when - * parsing fails, before returning an error to the caller (incidentally, it - * also makes sure to clean up the Py_buffer it initialized in this case, by - * calling PyBuffer_Release - which means the caller *must not* use - * PyBuffer_Release when PyArg_ParseTuple fails; not exactly what the - * documentation directs). - * - * The PyCObjects are given destructors which clean up some structure - * PyArg_ParseTuple has created (or initialized) - often another PyObject - * which needs to be decref'd. - * - * When parsing completes, the reference count of the PyListObject is merely - * decremented. The normal Python garbage collection logic (the reference - * counting logic, in this case) takes over and collects both the list and - * all of the objects in it. When each PyCObject in the list is collected, - * it triggers its destructor to clean up the structure it wraps. This all - * happens immediately, before the Py_XDECREF of the PyListObject returns. - * - * The PyListObject is similarly destroyed in the success case, but not - * until each PyCObject it contains has had its destructor set to NULL to - * prevent it from cleaning up its contents. - * - * When PyArg_ParseTuple returns in an error case, therefore, - * PyRelease_Buffer has already been used on the Py_buffer passed to - * PyArg_ParseTuple. - * - * This is fortuitous, as the Py_buffer is typically (always?) allocated on - * the stack of the caller of PyArg_ParseTuple. Once that caller returns, - * that stack memory is no longer valid, and the Py_buffer may no longer be - * used. - * - * On a Python runtime which does not use reference counting, the - * PyListObject may not actually be collected before Py_XDECREF returns. It - * may not even be collected before PyArg_ParseTuple returns. In fact, in - * particularly unfortunate cases, it may even not be collected before the - * caller of PyArg_ParseTuple returns. It may not be called until long, - * long after the stack memory the Py_buffer was allocated on has been - * re-used for some other function call, after the memory holding a pointer - * to the structure that owns the memory the Py_buffer wrapped has been - * overwritten. When PyBuffer_Release is used on the Py_buffer in this - * case, it will try to decrement a random integer - probably part of a - * local variable on some part of the stack. - * - * The PyPy runtime does not use reference counting. - * - * The solution adopted here is to allocate the Py_buffer on the heap, - * instead. As there is no mechanism for learning when the PyCObject used - * by PyArg_ParseTuple to do its internal cleanup has had its way with the - * Py_buffer, the Py_buffer is leaked in the error case, to ensure it is - * still valid whenever PyBuffer_Release is called on it. - * - * Real programs should rarely, if ever, trigger the error case of - * PyArg_ParseTuple, so this is probably okay. Plus, I'm tired of this - * stupid bug. -exarkun - */ - - Py_buffer *pbuf = PyMem_Malloc(sizeof *pbuf); - - if (!PyArg_ParseTuple(args, "s*|i:send", pbuf, &flags)) { - return NULL; - } - - buf = pbuf->buf; - len = pbuf->len; -#else - - if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags)) { - return NULL; - } -#endif - - MY_BEGIN_ALLOW_THREADS(self->tstate) - ret = SSL_write(self->ssl, buf, len); - MY_END_ALLOW_THREADS(self->tstate) - -#if PY_VERSION_HEX >= 0x02060000 - PyBuffer_Release(pbuf); - PyMem_Free(pbuf); -#endif - - if (PyErr_Occurred()) - { - flush_error_queue(); - return NULL; - } - - err = SSL_get_error(self->ssl, ret); - if (err == SSL_ERROR_NONE) - { - return PyLong_FromLong((long)ret); - } - else - { - handle_ssl_errors(self->ssl, err, ret); - return NULL; - } -} - -static char ssl_Connection_sendall_doc[] = "\n\ -Send \"all\" data on the connection. This calls send() repeatedly until\n\ -all data is sent. If an error occurs, it's impossible to tell how much data\n\ -has been sent.\n\ -\n\ -:param buf: The string to send\n\ -:param flags: (optional) Included for compatibility with the socket\n\ - API, the value is ignored\n\ -:return: The number of bytes written\n\ -"; -static PyObject * -ssl_Connection_sendall(ssl_ConnectionObj *self, PyObject *args) -{ - char *buf; - int len, ret, err, flags; - PyObject *pyret = Py_None; - -#if PY_VERSION_HEX >= 0x02060000 - Py_buffer *pbuf = PyMem_Malloc(sizeof *pbuf); - - if (!PyArg_ParseTuple(args, "s*|i:sendall", pbuf, &flags)) { - return NULL; - } - - buf = pbuf->buf; - len = pbuf->len; -#else - if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) { - return NULL; - } -#endif - - do { - MY_BEGIN_ALLOW_THREADS(self->tstate) - ret = SSL_write(self->ssl, buf, len); - MY_END_ALLOW_THREADS(self->tstate) - if (PyErr_Occurred()) - { - flush_error_queue(); - pyret = NULL; - break; - } - err = SSL_get_error(self->ssl, ret); - if (err == SSL_ERROR_NONE) - { - buf += ret; - len -= ret; - } - else if (err == SSL_ERROR_SSL || err == SSL_ERROR_SYSCALL || - err == SSL_ERROR_ZERO_RETURN) - { - handle_ssl_errors(self->ssl, err, ret); - pyret = NULL; - break; - } - } while (len > 0); - -#if PY_VERSION_HEX >= 0x02060000 - PyBuffer_Release(pbuf); - PyMem_Free(pbuf); -#endif - - Py_XINCREF(pyret); - return pyret; -} - -static char ssl_Connection_recv_doc[] = "\n\ -Receive data on the connection. NOTE: If you get one of the WantRead,\n\ -WantWrite or WantX509Lookup exceptions on this, you have to call the\n\ -method again with the SAME buffer.\n\ -\n\ -:param bufsiz: The maximum number of bytes to read\n\ -:param flags: (optional) Included for compatibility with the socket\n\ - API, the value is ignored\n\ -:return: The string read from the Connection\n\ -"; -static PyObject * -ssl_Connection_recv(ssl_ConnectionObj *self, PyObject *args) -{ - int bufsiz, ret, err, flags; - PyObject *buf; - - if (!PyArg_ParseTuple(args, "i|i:recv", &bufsiz, &flags)) - return NULL; - - buf = PyBytes_FromStringAndSize(NULL, bufsiz); - if (buf == NULL) - return NULL; - - MY_BEGIN_ALLOW_THREADS(self->tstate) - ret = SSL_read(self->ssl, PyBytes_AsString(buf), bufsiz); - MY_END_ALLOW_THREADS(self->tstate) - - if (PyErr_Occurred()) - { - Py_DECREF(buf); - flush_error_queue(); - return NULL; - } - - err = SSL_get_error(self->ssl, ret); - if (err == SSL_ERROR_NONE) - { - if (ret != bufsiz && _PyBytes_Resize(&buf, ret) < 0) - return NULL; - return buf; - } - else - { - handle_ssl_errors(self->ssl, err, ret); - Py_DECREF(buf); - return NULL; - } -} - -static char ssl_Connection_bio_read_doc[] = "\n\ -When using non-socket connections this function reads\n\ -the \"dirty\" data that would have traveled away on the network.\n\ -\n\ -:param bufsiz: The maximum number of bytes to read\n\ -:return: The string read.\n\ -"; -static PyObject * -ssl_Connection_bio_read(ssl_ConnectionObj *self, PyObject *args) -{ - int bufsiz, ret; - PyObject *buf; - - if (self->from_ssl == NULL) - { - PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); - return NULL; - } - - if (!PyArg_ParseTuple(args, "i:bio_read", &bufsiz)) - return NULL; - - buf = PyBytes_FromStringAndSize(NULL, bufsiz); - if (buf == NULL) - return NULL; - - ret = BIO_read(self->from_ssl, PyBytes_AsString(buf), bufsiz); - - if (PyErr_Occurred()) - { - Py_DECREF(buf); - flush_error_queue(); - return NULL; - } - - if (ret <= 0) { - /* - * There was a problem with the BIO_read of some sort. - */ - handle_bio_errors(self->from_ssl, ret); - Py_DECREF(buf); - return NULL; - } - - /* - * Shrink the string to match the number of bytes we actually read. - */ - if (ret != bufsiz && _PyBytes_Resize(&buf, ret) < 0) - { - Py_DECREF(buf); - return NULL; - } - return buf; -} - -static char ssl_Connection_renegotiate_doc[] = "\n\ -Renegotiate the session\n\ -\n\ -:return: True if the renegotiation can be started, false otherwise\n\ -"; -static PyObject * -ssl_Connection_renegotiate(ssl_ConnectionObj *self, PyObject *args) { - int ret; - - if (!PyArg_ParseTuple(args, ":renegotiate")) { - return NULL; - } - - MY_BEGIN_ALLOW_THREADS(self->tstate); - ret = SSL_renegotiate(self->ssl); - MY_END_ALLOW_THREADS(self->tstate); - - if (PyErr_Occurred()) { - flush_error_queue(); - return NULL; - } - - return PyLong_FromLong((long)ret); -} - -static char ssl_Connection_do_handshake_doc[] = "\n\ -Perform an SSL handshake (usually called after renegotiate() or one of\n\ -set_*_state()). This can raise the same exceptions as send and recv.\n\ -\n\ -:return: None.\n\ -"; -static PyObject * -ssl_Connection_do_handshake(ssl_ConnectionObj *self, PyObject *args) -{ - int ret, err; - - if (!PyArg_ParseTuple(args, ":do_handshake")) - return NULL; - - MY_BEGIN_ALLOW_THREADS(self->tstate); - ret = SSL_do_handshake(self->ssl); - MY_END_ALLOW_THREADS(self->tstate); - - if (PyErr_Occurred()) - { - flush_error_queue(); - return NULL; - } - - err = SSL_get_error(self->ssl, ret); - if (err == SSL_ERROR_NONE) - { - Py_INCREF(Py_None); - return Py_None; - } - else - { - handle_ssl_errors(self->ssl, err, ret); - return NULL; - } -} - -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L -static char ssl_Connection_renegotiate_pending_doc[] = "\n\ -Check if there's a renegotiation in progress, it will return false once\n\ -a renegotiation is finished.\n\ -\n\ -:return: Whether there's a renegotiation in progress\n\ -"; -static PyObject * -ssl_Connection_renegotiate_pending(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":renegotiate_pending")) - return NULL; - - return PyLong_FromLong((long)SSL_renegotiate_pending(self->ssl)); -} -#endif - -static char ssl_Connection_total_renegotiations_doc[] = "\n\ -Find out the total number of renegotiations.\n\ -\n\ -:return: The number of renegotiations.\n\ -"; -static PyObject * -ssl_Connection_total_renegotiations(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":total_renegotiations")) - return NULL; - - return PyLong_FromLong(SSL_total_renegotiations(self->ssl)); -} - -static char ssl_Connection_set_accept_state_doc[] = "\n\ -Set the connection to work in server mode. The handshake will be handled\n\ -automatically by read/write.\n\ -\n\ -:return: None\n\ -"; -static PyObject * -ssl_Connection_set_accept_state(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":set_accept_state")) - return NULL; - - SSL_set_accept_state(self->ssl); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Connection_set_connect_state_doc[] = "\n\ -Set the connection to work in client mode. The handshake will be handled\n\ -automatically by read/write.\n\ -\n\ -:return: None\n\ -"; -static PyObject * -ssl_Connection_set_connect_state(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":set_connect_state")) - return NULL; - - SSL_set_connect_state(self->ssl); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Connection_connect_doc[] = "\n\ -Connect to remote host and set up client-side SSL\n\ -\n\ -:param addr: A remote address\n\ -:return: What the socket's connect method returns\n\ -"; -static PyObject * -ssl_Connection_connect(ssl_ConnectionObj *self, PyObject *args) -{ - PyObject *meth, *ret; - - if ((meth = PyObject_GetAttrString(self->socket, "connect")) == NULL) - return NULL; - - SSL_set_connect_state(self->ssl); - - ret = PyEval_CallObject(meth, args); - Py_DECREF(meth); - if (ret == NULL) - return NULL; - - return ret; -} - -static char ssl_Connection_connect_ex_doc[] = "\n\ -Connect to remote host and set up client-side SSL. Note that if the socket's\n\ -connect_ex method doesn't return 0, SSL won't be initialized.\n\ -\n\ -:param addr: A remove address\n\ -:return: What the socket's connect_ex method returns\n\ -"; -static PyObject * -ssl_Connection_connect_ex(ssl_ConnectionObj *self, PyObject *args) -{ - PyObject *meth, *ret; - - if ((meth = PyObject_GetAttrString(self->socket, "connect_ex")) == NULL) - return NULL; - - SSL_set_connect_state(self->ssl); - - ret = PyEval_CallObject(meth, args); - Py_DECREF(meth); - return ret; -} - -static char ssl_Connection_accept_doc[] = "\n\ -Accept incoming connection and set up SSL on it\n\ -\n\ -:return: A (conn,addr) pair where conn is a Connection and addr is an\n\ - address\n\ -"; -static PyObject * -ssl_Connection_accept(ssl_ConnectionObj *self, PyObject *args) -{ - PyObject *tuple, *socket, *address, *meth; - ssl_ConnectionObj *conn; - - if ((meth = PyObject_GetAttrString(self->socket, "accept")) == NULL) - return NULL; - tuple = PyEval_CallObject(meth, args); - Py_DECREF(meth); - if (tuple == NULL) - return NULL; - - socket = PyTuple_GetItem(tuple, 0); - Py_INCREF(socket); - address = PyTuple_GetItem(tuple, 1); - Py_INCREF(address); - Py_DECREF(tuple); - - conn = ssl_Connection_New(self->context, socket); - Py_DECREF(socket); - if (conn == NULL) - { - Py_DECREF(address); - return NULL; - } - - SSL_set_accept_state(conn->ssl); - - tuple = Py_BuildValue("(OO)", conn, address); - - Py_DECREF(conn); - Py_DECREF(address); - - return tuple; -} - -static char ssl_Connection_bio_shutdown_doc[] = "\n\ -When using non-socket connections this function signals end of\n\ -data on the input for this connection.\n\ -\n\ -:return: None\n\ -"; - -static PyObject * -ssl_Connection_bio_shutdown(ssl_ConnectionObj *self, PyObject *args) -{ - if (self->from_ssl == NULL) - { - PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); - return NULL; - } - - BIO_set_mem_eof_return(self->into_ssl, 0); - Py_INCREF(Py_None); - return Py_None; -} - - - -static char ssl_Connection_shutdown_doc[] = "\n\ -Send closure alert\n\ -\n\ -:return: True if the shutdown completed successfully (i.e. both sides\n\ - have sent closure alerts), false otherwise (i.e. you have to\n\ - wait for a ZeroReturnError on a recv() method call\n\ -"; -static PyObject * -ssl_Connection_shutdown(ssl_ConnectionObj *self, PyObject *args) -{ - int ret; - - if (!PyArg_ParseTuple(args, ":shutdown")) - return NULL; - - MY_BEGIN_ALLOW_THREADS(self->tstate) - ret = SSL_shutdown(self->ssl); - MY_END_ALLOW_THREADS(self->tstate) - - if (PyErr_Occurred()) - { - flush_error_queue(); - return NULL; - } - - if (ret < 0) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else if (ret > 0) - { - Py_INCREF(Py_True); - return Py_True; - } - else - { - Py_INCREF(Py_False); - return Py_False; - } -} - -static char ssl_Connection_get_cipher_list_doc[] = "\n\ -Get the session cipher list\n\ -\n\ -:return: A list of cipher strings\n\ -"; -static PyObject * -ssl_Connection_get_cipher_list(ssl_ConnectionObj *self, PyObject *args) -{ - int idx = 0; - const char *ret; - PyObject *lst, *item; - - if (!PyArg_ParseTuple(args, ":get_cipher_list")) - return NULL; - - lst = PyList_New(0); - while ((ret = SSL_get_cipher_list(self->ssl, idx)) != NULL) - { - item = PyText_FromString(ret); - PyList_Append(lst, item); - Py_DECREF(item); - idx++; - } - return lst; -} - -static char ssl_Connection_get_client_ca_list_doc[] = "\n\ -Get CAs whose certificates are suggested for client authentication.\n\ -\n\ -:return: If this is a server connection, a list of X509Names representing\n\ - the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or\n\ - :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,\n\ - the list of such X509Names sent by the server, or an empty list if that\n\ - has not yet happened.\n\ -"; - -static PyObject * -ssl_Connection_get_client_ca_list(ssl_ConnectionObj *self, PyObject *args) { - STACK_OF(X509_NAME) *CANames; - PyObject *CAList; - int i, n; - - if (!PyArg_ParseTuple(args, ":get_client_ca_list")) { - return NULL; - } - CANames = SSL_get_client_CA_list(self->ssl); - if (CANames == NULL) { - return PyList_New(0); - } - n = sk_X509_NAME_num(CANames); - CAList = PyList_New(n); - if (CAList == NULL) { - return NULL; - } - for (i = 0; i < n; i++) { - X509_NAME *CAName; - PyObject *CA; - - CAName = X509_NAME_dup(sk_X509_NAME_value(CANames, i)); - if (CAName == NULL) { - Py_DECREF(CAList); - exception_from_error_queue(ssl_Error); - return NULL; - } - CA = (PyObject *)new_x509name(CAName, 1); - if (CA == NULL) { - X509_NAME_free(CAName); - Py_DECREF(CAList); - return NULL; - } - if (PyList_SetItem(CAList, i, CA)) { - Py_DECREF(CA); - Py_DECREF(CAList); - return NULL; - } - } - return CAList; -} - -static char ssl_Connection_makefile_doc[] = "\n\ -The makefile() method is not implemented, since there is no dup semantics\n\ -for SSL connections\n\ -\n\ -:raise NotImplementedError\n\ -"; -static PyObject * -ssl_Connection_makefile(ssl_ConnectionObj *self, PyObject *args) -{ - PyErr_SetString(PyExc_NotImplementedError, "Cannot make file object of SSL.Connection"); - return NULL; -} - -static char ssl_Connection_get_app_data_doc[] = "\n\ -Get application data\n\ -\n\ -:return: The application data\n\ -"; -static PyObject * -ssl_Connection_get_app_data(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":get_app_data")) - return NULL; - - Py_INCREF(self->app_data); - return self->app_data; -} - -static char ssl_Connection_set_app_data_doc[] = "\n\ -Set application data\n\ -\n\ -:param data - The application data\n\ -:return: None\n\ -"; -static PyObject * -ssl_Connection_set_app_data(ssl_ConnectionObj *self, PyObject *args) -{ - PyObject *data; - - if (!PyArg_ParseTuple(args, "O:set_app_data", &data)) - return NULL; - - Py_DECREF(self->app_data); - Py_INCREF(data); - self->app_data = data; - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Connection_get_shutdown_doc[] = "\n\ -Get shutdown state\n\ -\n\ -:return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.\n\ -"; -static PyObject * -ssl_Connection_get_shutdown(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":get_shutdown")) - return NULL; - - return PyLong_FromLong((long)SSL_get_shutdown(self->ssl)); -} - -static char ssl_Connection_set_shutdown_doc[] = "\n\ -Set shutdown state\n\ -\n\ -:param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.\n\ -:return: None\n\ -"; -static PyObject * -ssl_Connection_set_shutdown(ssl_ConnectionObj *self, PyObject *args) -{ - int shutdown; - - if (!PyArg_ParseTuple(args, "i:set_shutdown", &shutdown)) - return NULL; - - SSL_set_shutdown(self->ssl, shutdown); - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Connection_state_string_doc[] = "\n\ -Get a verbose state description\n\ -\n\ -:return: A string representing the state\n\ -"; -static PyObject * -ssl_Connection_state_string(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":state_string")) - return NULL; - - return PyText_FromString(SSL_state_string_long(self->ssl)); -} - -static char ssl_Connection_client_random_doc[] = "\n\ -Get a copy of the client hello nonce.\n\ -\n\ -:return: A string representing the state\n\ -"; -static PyObject * -ssl_Connection_client_random(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":client_random")) - return NULL; - - if (self->ssl->session == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyBytes_FromStringAndSize( (const char *) self->ssl->s3->client_random, SSL3_RANDOM_SIZE); -} - -static char ssl_Connection_server_random_doc[] = "\n\ -Get a copy of the server hello nonce.\n\ -\n\ -:return: A string representing the state\n\ -"; -static PyObject * -ssl_Connection_server_random(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":server_random")) - return NULL; - - if (self->ssl->session == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyBytes_FromStringAndSize( (const char *) self->ssl->s3->server_random, SSL3_RANDOM_SIZE); -} - -static char ssl_Connection_master_key_doc[] = "\n\ -Get a copy of the master key.\n\ -\n\ -:return: A string representing the state\n\ -"; -static PyObject * -ssl_Connection_master_key(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":master_key")) - return NULL; - - if (self->ssl->session == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyBytes_FromStringAndSize( (const char *) self->ssl->session->master_key, self->ssl->session->master_key_length); -} - -static char ssl_Connection_sock_shutdown_doc[] = "\n\ -See shutdown(2)\n\ -\n\ -:return: What the socket's shutdown() method returns\n\ -"; -static PyObject * -ssl_Connection_sock_shutdown(ssl_ConnectionObj *self, PyObject *args) -{ - PyObject *meth, *ret; - - if ((meth = PyObject_GetAttrString(self->socket, "shutdown")) == NULL) - return NULL; - ret = PyEval_CallObject(meth, args); - Py_DECREF(meth); - return ret; -} - -static char ssl_Connection_get_peer_certificate_doc[] = "\n\ -Retrieve the other side's certificate (if any)\n\ -\n\ -:return: The peer's certificate\n\ -"; -static PyObject * -ssl_Connection_get_peer_certificate(ssl_ConnectionObj *self, PyObject *args) -{ - X509 *cert; - - if (!PyArg_ParseTuple(args, ":get_peer_certificate")) - return NULL; - - cert = SSL_get_peer_certificate(self->ssl); - if (cert != NULL) - { - return (PyObject *)new_x509(cert, 1); - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Connection_get_peer_cert_chain_doc[] = "\n\ -Retrieve the other side's certificate (if any)\n\ -\n\ -:return: A list of X509 instances giving the peer's certificate chain,\n\ - or None if it does not have one.\n\ -"; -static PyObject * -ssl_Connection_get_peer_cert_chain(ssl_ConnectionObj *self, PyObject *args) { - STACK_OF(X509) *sk; - PyObject *chain; - crypto_X509Obj *cert; - Py_ssize_t i; - - if (!PyArg_ParseTuple(args, ":get_peer_cert_chain")) { - return NULL; - } - - sk = SSL_get_peer_cert_chain(self->ssl); - if (sk != NULL) { - chain = PyList_New(sk_X509_num(sk)); - for (i = 0; i < sk_X509_num(sk); i++) { - cert = new_x509(sk_X509_value(sk, i), 1); - if (!cert) { - /* XXX Untested */ - Py_DECREF(chain); - return NULL; - } - CRYPTO_add(&cert->x509->references, 1, CRYPTO_LOCK_X509); - PyList_SET_ITEM(chain, i, (PyObject *)cert); - } - return chain; - } else { - Py_INCREF(Py_None); - return Py_None; - } - -} - -static char ssl_Connection_want_read_doc[] = "\n\ -Checks if more data has to be read from the transport layer to complete an\n\ -operation.\n\ -\n\ -:return: True iff more data has to be read\n\ -"; -static PyObject * -ssl_Connection_want_read(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":want_read")) - return NULL; - - return PyLong_FromLong((long)SSL_want_read(self->ssl)); -} - -static char ssl_Connection_want_write_doc[] = "\n\ -Checks if there is data to write to the transport layer to complete an\n\ -operation.\n\ -\n\ -:return: True iff there is data to write\n\ -"; -static PyObject * -ssl_Connection_want_write(ssl_ConnectionObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":want_write")) - return NULL; - - return PyLong_FromLong((long)SSL_want_write(self->ssl)); -} - -static char ssl_Connection_get_session_doc[] = "\n\ -Returns the Session currently used.\n\ -\n\ -@return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if\n\ - no session exists.\n\ -"; -static PyObject * -ssl_Connection_get_session(ssl_ConnectionObj *self, PyObject *args) { - ssl_SessionObj *session; - SSL_SESSION *native_session; - - if (!PyArg_ParseTuple(args, ":get_session")) { - return NULL; - } - - native_session = SSL_get1_session(self->ssl); - - if (native_session == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - - session = ssl_Session_from_SSL_SESSION(native_session); - if (!session) { - Py_INCREF(Py_None); - return Py_None; - } - - return (PyObject*)session; -} - -static char ssl_Connection_set_session_doc[] = "\n\ -Set the session to be used when the TLS/SSL connection is established.\n\ -\n\ -:param session: A Session instance representing the session to use.\n\ -:returns: None\n\ -"; -static PyObject * -ssl_Connection_set_session(ssl_ConnectionObj *self, PyObject *args) { - ssl_SessionObj *session; - - if (!PyArg_ParseTuple(args, "O!:set_session", &ssl_Session_Type, &session)) { - return NULL; - } - - if (SSL_set_session(self->ssl, session->session) == 0) { - /* The only case which leads to this seems to be a mismatch, between - * this connection and the session, of the SSL method. - */ - exception_from_error_queue(ssl_Error); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} - -/* - * Member methods in the Connection object - * ADD_METHOD(name) expands to a correct PyMethodDef declaration - * { 'name', (PyCFunction)ssl_Connection_name, METH_VARARGS } - * for convenience - * ADD_ALIAS(name,real) creates an "alias" of the ssl_Connection_real - * function with the name 'name' - */ -#define ADD_METHOD(name) \ - { #name, (PyCFunction)ssl_Connection_##name, METH_VARARGS, ssl_Connection_##name##_doc } -#define ADD_ALIAS(name,real) \ - { #name, (PyCFunction)ssl_Connection_##real, METH_VARARGS, ssl_Connection_##real##_doc } -static PyMethodDef ssl_Connection_methods[] = -{ - ADD_METHOD(get_context), - ADD_METHOD(set_context), - ADD_METHOD(get_servername), - ADD_METHOD(set_tlsext_host_name), - ADD_METHOD(pending), - ADD_METHOD(send), - ADD_ALIAS (write, send), - ADD_METHOD(sendall), - ADD_METHOD(recv), - ADD_ALIAS (read, recv), - ADD_METHOD(bio_read), - ADD_METHOD(bio_write), - ADD_METHOD(renegotiate), - ADD_METHOD(do_handshake), -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L - ADD_METHOD(renegotiate_pending), -#endif - ADD_METHOD(total_renegotiations), - ADD_METHOD(connect), - ADD_METHOD(connect_ex), - ADD_METHOD(accept), - ADD_METHOD(bio_shutdown), - ADD_METHOD(shutdown), - ADD_METHOD(get_cipher_list), - ADD_METHOD(get_client_ca_list), - ADD_METHOD(makefile), - ADD_METHOD(get_app_data), - ADD_METHOD(set_app_data), - ADD_METHOD(get_shutdown), - ADD_METHOD(set_shutdown), - ADD_METHOD(state_string), - ADD_METHOD(server_random), - ADD_METHOD(client_random), - ADD_METHOD(master_key), - ADD_METHOD(sock_shutdown), - ADD_METHOD(get_peer_certificate), - ADD_METHOD(get_peer_cert_chain), - ADD_METHOD(want_read), - ADD_METHOD(want_write), - ADD_METHOD(set_accept_state), - ADD_METHOD(set_connect_state), - ADD_METHOD(get_session), - ADD_METHOD(set_session), - { NULL, NULL } -}; -#undef ADD_ALIAS -#undef ADD_METHOD - -static char ssl_Connection_doc[] = "\n\ -Connection(context, socket) -> Connection instance\n\ -\n\ -Create a new Connection object, using the given OpenSSL.SSL.Context instance\n\ -and socket.\n\ -\n\ -:param context: An SSL Context to use for this connection\n\ -:param socket: The socket to use for transport layer\n\ -"; - -/* - * Initializer used by ssl_Connection_new and ssl_Connection_New. *Not* - * tp_init. This takes an already allocated ssl_ConnectionObj, a context, and - * a optionally a socket, and glues them all together. - */ -static ssl_ConnectionObj* -ssl_Connection_init(ssl_ConnectionObj *self, ssl_ContextObj *ctx, PyObject *sock) { - int fd; - - Py_INCREF(ctx); - self->context = ctx; - - Py_INCREF(sock); - self->socket = sock; - - self->ssl = NULL; - self->from_ssl = NULL; - self->into_ssl = NULL; - - Py_INCREF(Py_None); - self->app_data = Py_None; - - self->tstate = NULL; - - self->ssl = SSL_new(self->context->ctx); - SSL_set_app_data(self->ssl, self); - - if (self->socket == Py_None) - { - /* If it's not a socket or file, treat it like a memory buffer, - * so crazy people can do things like EAP-TLS. */ - self->into_ssl = BIO_new(BIO_s_mem()); - self->from_ssl = BIO_new(BIO_s_mem()); - if (self->into_ssl == NULL || self->from_ssl == NULL) - goto error; - SSL_set_bio(self->ssl, self->into_ssl, self->from_ssl); - } - else - { - fd = PyObject_AsFileDescriptor(self->socket); - if (fd < 0) - { - Py_DECREF(self); - return NULL; - } - else - { - SSL_set_fd(self->ssl, (SOCKET_T)fd); - } - } - return self; - -error: - BIO_free(self->into_ssl); /* NULL safe */ - BIO_free(self->from_ssl); /* NULL safe */ - Py_DECREF(self); - return NULL; -} - -/* - * Constructor for Connection objects - * - * Arguments: ctx - An SSL Context to use for this connection - * sock - The socket to use for transport layer - * Returns: The newly created Connection object - */ -ssl_ConnectionObj * -ssl_Connection_New(ssl_ContextObj *ctx, PyObject *sock) { - ssl_ConnectionObj *self; - - self = PyObject_GC_New(ssl_ConnectionObj, &ssl_Connection_Type); - if (self == NULL) { - return NULL; - } - self = ssl_Connection_init(self, ctx, sock); - if (self == NULL) { - return NULL; - } - PyObject_GC_Track((PyObject *)self); - return self; -} - -static PyObject* -ssl_Connection_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { - ssl_ConnectionObj *self; - ssl_ContextObj *ctx; - PyObject *sock; - static char *kwlist[] = {"context", "socket", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Connection", kwlist, - &ssl_Context_Type, &ctx, &sock)) { - return NULL; - } - - self = (ssl_ConnectionObj *)subtype->tp_alloc(subtype, 1); - if (self == NULL) { - return NULL; - } - - return (PyObject *)ssl_Connection_init(self, ctx, sock); -} - -/* - * Find attribute - * - * Arguments: self - The Connection object - * name - The attribute name - * Returns: A Python object for the attribute, or NULL if something went - * wrong - */ -static PyObject * -ssl_Connection_getattro(ssl_ConnectionObj *self, PyObject *nameobj) { - PyObject *meth; - - meth = PyObject_GenericGetAttr((PyObject*)self, nameobj); - if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - /* Try looking it up in the "socket" instead. */ - meth = PyObject_GenericGetAttr(self->socket, nameobj); - } - - return meth; -} - -/* - * Call the visitproc on all contained objects. - * - * Arguments: self - The Connection object - * visit - Function to call - * arg - Extra argument to visit - * Returns: 0 if all goes well, otherwise the return code from the first - * call that gave non-zero result. - */ -static int -ssl_Connection_traverse(ssl_ConnectionObj *self, visitproc visit, void *arg) -{ - int ret = 0; - - if (ret == 0 && self->context != NULL) - ret = visit((PyObject *)self->context, arg); - if (ret == 0 && self->socket != NULL) - ret = visit(self->socket, arg); - if (ret == 0 && self->app_data != NULL) - ret = visit(self->app_data, arg); - return ret; -} - -/* - * Decref all contained objects and zero the pointers. - * - * Arguments: self - The Connection object - * Returns: Always 0. - */ -static int -ssl_Connection_clear(ssl_ConnectionObj *self) -{ - Py_XDECREF(self->context); - self->context = NULL; - Py_XDECREF(self->socket); - self->socket = NULL; - Py_XDECREF(self->app_data); - self->app_data = NULL; - self->into_ssl = NULL; /* was cleaned up by SSL_free() */ - self->from_ssl = NULL; /* was cleaned up by SSL_free() */ - return 0; -} - -/* - * Deallocate the memory used by the Connection object - * - * Arguments: self - The Connection object - * Returns: None - */ -static void -ssl_Connection_dealloc(ssl_ConnectionObj *self) -{ - PyObject_GC_UnTrack(self); - if (self->ssl != NULL) - SSL_free(self->ssl); - ssl_Connection_clear(self); - PyObject_GC_Del(self); -} - -PyTypeObject ssl_Connection_Type = { - PyOpenSSL_HEAD_INIT(&PyType_Type, 0) - "OpenSSL.SSL.Connection", - sizeof(ssl_ConnectionObj), - 0, - (destructor)ssl_Connection_dealloc, - NULL, /* print */ - NULL, /* tp_getattr */ - NULL, /* setattr */ - NULL, /* compare */ - NULL, /* repr */ - NULL, /* as_number */ - NULL, /* as_sequence */ - NULL, /* as_mapping */ - NULL, /* hash */ - NULL, /* call */ - NULL, /* str */ - (getattrofunc)ssl_Connection_getattro, /* getattro */ - NULL, /* setattro */ - NULL, /* as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - ssl_Connection_doc, /* doc */ - (traverseproc)ssl_Connection_traverse, - (inquiry)ssl_Connection_clear, - NULL, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - NULL, /* tp_iter */ - NULL, /* tp_iternext */ - ssl_Connection_methods, /* tp_methods */ - NULL, /* tp_members */ - NULL, /* tp_getset */ - NULL, /* tp_base */ - NULL, /* tp_dict */ - NULL, /* tp_descr_get */ - NULL, /* tp_descr_set */ - 0, /* tp_dictoffset */ - NULL, /* tp_init */ - NULL, /* tp_alloc */ - ssl_Connection_new, /* tp_new */ -}; - - -/* - * Initiailze the Connection part of the SSL sub module - * - * Arguments: dict - The OpenSSL.SSL module - * Returns: 1 for success, 0 otherwise - */ -int -init_ssl_connection(PyObject *module) { - - if (PyType_Ready(&ssl_Connection_Type) < 0) { - return 0; - } - - /* PyModule_AddObject steals a reference. - */ - Py_INCREF((PyObject *)&ssl_Connection_Type); - if (PyModule_AddObject(module, "Connection", (PyObject *)&ssl_Connection_Type) != 0) { - return 0; - } - - /* PyModule_AddObject steals a reference. - */ - Py_INCREF((PyObject *)&ssl_Connection_Type); - if (PyModule_AddObject(module, "ConnectionType", (PyObject *)&ssl_Connection_Type) != 0) { - return 0; - } - - return 1; -} - diff --git a/OpenSSL/ssl/connection.h b/OpenSSL/ssl/connection.h deleted file mode 100644 index 59f659b..0000000 --- a/OpenSSL/ssl/connection.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * connection.h - * - * Copyright (C) AB Strakt - * See LICENSE for details. - * - * Export SSL Connection data structures and functions. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - * - */ -#ifndef PyOpenSSL_SSL_CONNECTION_H_ -#define PyOpenSSL_SSL_CONNECTION_H_ - -#include <Python.h> -#include <openssl/ssl.h> - -/* shamelessly stolen from socketmodule.c */ -#ifdef MS_WINDOWS -# include <winsock.h> -typedef SOCKET SOCKET_T; -# ifdef MS_WIN64 -# define SIZEOF_SOCKET_T 8 -# else -# define SIZEOF_SOCKET_T 4 -# endif -#else -typedef int SOCKET_T; -# define SIZEOF_SOCKET_T SIZEOF_INT -#endif - - -extern int init_ssl_connection (PyObject *); - -extern PyTypeObject ssl_Connection_Type; - -#define ssl_Connection_Check(v) ((v)->ob_type == &ssl_Connection_Type) - -typedef struct { - PyObject_HEAD - SSL *ssl; - ssl_ContextObj *context; - PyObject *socket; - PyThreadState *tstate; /* This field is no longer used. */ - PyObject *app_data; - BIO *into_ssl, *from_ssl; /* for connections without file descriptors */ -} ssl_ConnectionObj; - - - -#endif - diff --git a/OpenSSL/ssl/context.c b/OpenSSL/ssl/context.c deleted file mode 100644 index 84180b8..0000000 --- a/OpenSSL/ssl/context.c +++ /dev/null @@ -1,1501 +0,0 @@ -/* - * context.c - * - * Copyright (C) AB Strakt - * Copyright (C) Jean-Paul Calderone - * See LICENSE for details. - * - * SSL Context objects and their methods. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - */ -#include <Python.h> - -#if PY_VERSION_HEX >= 0x02050000 -# define PYARG_PARSETUPLE_FORMAT const char -# define PYOBJECT_GETATTRSTRING_TYPE const char* -#else -# define PYARG_PARSETUPLE_FORMAT char -# define PYOBJECT_GETATTRSTRING_TYPE char* -#endif - -#ifndef MS_WINDOWS -# include <sys/socket.h> -# include <netinet/in.h> -# if !(defined(__BEOS__) || defined(__CYGWIN__)) -# include <netinet/tcp.h> -# endif -#else -# include <winsock.h> -# include <wincrypt.h> -#endif - -#define SSL_MODULE -#include "ssl.h" - -/* - * CALLBACKS - * - * Callbacks work like this: We provide a "global" callback in C which - * transforms the arguments into a Python argument tuple and calls the - * corresponding Python callback, and then parsing the return value back into - * things the C function can return. - * - * Three caveats: - * + How do we find the Context object where the Python callbacks are stored? - * + What about multithreading and execution frames? - * + What about Python callbacks that raise exceptions? - * - * The solution to the first issue is trivial if the callback provides - * "userdata" functionality. Since the only callbacks that don't provide - * userdata do provide a pointer to an SSL structure, we can associate an SSL - * object and a Connection one-to-one via the SSL_set/get_app_data() - * functions. - * - * The solution to the other issue is to rewrite the Py_BEGIN_ALLOW_THREADS - * macro allowing it (or rather a new macro) to specify where to save the - * thread state (in our case, as a member of the Connection/Context object) so - * we can retrieve it again before calling the Python callback. - */ - -/* - * Globally defined passphrase callback. This is called from OpenSSL - * internally. The GIL will not be held when this function is invoked. It - * must not be held when the function returns. - * - * Arguments: buf - Buffer to store the returned passphrase in - * maxlen - Maximum length of the passphrase - * verify - If true, the passphrase callback should ask for a - * password twice and verify they're equal. If false, only - * ask once. - * arg - User data, always a Context object - * Returns: The length of the password if successful, 0 otherwise - */ -static int -global_passphrase_callback(char *buf, int maxlen, int verify, void *arg) -{ - /* - * Initialize len here because we're always going to return it, and we - * might jump to the return before it gets initialized in any other way. - */ - int len = 0; - char *str; - PyObject *argv, *ret = NULL; - ssl_ContextObj *ctx = (ssl_ContextObj *)arg; - - /* - * GIL isn't held yet. First things first - acquire it, or any Python API - * we invoke might segfault or blow up the sun. The reverse will be done - * before returning. - */ - MY_END_ALLOW_THREADS(ctx->tstate); - - /* The Python callback is called with a (maxlen,verify,userdata) tuple */ - argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata); - - /* - * XXX Didn't check argv to see if it was NULL. -exarkun - */ - ret = PyEval_CallObject(ctx->passphrase_callback, argv); - Py_DECREF(argv); - - if (ret == NULL) { - /* - * The callback raised an exception. It will be raised by whatever - * Python API triggered this callback. - */ - goto out; - } - - if (!PyObject_IsTrue(ret)) { - /* - * Returned "", or None, or something. Treat it as no passphrase. - */ - Py_DECREF(ret); - goto out; - } - - if (!PyBytes_Check(ret)) { - /* - * XXX Returned something that wasn't a string. This is bogus. We'll - * return 0 and OpenSSL will treat it as an error, resulting in an - * exception from whatever Python API triggered this callback. - */ - Py_DECREF(ret); - goto out; - } - - len = PyBytes_Size(ret); - if (len > maxlen) { - /* - * Returned more than we said they were allowed to return. Just - * truncate it. Might be better to raise an exception, - * instead. -exarkun - */ - len = maxlen; - } - - str = PyBytes_AsString(ret); - strncpy(buf, str, len); - Py_XDECREF(ret); - - out: - /* - * This function is returning into OpenSSL. Release the GIL again. - */ - MY_BEGIN_ALLOW_THREADS(ctx->tstate); - return len; -} - -/* - * Globally defined verify callback - * - * Arguments: ok - True everything is OK "so far", false otherwise - * x509_ctx - Contains the certificate being checked, the current - * error number and depth, and the Connection we're - * dealing with - * Returns: True if everything is okay, false otherwise - */ -static int -global_verify_callback(int ok, X509_STORE_CTX *x509_ctx) -{ - PyObject *argv, *ret; - SSL *ssl; - ssl_ConnectionObj *conn; - crypto_X509Obj *cert; - int errnum, errdepth, c_ret; - - // Get Connection object to check thread state - ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx); - conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl); - - MY_END_ALLOW_THREADS(conn->tstate); - - cert = new_x509(X509_STORE_CTX_get_current_cert(x509_ctx), 0); - errnum = X509_STORE_CTX_get_error(x509_ctx); - errdepth = X509_STORE_CTX_get_error_depth(x509_ctx); - - argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert, - errnum, errdepth, ok); - Py_DECREF(cert); - ret = PyEval_CallObject(conn->context->verify_callback, argv); - Py_DECREF(argv); - - if (ret != NULL && PyObject_IsTrue(ret)) { - X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); - Py_DECREF(ret); - c_ret = 1; - } else { - c_ret = 0; - } - - MY_BEGIN_ALLOW_THREADS(conn->tstate); - return c_ret; -} - -/* - * Globally defined info callback. This is called from OpenSSL internally. - * The GIL will not be held when this function is invoked. It must not be held - * when the function returns. - * - * Arguments: ssl - The Connection - * where - The part of the SSL code that called us - * _ret - The return code of the SSL function that called us - * Returns: None - */ -static void -global_info_callback(const SSL *ssl, int where, int _ret) -{ - ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl); - PyObject *argv, *ret; - - /* - * GIL isn't held yet. First things first - acquire it, or any Python API - * we invoke might segfault or blow up the sun. The reverse will be done - * before returning. - */ - MY_END_ALLOW_THREADS(conn->tstate); - - argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret); - ret = PyEval_CallObject(conn->context->info_callback, argv); - Py_DECREF(argv); - - if (ret == NULL) { - /* - * XXX - This should be reported somehow. -exarkun - */ - PyErr_Clear(); - } else { - Py_DECREF(ret); - } - - /* - * This function is returning into OpenSSL. Release the GIL again. - */ - MY_BEGIN_ALLOW_THREADS(conn->tstate); - return; -} - -/* - * Globally defined TLS extension server name callback. This is called from - * OpenSSL internally. The GIL will not be held when this function is invoked. - * It must not be held when the function returns. - * - * ssl represents the connection this callback is for - * - * alert is a pointer to the alert value which maybe will be emitted to the - * client if there is an error handling the client hello (which contains the - * server name). This is an out parameter, maybe. - * - * arg is an arbitrary pointer specified by SSL_CTX_set_tlsext_servername_arg. - * It will be NULL for all pyOpenSSL uses. - */ -static int -global_tlsext_servername_callback(const SSL *ssl, int *alert, void *arg) { - int result = 0; - PyObject *argv, *ret; - ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl); - - /* - * GIL isn't held yet. First things first - acquire it, or any Python API - * we invoke might segfault or blow up the sun. The reverse will be done - * before returning. - */ - MY_END_ALLOW_THREADS(conn->tstate); - - argv = Py_BuildValue("(O)", (PyObject *)conn); - ret = PyEval_CallObject(conn->context->tlsext_servername_callback, argv); - Py_DECREF(argv); - Py_DECREF(ret); - - /* - * This function is returning into OpenSSL. Release the GIL again. - */ - MY_BEGIN_ALLOW_THREADS(conn->tstate); - return result; -} - -/* - * More recent builds of OpenSSL may have SSLv2 completely disabled. - */ -#ifdef OPENSSL_NO_SSL2 -#define SSLv2_METHOD_TEXT "" -#else -#define SSLv2_METHOD_TEXT " SSLv2_METHOD" -#endif - -#ifdef SSL_OP_NO_TLSv1_1 -#define TLSv1_1_METHOD_TEXT " TLSv1_1_METHOD" -#endif - -#ifdef SSL_OP_NO_TLSv1_2 -#define TLSv1_2_METHOD_TEXT " TLSv1_2_METHOD" -#endif - -static char ssl_Context_doc[] = "\n\ -Context(method) -> Context instance\n\ -\n\ -OpenSSL.SSL.Context instances define the parameters for setting up new SSL\n\ -connections.\n\ -\n\ -:param method: One of:" SSLv2_METHOD_TEXT " SSLv3_METHOD SSLv23_METHOD TLSv1_METHOD" TLSv1_1_METHOD_TEXT TLSv1_2_METHOD_TEXT "\n\ -"; - -#undef SSLv2_METHOD_TEXT -#undef TLSv1_1_METHOD_TEXT -#undef TLSv1_2_METHOD_TEXT - -static char ssl_Context_load_verify_locations_doc[] = "\n\ -Let SSL know where we can find trusted certificates for the certificate\n\ -chain\n\ -\n\ -:param cafile: In which file we can find the certificates\n\ -:param capath: In which directory we can find the certificates\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_load_verify_locations(ssl_ContextObj *self, PyObject *args) { - char *cafile = NULL; - char *capath = NULL; - - if (!PyArg_ParseTuple(args, "z|z:load_verify_locations", &cafile, &capath)) { - return NULL; - } - - if (!SSL_CTX_load_verify_locations(self->ctx, cafile, capath)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_set_default_verify_paths_doc[] = "\n\ -Use the platform-specific CA certificate locations\n\ -\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_default_verify_paths(ssl_ContextObj *self, PyObject *args) { - if (!PyArg_ParseTuple(args, ":set_default_verify_paths")) { - return NULL; - } - - /* - * XXX Error handling for SSL_CTX_set_default_verify_paths is untested. - * -exarkun - */ - if (!SSL_CTX_set_default_verify_paths(self->ctx)) { - exception_from_error_queue(ssl_Error); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -}; - - -static char ssl_Context_set_passwd_cb_doc[] = "\n\ -Set the passphrase callback\n\ -\n\ -:param callback: The Python callback to use\n\ -:param userdata: (optional) A Python object which will be given as\n\ - argument to the callback\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_passwd_cb(ssl_ContextObj *self, PyObject *args) -{ - PyObject *callback = NULL, *userdata = Py_None; - - if (!PyArg_ParseTuple(args, "O|O:set_passwd_cb", &callback, &userdata)) - return NULL; - - if (!PyCallable_Check(callback)) - { - PyErr_SetString(PyExc_TypeError, "expected PyCallable"); - return NULL; - } - - Py_DECREF(self->passphrase_callback); - Py_INCREF(callback); - self->passphrase_callback = callback; - SSL_CTX_set_default_passwd_cb(self->ctx, global_passphrase_callback); - - Py_DECREF(self->passphrase_userdata); - Py_INCREF(userdata); - self->passphrase_userdata = userdata; - SSL_CTX_set_default_passwd_cb_userdata(self->ctx, (void *)self); - - Py_INCREF(Py_None); - return Py_None; -} - -static PyTypeObject * -type_modified_error(const char *name) { - PyErr_Format(PyExc_RuntimeError, - "OpenSSL.crypto's '%s' attribute has been modified", - name); - return NULL; -} - -static PyTypeObject * -import_crypto_type(const char *name, size_t objsize) { - PyObject *module, *type, *name_attr; - PyTypeObject *res; - int right_name; - - module = PyImport_ImportModule("OpenSSL.crypto"); - if (module == NULL) { - return NULL; - } - type = PyObject_GetAttrString(module, (PYOBJECT_GETATTRSTRING_TYPE)name); - Py_DECREF(module); - if (type == NULL) { - return NULL; - } - if (!(PyType_Check(type))) { - Py_DECREF(type); - return type_modified_error(name); - } - name_attr = PyObject_GetAttrString(type, "__name__"); - if (name_attr == NULL) { - Py_DECREF(type); - return NULL; - } - -#ifdef PY3 - { - PyObject* asciiname = PyUnicode_AsASCIIString(name_attr); - Py_DECREF(name_attr); - name_attr = asciiname; - } -#endif - right_name = (PyBytes_CheckExact(name_attr) && - strcmp(name, PyBytes_AsString(name_attr)) == 0); - Py_DECREF(name_attr); - res = (PyTypeObject *)type; - if (!right_name || res->tp_basicsize != objsize) { - Py_DECREF(type); - return type_modified_error(name); - } - return res; -} - -static crypto_X509Obj * -parse_certificate_argument(const char* format, PyObject* args) { - static PyTypeObject *crypto_X509_type = NULL; - crypto_X509Obj *cert; - - if (!crypto_X509_type) { - crypto_X509_type = import_crypto_type("X509", sizeof(crypto_X509Obj)); - if (!crypto_X509_type) { - return NULL; - } - } - if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format, - crypto_X509_type, &cert)) { - return NULL; - } - return cert; -} - -static char ssl_Context_add_extra_chain_cert_doc[] = "\n\ -Add certificate to chain\n\ -\n\ -:param certobj: The X509 certificate object to add to the chain\n\ -:return: None\n\ -"; - -static PyObject * -ssl_Context_add_extra_chain_cert(ssl_ContextObj *self, PyObject *args) -{ - X509* cert_original; - crypto_X509Obj *cert = parse_certificate_argument( - "O!:add_extra_chain_cert", args); - if (cert == NULL) - { - return NULL; - } - if (!(cert_original = X509_dup(cert->x509))) - { - /* exception_from_error_queue(ssl_Error); */ - PyErr_SetString(PyExc_RuntimeError, "X509_dup failed"); - return NULL; - } - if (!SSL_CTX_add_extra_chain_cert(self->ctx, cert_original)) - { - X509_free(cert_original); - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - - -static char ssl_Context_use_certificate_chain_file_doc[] = "\n\ -Load a certificate chain from a file\n\ -\n\ -:param certfile: The name of the certificate chain file\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args) -{ - char *certfile; - - if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile)) - return NULL; - - if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - - -static char ssl_Context_use_certificate_file_doc[] = "\n\ -Load a certificate from a file\n\ -\n\ -:param certfile: The name of the certificate file\n\ -:param filetype: (optional) The encoding of the file, default is PEM\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args) -{ - char *certfile; - int filetype = SSL_FILETYPE_PEM; - - if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype)) - return NULL; - - if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_use_certificate_doc[] = "\n\ -Load a certificate from a X509 object\n\ -\n\ -:param cert: The X509 object\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args) -{ - crypto_X509Obj *cert = parse_certificate_argument( - "O!:use_certificate", args); - if (cert == NULL) { - return NULL; - } - - if (!SSL_CTX_use_certificate(self->ctx, cert->x509)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_use_privatekey_file_doc[] = "\n\ -Load a private key from a file\n\ -\n\ -:param keyfile: The name of the key file\n\ -:param filetype: (optional) The encoding of the file, default is PEM\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args) -{ - char *keyfile; - int filetype = SSL_FILETYPE_PEM, ret; - - if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype)) - return NULL; - - MY_BEGIN_ALLOW_THREADS(self->tstate); - ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype); - MY_END_ALLOW_THREADS(self->tstate); - - if (PyErr_Occurred()) - { - flush_error_queue(); - return NULL; - } - - if (!ret) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_use_privatekey_doc[] = "\n\ -Load a private key from a PKey object\n\ -\n\ -:param pkey: The PKey object\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args) { - static PyTypeObject *crypto_PKey_type = NULL; - crypto_PKeyObj *pkey; - - if (!crypto_PKey_type) { - crypto_PKey_type = import_crypto_type("PKey", sizeof(crypto_PKeyObj)); - if (!crypto_PKey_type) { - return NULL; - } - } - if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey)) { - return NULL; - } - - if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey)) { - exception_from_error_queue(ssl_Error); - return NULL; - } else { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_check_privatekey_doc[] = "\n\ -Check that the private key and certificate match up\n\ -\n\ -:return: None (raises an exception if something's wrong)\n\ -"; -static PyObject * -ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":check_privatekey")) - return NULL; - - if (!SSL_CTX_check_private_key(self->ctx)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_load_client_ca_doc[] = "\n\ -Load the trusted certificates that will be sent to the client (basically\n\ -telling the client \"These are the guys I trust\"). Does not actually\n\ -imply any of the certificates are trusted; that must be configured\n\ -separately.\n\ -\n\ -:param cafile: The name of the certificates file\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args) -{ - char *cafile; - - if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile)) - return NULL; - - SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile)); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_set_session_id_doc[] = "\n\ -Set the session identifier. This is needed if you want to do session\n\ -resumption.\n\ -\n\ -:param buf: A Python object that can be safely converted to a string\n\ -:returns: None\n\ -"; -static PyObject * -ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args) -{ - unsigned char *buf; - unsigned int len; - - if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len)) - return NULL; - - if (!SSL_CTX_set_session_id_context(self->ctx, buf, len)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_set_session_cache_mode_doc[] = "\n\ -Enable/disable session caching and specify the mode used.\n\ -\n\ -:param mode: One or more of the SESS_CACHE_* flags (combine using bitwise or)\n\ -:returns: The previously set caching mode.\n\ -"; -static PyObject * -ssl_Context_set_session_cache_mode(ssl_ContextObj *self, PyObject *args) { - long mode, result; - - if (!PyArg_ParseTuple(args, "l:set_session_cache_mode", &mode)) { - return NULL; - } - - result = SSL_CTX_set_session_cache_mode(self->ctx, mode); - return PyLong_FromLong(result); - -} - -static char ssl_Context_get_session_cache_mode_doc[] = "\n\ -:returns: The currently used cache mode.\n\ -"; -static PyObject * -ssl_Context_get_session_cache_mode(ssl_ContextObj *self, PyObject *args) { - long result; - - if (!PyArg_ParseTuple(args, ":get_session_cache_mode")) { - return NULL; - } - result = SSL_CTX_get_session_cache_mode(self->ctx); - return PyLong_FromLong(result); -} - -static char ssl_Context_set_verify_doc[] = "\n\ -Set the verify mode and verify callback\n\ -\n\ -:param mode: The verify mode, this is either VERIFY_NONE or\n\ - VERIFY_PEER combined with possible other flags\n\ -:param callback: The Python callback to use\n\ -:return: None\n\ -\n\ -See SSL_CTX_set_verify(3SSL) for further details.\n\ -"; -static PyObject * -ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args) -{ - int mode; - PyObject *callback = NULL; - - if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback)) - return NULL; - - if (!PyCallable_Check(callback)) - { - PyErr_SetString(PyExc_TypeError, "expected PyCallable"); - return NULL; - } - - Py_DECREF(self->verify_callback); - Py_INCREF(callback); - self->verify_callback = callback; - SSL_CTX_set_verify(self->ctx, mode, global_verify_callback); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_set_verify_depth_doc[] = "\n\ -Set the verify depth\n\ -\n\ -:param depth: An integer specifying the verify depth\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args) -{ - int depth; - - if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth)) - return NULL; - - SSL_CTX_set_verify_depth(self->ctx, depth); - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_get_verify_mode_doc[] = "\n\ -Get the verify mode\n\ -\n\ -:return: The verify mode\n\ -"; -static PyObject * -ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args) -{ - int mode; - - if (!PyArg_ParseTuple(args, ":get_verify_mode")) - return NULL; - - mode = SSL_CTX_get_verify_mode(self->ctx); - return PyLong_FromLong((long)mode); -} - -static char ssl_Context_get_verify_depth_doc[] = "\n\ -Get the verify depth\n\ -\n\ -:return: The verify depth\n\ -"; -static PyObject * -ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args) -{ - int depth; - - if (!PyArg_ParseTuple(args, ":get_verify_depth")) - return NULL; - - depth = SSL_CTX_get_verify_depth(self->ctx); - return PyLong_FromLong((long)depth); -} - -static char ssl_Context_load_tmp_dh_doc[] = "\n\ -Load parameters for Ephemeral Diffie-Hellman\n\ -\n\ -:param dhfile: The file to load EDH parameters from\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args) -{ - char *dhfile; - BIO *bio; - DH *dh; - - if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile)) - return NULL; - - bio = BIO_new_file(dhfile, "r"); - if (bio == NULL) { - exception_from_error_queue(ssl_Error); - return NULL; - } - - dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); - SSL_CTX_set_tmp_dh(self->ctx, dh); - DH_free(dh); - BIO_free(bio); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_set_cipher_list_doc[] = "\n\ -Change the cipher list\n\ -\n\ -:param cipher_list: A cipher list, see ciphers(1)\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args) -{ - char *cipher_list; - - if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list)) - return NULL; - - if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list)) - { - exception_from_error_queue(ssl_Error); - return NULL; - } - else - { - Py_INCREF(Py_None); - return Py_None; - } -} - -static char ssl_Context_set_client_ca_list_doc[] = "\n\ -Set the list of preferred client certificate signers for this server context.\n\ -\n\ -This list of certificate authorities will be sent to the client when the\n\ -server requests a client certificate.\n\ -\n\ -:param certificate_authorities: a sequence of X509Names.\n\ -:return: None\n\ -"; - -static PyObject * -ssl_Context_set_client_ca_list(ssl_ContextObj *self, PyObject *args) -{ - static PyTypeObject *X509NameType; - PyObject *sequence, *tuple, *item; - crypto_X509NameObj *name; - X509_NAME *sslname; - STACK_OF(X509_NAME) *CANames; - Py_ssize_t length; - int i; - - if (X509NameType == NULL) { - X509NameType = import_crypto_type("X509Name", sizeof(crypto_X509NameObj)); - if (X509NameType == NULL) { - return NULL; - } - } - if (!PyArg_ParseTuple(args, "O:set_client_ca_list", &sequence)) { - return NULL; - } - tuple = PySequence_Tuple(sequence); - if (tuple == NULL) { - return NULL; - } - length = PyTuple_Size(tuple); - if (length >= INT_MAX) { - PyErr_SetString(PyExc_ValueError, "client CA list is too long"); - Py_DECREF(tuple); - return NULL; - } - CANames = sk_X509_NAME_new_null(); - if (CANames == NULL) { - Py_DECREF(tuple); - exception_from_error_queue(ssl_Error); - return NULL; - } - for (i = 0; i < length; i++) { - item = PyTuple_GetItem(tuple, i); - if (item->ob_type != X509NameType) { - PyErr_Format(PyExc_TypeError, - "client CAs must be X509Name objects, not %s objects", - item->ob_type->tp_name); - sk_X509_NAME_free(CANames); - Py_DECREF(tuple); - return NULL; - } - name = (crypto_X509NameObj *)item; - sslname = X509_NAME_dup(name->x509_name); - if (sslname == NULL) { - sk_X509_NAME_free(CANames); - Py_DECREF(tuple); - exception_from_error_queue(ssl_Error); - return NULL; - } - if (!sk_X509_NAME_push(CANames, sslname)) { - X509_NAME_free(sslname); - sk_X509_NAME_free(CANames); - Py_DECREF(tuple); - exception_from_error_queue(ssl_Error); - return NULL; - } - } - Py_DECREF(tuple); - SSL_CTX_set_client_CA_list(self->ctx, CANames); - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_add_client_ca_doc[] = "\n\ -Add the CA certificate to the list of preferred signers for this context.\n\ -\n\ -The list of certificate authorities will be sent to the client when the\n\ -server requests a client certificate.\n\ -\n\ -:param certificate_authority: certificate authority's X509 certificate.\n\ -:return: None\n\ -"; - -static PyObject * -ssl_Context_add_client_ca(ssl_ContextObj *self, PyObject *args) -{ - crypto_X509Obj *cert; - - cert = parse_certificate_argument("O!:add_client_ca", args); - if (cert == NULL) { - return NULL; - } - if (!SSL_CTX_add_client_CA(self->ctx, cert->x509)) { - exception_from_error_queue(ssl_Error); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_set_timeout_doc[] = "\n\ -Set session timeout\n\ -\n\ -:param timeout: The timeout in seconds\n\ -:return: The previous session timeout\n\ -"; -static PyObject * -ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args) -{ - long t, ret; - - if (!PyArg_ParseTuple(args, "l:set_timeout", &t)) - return NULL; - - ret = SSL_CTX_set_timeout(self->ctx, t); - return PyLong_FromLong(ret); -} - -static char ssl_Context_get_timeout_doc[] = "\n\ -Get the session timeout\n\ -\n\ -:return: The session timeout\n\ -"; -static PyObject * -ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args) -{ - long ret; - - if (!PyArg_ParseTuple(args, ":get_timeout")) - return NULL; - - ret = SSL_CTX_get_timeout(self->ctx); - return PyLong_FromLong(ret); -} - -static char ssl_Context_set_info_callback_doc[] = "\n\ -Set the info callback\n\ -\n\ -:param callback: The Python callback to use\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args) -{ - PyObject *callback; - - if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback)) - return NULL; - - if (!PyCallable_Check(callback)) - { - PyErr_SetString(PyExc_TypeError, "expected PyCallable"); - return NULL; - } - - Py_DECREF(self->info_callback); - Py_INCREF(callback); - self->info_callback = callback; - SSL_CTX_set_info_callback(self->ctx, global_info_callback); - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_get_app_data_doc[] = "\n\ -Get the application data (supplied via set_app_data())\n\ -\n\ -:return: The application data\n\ -"; -static PyObject * -ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":get_app_data")) - return NULL; - - Py_INCREF(self->app_data); - return self->app_data; -} - -static char ssl_Context_set_app_data_doc[] = "\n\ -Set the application data (will be returned from get_app_data())\n\ -\n\ -:param data: Any Python object\n\ -:return: None\n\ -"; -static PyObject * -ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args) -{ - PyObject *data; - - if (!PyArg_ParseTuple(args, "O:set_app_data", &data)) - return NULL; - - Py_DECREF(self->app_data); - Py_INCREF(data); - self->app_data = data; - - Py_INCREF(Py_None); - return Py_None; -} - -static char ssl_Context_get_cert_store_doc[] = "\n\ -Get the certificate store for the context\n\ -\n\ -:return: A X509Store object\n\ -"; -static PyObject * -ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args) -{ - X509_STORE *store; - - if (!PyArg_ParseTuple(args, ":get_cert_store")) - return NULL; - - if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL) - { - Py_INCREF(Py_None); - return Py_None; - } - else - { - return (PyObject *)new_x509store(store, 0); - } -} - -static char ssl_Context_set_options_doc[] = "\n\ -Add options. Options set before are not cleared!\n\ -\n\ -:param options: The options to add.\n\ -:return: The new option bitmask.\n\ -"; -static PyObject * -ssl_Context_set_options(ssl_ContextObj *self, PyObject *args) -{ - long options; - - if (!PyArg_ParseTuple(args, "l:set_options", &options)) - return NULL; - - return PyLong_FromLong(SSL_CTX_set_options(self->ctx, options)); -} - -static char ssl_Context_set_mode_doc[] = "\n\ -Add modes via bitmask. Modes set before are not cleared!\n\ -\n\ -:param mode: The mode to add.\n\ -:return: The new mode bitmask.\n\ -"; -static PyObject * -ssl_Context_set_mode(ssl_ContextObj *self, PyObject *args) { - long mode; - - if (!PyArg_ParseTuple(args, "l:set_mode", &mode)) { - return NULL; - } - - return PyLong_FromLong(SSL_CTX_set_mode(self->ctx, mode)); -} - -static char ssl_Context_set_tlsext_servername_callback_doc[] = "\n\ -Specify a callback function to be called when clients specify a server name.\n\ -\n\ -:param callback: The callback function. It will be invoked with one\n\ - argument, the Connection instance.\n\ -\n\ -"; -static PyObject * -ssl_Context_set_tlsext_servername_callback(ssl_ContextObj *self, PyObject *args) { - PyObject *callback; - PyObject *old; - - if (!PyArg_ParseTuple(args, "O:set_tlsext_servername_callback", &callback)) { - return NULL; - } - - Py_INCREF(callback); - old = self->tlsext_servername_callback; - self->tlsext_servername_callback = callback; - Py_DECREF(old); - - SSL_CTX_set_tlsext_servername_callback(self->ctx, global_tlsext_servername_callback); - SSL_CTX_set_tlsext_servername_arg(self->ctx, NULL); - - Py_INCREF(Py_None); - return Py_None; -} - - -/* - * Member methods in the Context object - * ADD_METHOD(name) expands to a correct PyMethodDef declaration - * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS } - * for convenience - * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real - * function with the name 'name' - */ -#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc } -static PyMethodDef ssl_Context_methods[] = { - ADD_METHOD(load_verify_locations), - ADD_METHOD(set_passwd_cb), - ADD_METHOD(set_default_verify_paths), - ADD_METHOD(use_certificate_chain_file), - ADD_METHOD(use_certificate_file), - ADD_METHOD(use_certificate), - ADD_METHOD(add_extra_chain_cert), - ADD_METHOD(use_privatekey_file), - ADD_METHOD(use_privatekey), - ADD_METHOD(check_privatekey), - ADD_METHOD(load_client_ca), - ADD_METHOD(set_session_id), - ADD_METHOD(set_session_cache_mode), - ADD_METHOD(get_session_cache_mode), - ADD_METHOD(set_verify), - ADD_METHOD(set_verify_depth), - ADD_METHOD(get_verify_mode), - ADD_METHOD(get_verify_depth), - ADD_METHOD(load_tmp_dh), - ADD_METHOD(set_cipher_list), - ADD_METHOD(set_client_ca_list), - ADD_METHOD(add_client_ca), - ADD_METHOD(set_timeout), - ADD_METHOD(get_timeout), - ADD_METHOD(set_info_callback), - ADD_METHOD(get_app_data), - ADD_METHOD(set_app_data), - ADD_METHOD(get_cert_store), - ADD_METHOD(set_options), - ADD_METHOD(set_mode), - ADD_METHOD(set_tlsext_servername_callback), - { NULL, NULL } -}; -#undef ADD_METHOD - -/* - * Despite the name which might suggest otherwise, this is not the tp_init for - * the Context type. It's just the common initialization code shared by the - * two _{Nn}ew functions below. - */ -static ssl_ContextObj* -ssl_Context_init(ssl_ContextObj *self, int i_method) { -#if (OPENSSL_VERSION_NUMBER >> 28) == 0x01 - const -#endif - SSL_METHOD *method; - - switch (i_method) { - case ssl_SSLv2_METHOD: -#ifdef OPENSSL_NO_SSL2 - PyErr_SetString(PyExc_ValueError, "SSLv2_METHOD not supported by this version of OpenSSL"); - return NULL; -#else - method = SSLv2_method(); -#endif - break; - case ssl_SSLv23_METHOD: - method = SSLv23_method(); - break; - case ssl_SSLv3_METHOD: - method = SSLv3_method(); - break; - case ssl_TLSv1_METHOD: - method = TLSv1_method(); - break; - case ssl_TLSv1_1_METHOD: -#ifdef SSL_OP_NO_TLSv1_1 - method = TLSv1_1_method(); -#else - PyErr_SetString(PyExc_ValueError, "TLSv1_1_method not supported by this version of OpenSSL"); - return NULL; -#endif - break; - case ssl_TLSv1_2_METHOD: -#ifdef SSL_OP_NO_TLSv1_2 - method = TLSv1_2_method(); -#else - PyErr_SetString(PyExc_ValueError, "TLSv1_2_method not supported by this version of OpenSSL"); - return NULL; -#endif - break; - default: - PyErr_SetString(PyExc_ValueError, "No such protocol"); - return NULL; - } - - self->ctx = SSL_CTX_new(method); - if (self->ctx == NULL) { - exception_from_error_queue(ssl_Error); - return NULL; - } - - Py_INCREF(Py_None); - self->passphrase_callback = Py_None; - Py_INCREF(Py_None); - self->verify_callback = Py_None; - Py_INCREF(Py_None); - self->info_callback = Py_None; - - Py_INCREF(Py_None); - self->tlsext_servername_callback = Py_None; - - Py_INCREF(Py_None); - self->passphrase_userdata = Py_None; - - Py_INCREF(Py_None); - self->app_data = Py_None; - - /* Some initialization that's required to operate smoothly in Python */ - SSL_CTX_set_app_data(self->ctx, self); - SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | - SSL_MODE_AUTO_RETRY); - - self->tstate = NULL; - - return self; -} - -/* - * This one is exposed in the CObject API. I want to deprecate it. - */ -ssl_ContextObj* -ssl_Context_New(int i_method) { - ssl_ContextObj *self; - - self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type); - if (self == NULL) { - return (ssl_ContextObj *)PyErr_NoMemory(); - } - self = ssl_Context_init(self, i_method); - PyObject_GC_Track((PyObject *)self); - return self; -} - - -/* - * This one is the tp_new of the Context type. It's great. - */ -static PyObject* -ssl_Context_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { - int i_method; - ssl_ContextObj *self; - static char *kwlist[] = {"method", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:Context", kwlist, &i_method)) { - return NULL; - } - - self = (ssl_ContextObj *)subtype->tp_alloc(subtype, 1); - if (self == NULL) { - return NULL; - } - - return (PyObject *)ssl_Context_init(self, i_method); -} - -/* - * Call the visitproc on all contained objects. - * - * Arguments: self - The Context object - * visit - Function to call - * arg - Extra argument to visit - * Returns: 0 if all goes well, otherwise the return code from the first - * call that gave non-zero result. - */ -static int -ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg) -{ - int ret = 0; - - if (ret == 0 && self->passphrase_callback != NULL) - ret = visit((PyObject *)self->passphrase_callback, arg); - if (ret == 0 && self->passphrase_userdata != NULL) - ret = visit((PyObject *)self->passphrase_userdata, arg); - if (ret == 0 && self->verify_callback != NULL) - ret = visit((PyObject *)self->verify_callback, arg); - if (ret == 0 && self->info_callback != NULL) - ret = visit((PyObject *)self->info_callback, arg); - if (ret == 0 && self->app_data != NULL) - ret = visit(self->app_data, arg); - return ret; -} - -/* - * Decref all contained objects and zero the pointers. - * - * Arguments: self - The Context object - * Returns: Always 0. - */ -static int -ssl_Context_clear(ssl_ContextObj *self) -{ - Py_XDECREF(self->passphrase_callback); - self->passphrase_callback = NULL; - Py_XDECREF(self->passphrase_userdata); - self->passphrase_userdata = NULL; - Py_XDECREF(self->verify_callback); - self->verify_callback = NULL; - Py_XDECREF(self->info_callback); - self->info_callback = NULL; - Py_XDECREF(self->app_data); - self->app_data = NULL; - return 0; -} - -/* - * Deallocate the memory used by the Context object - * - * Arguments: self - The Context object - * Returns: None - */ -static void -ssl_Context_dealloc(ssl_ContextObj *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - SSL_CTX_free(self->ctx); - ssl_Context_clear(self); - PyObject_GC_Del(self); -} - - -PyTypeObject ssl_Context_Type = { - PyOpenSSL_HEAD_INIT(&PyType_Type, 0) - "OpenSSL.SSL.Context", - sizeof(ssl_ContextObj), - 0, - (destructor)ssl_Context_dealloc, /* tp_dealloc */ - NULL, /* print */ - NULL, /* tp_getattr */ - NULL, /* setattr */ - NULL, /* compare */ - NULL, /* repr */ - NULL, /* as_number */ - NULL, /* as_sequence */ - NULL, /* as_mapping */ - NULL, /* hash */ - NULL, /* call */ - NULL, /* str */ - NULL, /* getattro */ - NULL, /* setattro */ - NULL, /* as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - ssl_Context_doc, /* tp_doc */ - (traverseproc)ssl_Context_traverse, /* tp_traverse */ - (inquiry)ssl_Context_clear, /* tp_clear */ - NULL, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - NULL, /* tp_iter */ - NULL, /* tp_iternext */ - ssl_Context_methods, /* tp_methods */ - NULL, /* tp_members */ - NULL, /* tp_getset */ - NULL, /* tp_base */ - NULL, /* tp_dict */ - NULL, /* tp_descr_get */ - NULL, /* tp_descr_set */ - 0, /* tp_dictoffset */ - NULL, /* tp_init */ - NULL, /* tp_alloc */ - ssl_Context_new, /* tp_new */ -}; - - -/* - * Initialize the Context part of the SSL sub module - * - * Arguments: dict - The OpenSSL.SSL module - * Returns: 1 for success, 0 otherwise - */ -int -init_ssl_context(PyObject *module) { - - if (PyType_Ready(&ssl_Context_Type) < 0) { - return 0; - } - - /* PyModule_AddObject steals a reference. - */ - Py_INCREF((PyObject *)&ssl_Context_Type); - if (PyModule_AddObject(module, "Context", (PyObject *)&ssl_Context_Type) < 0) { - return 0; - } - - /* PyModule_AddObject steals a reference. - */ - Py_INCREF((PyObject *)&ssl_Context_Type); - if (PyModule_AddObject(module, "ContextType", (PyObject *)&ssl_Context_Type) < 0) { - return 0; - } - - return 1; -} - diff --git a/OpenSSL/ssl/context.h b/OpenSSL/ssl/context.h deleted file mode 100644 index 989d8f1..0000000 --- a/OpenSSL/ssl/context.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * context.h - * - * Copyright (C) AB Strakt - * See LICENSE for details. - * - * Export SSL Context object data structures and functions. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - * - */ -#ifndef PyOpenSSL_SSL_CONTEXT_H_ -#define PyOpenSSL_SSL_CONTEXT_H_ - -#include <Python.h> -#include <openssl/ssl.h> - -extern int init_ssl_context (PyObject *); - -extern PyTypeObject ssl_Context_Type; - -#define ssl_Context_Check(v) ((v)->ob_type == &ssl_Context_Type) - -typedef struct { - PyObject_HEAD - SSL_CTX *ctx; - PyObject *passphrase_callback, - *passphrase_userdata, - *verify_callback, - *info_callback, - *tlsext_servername_callback, - *app_data; - PyThreadState *tstate; -} ssl_ContextObj; - -#define ssl_SSLv2_METHOD (1) -#define ssl_SSLv3_METHOD (2) -#define ssl_SSLv23_METHOD (3) -#define ssl_TLSv1_METHOD (4) -#define ssl_TLSv1_1_METHOD (5) -#define ssl_TLSv1_2_METHOD (6) - - -#endif diff --git a/OpenSSL/ssl/session.c b/OpenSSL/ssl/session.c deleted file mode 100644 index f9932a4..0000000 --- a/OpenSSL/ssl/session.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * session.c - * - * Copyright (C) Jean-Paul Calderone - * Copyright (C) Alejandro Alvarez Ayllon - * See LICENSE for details. - * - * SSL Session object data structures and functions. - * - */ -#include <Python.h> -#define SSL_MODULE -#include "ssl.h" - -static char ssl_Session_doc[] = "\n\ -Session() -> Session instance\n\ -\n\ -"; - -/* - * Initialize an already-constructed Session instance with an OpenSSL session - * structure (or NULL). A reference to the OpenSSL session structure is stolen. - */ -static ssl_SessionObj* -ssl_Session_init(ssl_SessionObj *self, SSL_SESSION *native_session) { - self->session = native_session; - return self; -} - -/* - * Create a Session object - */ -static PyObject* -ssl_Session_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { - ssl_SessionObj *self; - - if (!PyArg_ParseTuple(args, ":Session")) { - return NULL; - } - - self = PyObject_New(ssl_SessionObj, &ssl_Session_Type); - if (self == NULL) { - return NULL; - } - - return (PyObject *)ssl_Session_init(self, NULL); -} - -/* - * Create a Session object from an existing SSL_SESSION*. A reference to the - * SSL_SESSION* is stolen. - */ -ssl_SessionObj* -ssl_Session_from_SSL_SESSION(SSL_SESSION *native_session) { - ssl_SessionObj *self; - - self = PyObject_New(ssl_SessionObj, &ssl_Session_Type); - if (self == NULL) { - return NULL; - } - - return ssl_Session_init(self, native_session); -} - -/* - * Discard the reference to the OpenSSL session structure, if there is one, so - * that it can be freed if it is no longer in use. Also release the memory for - * the Python object. - */ -static void -ssl_Session_dealloc(ssl_SessionObj *self) { - if (self->session != NULL) { - SSL_SESSION_free(self->session); - self->session = NULL; - } - Py_TYPE(self)->tp_free((PyObject*)self); -} - -/* - * Member methods in the Session object - * ADD_METHOD(name) expands to a correct PyMethodDef declaration - * { 'name', (PyCFunction)ssl_Session_name, METH_VARARGS } - * for convenience - * ADD_ALIAS(name,real) creates an "alias" of the ssl_Session_real - * function with the name 'name' - */ -#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Session_##name, METH_VARARGS, ssl_Session_##name##_doc } -static PyMethodDef ssl_Session_methods[] = { - { NULL, NULL } -}; -#undef ADD_METHOD - -/* - * The Python Session type definition. - */ -PyTypeObject ssl_Session_Type = { - PyOpenSSL_HEAD_INIT(&PyType_Type, 0) - "OpenSSL.SSL.Session", - sizeof(ssl_SessionObj), - 0, - (destructor)ssl_Session_dealloc, /* tp_dealloc */ - NULL, /* print */ - NULL, /* tp_getattr */ - NULL, /* setattr */ - NULL, /* compare */ - NULL, /* repr */ - NULL, /* as_number */ - NULL, /* as_sequence */ - NULL, /* as_mapping */ - NULL, /* hash */ - NULL, /* call */ - NULL, /* str */ - NULL, /* getattro */ - NULL, /* setattro */ - NULL, /* as_buffer */ - Py_TPFLAGS_DEFAULT, // Py_TPFLAGS_HAVE_GC, /* tp_flags */ - ssl_Session_doc, /* tp_doc */ - NULL, // (traverseproc)ssl_Session_traverse, /* tp_traverse */ - NULL, // (inquiry)ssl_Session_clear, /* tp_clear */ - NULL, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - NULL, /* tp_iter */ - NULL, /* tp_iternext */ - ssl_Session_methods, /* tp_methods */ - NULL, /* tp_members */ - NULL, /* tp_getset */ - NULL, /* tp_base */ - NULL, /* tp_dict */ - NULL, /* tp_descr_get */ - NULL, /* tp_descr_set */ - 0, /* tp_dictoffset */ - NULL, /* tp_init */ - NULL, /* tp_alloc */ - ssl_Session_new, /* tp_new */ -}; - -/* - * Initialize the Session part of the SSL sub module - * - * Arguments: dict - The OpenSSL.SSL module - * Returns: 1 for success, 0 otherwise - */ -int -init_ssl_session(PyObject *module) { - - if (PyType_Ready(&ssl_Session_Type) < 0) { - return 0; - } - - /* PyModule_AddObject steals a reference. - */ - Py_INCREF((PyObject *)&ssl_Session_Type); - if (PyModule_AddObject(module, "Session", (PyObject *)&ssl_Session_Type) < 0) { - return 0; - } - - return 1; -} - diff --git a/OpenSSL/ssl/session.h b/OpenSSL/ssl/session.h deleted file mode 100644 index 4e8de11..0000000 --- a/OpenSSL/ssl/session.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * session.h - * Copyright (C) Jean-Paul Calderone - * See LICENSE for details. - * - * Defined here is the Python type which represents an SSL session by wrapping - * an OpenSSL SSL_SESSION*. - * - */ - -#ifndef PyOpenSSL_SSL_SESSION_H_ -#define PyOpenSSL_SSL_SESSION_H_ - -#include <Python.h> -#include <openssl/ssl.h> - -typedef struct { - PyObject_HEAD - SSL_SESSION *session; -} ssl_SessionObj; - -extern PyTypeObject ssl_Session_Type; - -extern int init_ssl_session(PyObject *); -extern ssl_SessionObj *ssl_Session_from_SSL_SESSION(SSL_SESSION *native_session); - -#endif diff --git a/OpenSSL/ssl/ssl.c b/OpenSSL/ssl/ssl.c deleted file mode 100644 index 0087cbb..0000000 --- a/OpenSSL/ssl/ssl.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * ssl.c - * - * Copyright (C) AB Strakt - * Copyright (C) Jean-Paul Calderone - * See LICENSE for details. - * - * Main file of the SSL sub module. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - */ -#include <Python.h> - -#ifndef MS_WINDOWS -# include <sys/socket.h> -# include <netinet/in.h> -# if !(defined(__BEOS__) || defined(__CYGWIN__)) -# include <netinet/tcp.h> -# endif -#else -# include <winsock.h> -# include <wincrypt.h> -#endif - -#define SSL_MODULE -#include "ssl.h" - -static char ssl_doc[] = "\n\ -Main file of the SSL sub module.\n\ -See the file RATIONALE for a short explanation of why this module was written.\n\ -"; - -crypto_X509Obj* (*new_x509)(X509*, int); -crypto_X509NameObj* (*new_x509name)(X509_NAME*, int); -crypto_X509StoreObj* (*new_x509store)(X509_STORE*, int); - - -#ifndef PY3 -void **crypto_API; -#endif - -int _pyOpenSSL_tstate_key; - -/* Exceptions defined by the SSL submodule */ -PyObject *ssl_Error, /* Base class */ - *ssl_ZeroReturnError, /* Used with SSL_get_error */ - *ssl_WantReadError, /* ... */ - *ssl_WantWriteError, /* ... */ - *ssl_WantX509LookupError, /* ... */ - *ssl_SysCallError; /* Uses (errno,errstr) */ - -static char ssl_SSLeay_version_doc[] = "\n\ -Return a string describing the version of OpenSSL in use.\n\ -\n\ -:param type: One of the SSLEAY_ constants defined in this module.\n\ -"; - -static PyObject * -ssl_SSLeay_version(PyObject *spam, PyObject *args) { - int t; - const char *version; - - if (!PyArg_ParseTuple(args, "i:SSLeay_version", &t)) { - return NULL; - } - - version = SSLeay_version(t); - return PyBytes_FromStringAndSize(version, strlen(version)); -} - - - -/* Methods in the OpenSSL.SSL module */ -static PyMethodDef ssl_methods[] = { - { "SSLeay_version", ssl_SSLeay_version, METH_VARARGS, ssl_SSLeay_version_doc }, - { NULL, NULL } -}; - -#ifdef PY3 -static struct PyModuleDef sslmodule = { - PyModuleDef_HEAD_INIT, - "xSSL", - ssl_doc, - -1, - ssl_methods -}; -#endif - -/* - * Initialize SSL sub module - * - * Arguments: None - * Returns: None - */ -PyOpenSSL_MODINIT(xSSL) { - PyObject *module; -#ifndef PY3 - static void *ssl_API[ssl_API_pointers]; - PyObject *ssl_api_object; - - import_crypto(); - - new_x509 = crypto_X509_New; - new_x509name = crypto_X509Name_New; - new_x509store = crypto_X509Store_New; -#else -# ifdef _WIN32 - HMODULE crypto = GetModuleHandle("crypto.pyd"); - if (crypto == NULL) { - PyErr_SetString(PyExc_RuntimeError, "Unable to get crypto module"); - PyOpenSSL_MODRETURN(NULL); - } - - new_x509 = (crypto_X509Obj* (*)(X509*, int))GetProcAddress(crypto, "crypto_X509_New"); - new_x509name = (crypto_X509NameObj* (*)(X509_NAME*, int))GetProcAddress(crypto, "crypto_X509Name_New"); - new_x509store = (crypto_X509StoreObj* (*)(X509_STORE*, int))GetProcAddress(crypto, "crypto_X509Store_New"); -# else - new_x509 = crypto_X509_New; - new_x509name = crypto_X509Name_New; - new_x509store = crypto_X509Store_New; -# endif -#endif - - SSL_library_init(); - ERR_load_SSL_strings(); - -#ifdef PY3 - module = PyModule_Create(&sslmodule); -#else - module = Py_InitModule3("xSSL", ssl_methods, ssl_doc); -#endif - if (module == NULL) { - PyOpenSSL_MODRETURN(NULL); - } - -#ifndef PY3 - /* Initialize the C API pointer array */ - ssl_API[ssl_Context_New_NUM] = (void *)ssl_Context_New; - ssl_API[ssl_Connection_New_NUM] = (void *)ssl_Connection_New; - ssl_api_object = PyCObject_FromVoidPtr((void *)ssl_API, NULL); - if (ssl_api_object != NULL) { - /* PyModule_AddObject steals a reference. - */ - Py_INCREF(ssl_api_object); - PyModule_AddObject(module, "_C_API", ssl_api_object); - } -#endif - - /* Exceptions */ -/* - * ADD_EXCEPTION(dict,name,base) expands to a correct Exception declaration, - * inserting OpenSSL.SSL.name into dict, derviving the exception from base. - */ -#define ADD_EXCEPTION(_name, _base) \ -do { \ - ssl_##_name = PyErr_NewException("OpenSSL.SSL."#_name, _base, NULL);\ - if (ssl_##_name == NULL) \ - goto error; \ - /* PyModule_AddObject steals a reference. */ \ - Py_INCREF(ssl_##_name); \ - if (PyModule_AddObject(module, #_name, ssl_##_name) != 0) \ - goto error; \ -} while (0) - - ssl_Error = PyErr_NewException("OpenSSL.SSL.Error", NULL, NULL); - if (ssl_Error == NULL) { - goto error; - } - - /* PyModule_AddObject steals a reference. */ - Py_INCREF(ssl_Error); - if (PyModule_AddObject(module, "Error", ssl_Error) != 0) - goto error; - - ADD_EXCEPTION(ZeroReturnError, ssl_Error); - ADD_EXCEPTION(WantReadError, ssl_Error); - ADD_EXCEPTION(WantWriteError, ssl_Error); - ADD_EXCEPTION(WantX509LookupError, ssl_Error); - ADD_EXCEPTION(SysCallError, ssl_Error); -#undef ADD_EXCEPTION - - /* Method constants */ - PyModule_AddIntConstant(module, "SSLv2_METHOD", ssl_SSLv2_METHOD); - PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD); - PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD); - PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD); - PyModule_AddIntConstant(module, "TLSv1_1_METHOD", ssl_TLSv1_1_METHOD); - PyModule_AddIntConstant(module, "TLSv1_2_METHOD", ssl_TLSv1_2_METHOD); - - /* Verify constants */ - PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE); - PyModule_AddIntConstant(module, "VERIFY_PEER", SSL_VERIFY_PEER); - PyModule_AddIntConstant(module, "VERIFY_FAIL_IF_NO_PEER_CERT", - SSL_VERIFY_FAIL_IF_NO_PEER_CERT); - PyModule_AddIntConstant(module, "VERIFY_CLIENT_ONCE", - SSL_VERIFY_CLIENT_ONCE); - - /* File type constants */ - PyModule_AddIntConstant(module, "FILETYPE_PEM", SSL_FILETYPE_PEM); - PyModule_AddIntConstant(module, "FILETYPE_ASN1", SSL_FILETYPE_ASN1); - - /* SSL option constants */ - PyModule_AddIntConstant(module, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); - PyModule_AddIntConstant(module, "OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA); - PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); - PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); - PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); -#ifdef SSL_OP_NO_TLSv1_1 - PyModule_AddIntConstant(module, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); -#endif -#ifdef SSL_OP_NO_TLSv1_2 - PyModule_AddIntConstant(module, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); -#endif - - /* More SSL option constants */ - PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG); - PyModule_AddIntConstant(module, "OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG); - PyModule_AddIntConstant(module, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG); - PyModule_AddIntConstant(module, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG); - PyModule_AddIntConstant(module, "OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER); - PyModule_AddIntConstant(module, "OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING); - PyModule_AddIntConstant(module, "OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG); - PyModule_AddIntConstant(module, "OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG); - PyModule_AddIntConstant(module, "OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG); - PyModule_AddIntConstant(module, "OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); - PyModule_AddIntConstant(module, "OP_ALL", SSL_OP_ALL); - PyModule_AddIntConstant(module, "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE); - PyModule_AddIntConstant(module, "OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG); - PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1); - PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2); - PyModule_AddIntConstant(module, "OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG); - PyModule_AddIntConstant(module, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); - -#ifdef SSL_OP_NO_COMPRESSION - PyModule_AddIntConstant(module, "OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION); -#endif - - /* DTLS related options. The first two of these were introduced in - * 2005, the third in 2007. To accomodate systems which are still using - * older versions, make them optional. */ -#ifdef SSL_OP_NO_QUERY_MTU - PyModule_AddIntConstant(module, "OP_NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU); -#endif -#ifdef SSL_OP_COOKIE_EXCHANGE - PyModule_AddIntConstant(module, "OP_COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE); -#endif -#ifdef SSL_OP_NO_TICKET - PyModule_AddIntConstant(module, "OP_NO_TICKET", SSL_OP_NO_TICKET); -#endif - - /* For SSL_set_shutdown */ - PyModule_AddIntConstant(module, "SENT_SHUTDOWN", SSL_SENT_SHUTDOWN); - PyModule_AddIntConstant(module, "RECEIVED_SHUTDOWN", SSL_RECEIVED_SHUTDOWN); - - /* For set_info_callback */ - PyModule_AddIntConstant(module, "SSL_ST_CONNECT", SSL_ST_CONNECT); - PyModule_AddIntConstant(module, "SSL_ST_ACCEPT", SSL_ST_ACCEPT); - PyModule_AddIntConstant(module, "SSL_ST_MASK", SSL_ST_MASK); - PyModule_AddIntConstant(module, "SSL_ST_INIT", SSL_ST_INIT); - PyModule_AddIntConstant(module, "SSL_ST_BEFORE", SSL_ST_BEFORE); - PyModule_AddIntConstant(module, "SSL_ST_OK", SSL_ST_OK); - PyModule_AddIntConstant(module, "SSL_ST_RENEGOTIATE", SSL_ST_RENEGOTIATE); - PyModule_AddIntConstant(module, "SSL_CB_LOOP", SSL_CB_LOOP); - PyModule_AddIntConstant(module, "SSL_CB_EXIT", SSL_CB_EXIT); - PyModule_AddIntConstant(module, "SSL_CB_READ", SSL_CB_READ); - PyModule_AddIntConstant(module, "SSL_CB_WRITE", SSL_CB_WRITE); - PyModule_AddIntConstant(module, "SSL_CB_ALERT", SSL_CB_ALERT); - PyModule_AddIntConstant(module, "SSL_CB_READ_ALERT", SSL_CB_READ_ALERT); - PyModule_AddIntConstant(module, "SSL_CB_WRITE_ALERT", SSL_CB_WRITE_ALERT); - PyModule_AddIntConstant(module, "SSL_CB_ACCEPT_LOOP", SSL_CB_ACCEPT_LOOP); - PyModule_AddIntConstant(module, "SSL_CB_ACCEPT_EXIT", SSL_CB_ACCEPT_EXIT); - PyModule_AddIntConstant(module, "SSL_CB_CONNECT_LOOP", SSL_CB_CONNECT_LOOP); - PyModule_AddIntConstant(module, "SSL_CB_CONNECT_EXIT", SSL_CB_CONNECT_EXIT); - PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_START", SSL_CB_HANDSHAKE_START); - PyModule_AddIntConstant(module, "SSL_CB_HANDSHAKE_DONE", SSL_CB_HANDSHAKE_DONE); - - /* Version information indicators, used with SSLeay_version */ - PyModule_AddIntConstant(module, "SSLEAY_VERSION", SSLEAY_VERSION); - PyModule_AddIntConstant(module, "SSLEAY_CFLAGS", SSLEAY_CFLAGS); - PyModule_AddIntConstant(module, "SSLEAY_BUILT_ON", SSLEAY_BUILT_ON); - PyModule_AddIntConstant(module, "SSLEAY_PLATFORM", SSLEAY_PLATFORM); - PyModule_AddIntConstant(module, "SSLEAY_DIR", SSLEAY_DIR); - - /* Cache modes */ -#define CACHE_MODE(mode) \ - PyModule_AddIntConstant(module, "SESS_CACHE_" #mode, SSL_SESS_CACHE_##mode) - - CACHE_MODE(OFF); - CACHE_MODE(CLIENT); - CACHE_MODE(SERVER); - CACHE_MODE(BOTH); - CACHE_MODE(NO_AUTO_CLEAR); - CACHE_MODE(NO_INTERNAL_LOOKUP); - CACHE_MODE(NO_INTERNAL_STORE); - CACHE_MODE(NO_INTERNAL); -#undef CACHE_MODE - - /* Straight up version number */ - PyModule_AddIntConstant(module, "OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER); - - /* SSL modes constants */ -#ifdef SSL_MODE_RELEASE_BUFFERS - PyModule_AddIntConstant(module, "MODE_RELEASE_BUFFERS", SSL_MODE_RELEASE_BUFFERS); -#endif - - if (!init_ssl_context(module)) - goto error; - if (!init_ssl_session(module)) - goto error; - if (!init_ssl_connection(module)) - goto error; - -#ifdef WITH_THREAD - /* - * Initialize this module's threading support structures. - */ - _pyOpenSSL_tstate_key = PyThread_create_key(); -#endif - - PyOpenSSL_MODRETURN(module); - -error: - PyOpenSSL_MODRETURN(NULL); - ; -} diff --git a/OpenSSL/ssl/ssl.h b/OpenSSL/ssl/ssl.h deleted file mode 100644 index 3074ba5..0000000 --- a/OpenSSL/ssl/ssl.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ssl.h - * - * Copyright (C) AB Strakt - * See LICENSE for details. - * - * Export functions and exceptions from the SSL sub module. - * See the file RATIONALE for a short explanation of why this module was written. - * - * Reviewed 2001-07-23 - * - */ -#ifndef PyOpenSSL_SSL_H_ -#define PyOpenSSL_SSL_H_ - -#include <Python.h> -#include <pythread.h> -#include "context.h" -#include "session.h" -#include "connection.h" -#include "../util.h" -#include "../crypto/crypto.h" - -extern PyObject *ssl_Error, /* Base class */ - *ssl_ZeroReturnError, /* Used with SSL_get_erorr */ - *ssl_WantReadError, /* ... */ - *ssl_WantWriteError, /* ... */ - *ssl_WantX509LookupError, /* ... */ - *ssl_SysCallError; /* Uses (errno,errstr) */ - -#define ssl_Context_New_NUM 0 -#define ssl_Context_New_RETURN ssl_ContextObj * -#define ssl_Context_New_PROTO (int method) - -#define ssl_Connection_New_NUM 1 -#define ssl_Connection_New_RETURN ssl_ConnectionObj * -#define ssl_Connection_New_PROTO (ssl_ContextObj *ctx, PyObject *sock) - -#define ssl_API_pointers 2 - -#ifdef WITH_THREAD -extern int _pyOpenSSL_tstate_key; -#endif /* WITH_THREAD */ - -#ifdef SSL_MODULE - -extern ssl_Context_New_RETURN ssl_Context_New ssl_Context_New_PROTO; -extern ssl_Connection_New_RETURN ssl_Connection_New ssl_Connection_New_PROTO; - -extern crypto_X509Obj* (*new_x509)(X509*, int); -extern crypto_X509NameObj* (*new_x509name)(X509_NAME*, int); -extern crypto_X509StoreObj* (*new_x509store)(X509_STORE*, int); - -#else /* SSL_MODULE */ - -extern void **ssl_API; - -#define ssl_Context_New \ - (*(ssl_Context_New_RETURN (*)ssl_Context_New_PROTO) ssl_API[ssl_Context_New_NUM]) -#define ssl_Connection_New \ - (*(ssl_Connection_New_RETURN (*)ssl_Connection_New_PROTO) ssl_API[ssl_Connection_New_NUM]) - -#define import_SSL() \ -{ \ - PyObject *module = PyImport_ImportModule("OpenSSL.SSL"); \ - if (module != NULL) { \ - PyObject *module_dict = PyModule_GetDict(module); \ - PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ - if (PyCObject_Check(c_api_object)) { \ - ssl_API = (void **)PyCObject_AsVoidPtr(c_api_object); \ - } \ - } \ -} - -#endif /* SSL_MODULE */ - -#endif /* PyOpenSSL_SSL_H_ */ |