/* SSL socket module 

   SSL support based on patches by Brian E Gallew and Laszlo Kovacs.

   This module is imported by socket.py. It should *not* be used
   directly.

*/

#include "Python.h"
enum py_ssl_error {
	/* these mirror ssl.h */
	PY_SSL_ERROR_NONE,                 
	PY_SSL_ERROR_SSL,                   
	PY_SSL_ERROR_WANT_READ,             
	PY_SSL_ERROR_WANT_WRITE,            
	PY_SSL_ERROR_WANT_X509_LOOKUP,      
	PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */
	PY_SSL_ERROR_ZERO_RETURN,           
	PY_SSL_ERROR_WANT_CONNECT,
	/* start of non ssl.h errorcodes */ 
	PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */
	PY_SSL_ERROR_INVALID_ERROR_CODE
};

/* Include symbols from _socket module */
#include "socketmodule.h"

/* Include OpenSSL header files */
#include "openssl/rsa.h"
#include "openssl/crypto.h"
#include "openssl/x509.h"
#include "openssl/pem.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/rand.h"

/* SSL error object */
static PyObject *PySSLErrorObject;

/* SSL socket object */

#define X509_NAME_MAXLEN 256

/* RAND_* APIs got added to OpenSSL in 0.9.5 */
#if OPENSSL_VERSION_NUMBER >= 0x0090500fL
# define HAVE_OPENSSL_RAND 1
#else
# undef HAVE_OPENSSL_RAND
#endif

typedef struct {
	PyObject_HEAD
	PySocketSockObject *Socket;	/* Socket on which we're layered */
	SSL_CTX* 	ctx;
	SSL*     	ssl;
	X509*    	server_cert;
	BIO*		sbio;
	char    	server[X509_NAME_MAXLEN];
	char		issuer[X509_NAME_MAXLEN];

} PySSLObject;

static PyTypeObject PySSL_Type;
static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
static int wait_for_timeout(PySocketSockObject *s, int writing);

#define PySSLObject_Check(v)	((v)->ob_type == &PySSL_Type)

/* XXX It might be helpful to augment the error message generated
   below with the name of the SSL function that generated the error.
   I expect it's obvious most of the time.
*/

static PyObject *
PySSL_SetError(PySSLObject *obj, int ret)
{
	PyObject *v, *n, *s;
	char *errstr;
	int err;
	enum py_ssl_error p;

	assert(ret <= 0);
    
	err = SSL_get_error(obj->ssl, ret);

	switch (err) {
	case SSL_ERROR_ZERO_RETURN:
		errstr = "TLS/SSL connection has been closed";
		p = PY_SSL_ERROR_ZERO_RETURN;
		break;
	case SSL_ERROR_WANT_READ:
		errstr = "The operation did not complete (read)";
		p = PY_SSL_ERROR_WANT_READ;
		break;
	case SSL_ERROR_WANT_WRITE:
		p = PY_SSL_ERROR_WANT_WRITE;
		errstr = "The operation did not complete (write)";
		break;
	case SSL_ERROR_WANT_X509_LOOKUP:
		p = PY_SSL_ERROR_WANT_X509_LOOKUP;
		errstr = "The operation did not complete (X509 lookup)";
		break;
	case SSL_ERROR_WANT_CONNECT:
		p = PY_SSL_ERROR_WANT_CONNECT;
		errstr = "The operation did not complete (connect)";
		break;
	case SSL_ERROR_SYSCALL:
	{
		unsigned long e = ERR_get_error();
		if (e == 0) {
			if (ret == 0) {
				p = PY_SSL_ERROR_EOF;
				errstr = "EOF occurred in violation of protocol";
			} else if (ret == -1) {
				/* the underlying BIO reported an I/O error */
				return obj->Socket->errorhandler();
			} else {  /* possible? */
				p = PY_SSL_ERROR_SYSCALL;
				errstr = "Some I/O error occurred";
			}
		} else {
			p = PY_SSL_ERROR_SYSCALL;
			/* XXX Protected by global interpreter lock */
			errstr = ERR_error_string(e, NULL);
		}
		break;
	}   
	case SSL_ERROR_SSL:
	{
		unsigned long e = ERR_get_error();
		p = PY_SSL_ERROR_SSL;
		if (e != 0) 
			/* XXX Protected by global interpreter lock */
			errstr = ERR_error_string(e, NULL);
		else { /* possible? */
			errstr = "A failure in the SSL library occurred";
		}
		break;
	}
	default:
		p = PY_SSL_ERROR_INVALID_ERROR_CODE;
		errstr = "Invalid error code";
	}
	n = PyInt_FromLong((long) p);
	if (n == NULL)
		return NULL;
	v = PyTuple_New(2);
	if (v == NULL) {
		Py_DECREF(n);
		return NULL;
	}

	s = PyString_FromString(errstr);
	if (s == NULL) {
		Py_DECREF(v);
		Py_DECREF(n);
	}
	PyTuple_SET_ITEM(v, 0, n);
	PyTuple_SET_ITEM(v, 1, s);
	PyErr_SetObject(PySSLErrorObject, v);
	return NULL;
}

static PySSLObject *
newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
{
	PySSLObject *self;
	char *errstr = NULL;
	int ret;
	int err;
	int timedout;

	self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
	if (self == NULL){
		errstr = "newPySSLObject error";
		goto fail;
	}
	memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
	memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
	self->server_cert = NULL;
	self->ssl = NULL;
	self->ctx = NULL;
	self->Socket = NULL;

	if ((key_file && !cert_file) || (!key_file && cert_file)) {
		errstr = "Both the key & certificate files must be specified";
		goto fail;
	}

	Py_BEGIN_ALLOW_THREADS
	self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
	Py_END_ALLOW_THREADS
	if (self->ctx == NULL) {
		errstr = "SSL_CTX_new error";
		goto fail;
	}

	if (key_file) {
		Py_BEGIN_ALLOW_THREADS
		ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
						SSL_FILETYPE_PEM);
		Py_END_ALLOW_THREADS
		if (ret < 1) {
			errstr = "SSL_CTX_use_PrivateKey_file error";
			goto fail;
		}

		Py_BEGIN_ALLOW_THREADS
		ret = SSL_CTX_use_certificate_chain_file(self->ctx,
						       cert_file);
		Py_END_ALLOW_THREADS
		if (ret < 1) {
			errstr = "SSL_CTX_use_certificate_chain_file error";
			goto fail;
		}
	}

	Py_BEGIN_ALLOW_THREADS
	SSL_CTX_set_verify(self->ctx,
			   SSL_VERIFY_NONE, NULL); /* set verify lvl */
	self->ssl = SSL_new(self->ctx); /* New ssl struct */
	Py_END_ALLOW_THREADS
	SSL_set_fd(self->ssl, Sock->sock_fd);	/* Set the socket for SSL */

	/* If the socket is is non-blocking mode or timeout mode, set the BIO
	 * to non-blocking mode (blocking is the default)
	 */
	if (Sock->sock_timeout >= 0.0) {
		/* Set both the read and write BIO's to non-blocking mode */
		BIO_set_nbio(SSL_get_rbio(self->ssl), 1);
		BIO_set_nbio(SSL_get_wbio(self->ssl), 1);
	}

	Py_BEGIN_ALLOW_THREADS
	SSL_set_connect_state(self->ssl);
	Py_END_ALLOW_THREADS

	/* Actually negotiate SSL connection */
	/* XXX If SSL_connect() returns 0, it's also a failure. */
	timedout = 0;
	do {
		Py_BEGIN_ALLOW_THREADS
		ret = SSL_connect(self->ssl);
		err = SSL_get_error(self->ssl, ret);
		Py_END_ALLOW_THREADS
		if (err == SSL_ERROR_WANT_READ) {
			timedout = wait_for_timeout(Sock, 0);
		} else if (err == SSL_ERROR_WANT_WRITE) {
			timedout = wait_for_timeout(Sock, 1);
		}
		if (timedout) {
			PyErr_SetString(PySSLErrorObject, "The connect operation timed out");
			return NULL;
		}
	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
	if (ret <= 0) {
		PySSL_SetError(self, ret);
		goto fail;
	}
	self->ssl->debug = 1;

	Py_BEGIN_ALLOW_THREADS
	if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
		X509_NAME_oneline(X509_get_subject_name(self->server_cert),
				  self->server, X509_NAME_MAXLEN);
		X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
				  self->issuer, X509_NAME_MAXLEN);
	}
	Py_END_ALLOW_THREADS
	self->Socket = Sock;
	Py_INCREF(self->Socket);
	return self;
 fail:
	if (errstr)
		PyErr_SetString(PySSLErrorObject, errstr);
	Py_DECREF(self);
	return NULL;
}

static PyObject *
PySocket_ssl(PyObject *self, PyObject *args)
{
	PySSLObject *rv;
	PySocketSockObject *Sock;
	char *key_file = NULL;
	char *cert_file = NULL;

	if (!PyArg_ParseTuple(args, "O!|zz:ssl",
			      PySocketModule.Sock_Type,
			      (PyObject*)&Sock,
			      &key_file, &cert_file))
		return NULL;

	rv = newPySSLObject(Sock, key_file, cert_file);
	if (rv == NULL)
		return NULL;
	return (PyObject *)rv;
}

PyDoc_STRVAR(ssl_doc,
"ssl(socket, [keyfile, certfile]) -> sslobject");

/* SSL object methods */

static PyObject *
PySSL_server(PySSLObject *self)
{
	return PyString_FromString(self->server);
}

static PyObject *
PySSL_issuer(PySSLObject *self)
{
	return PyString_FromString(self->issuer);
}


static void PySSL_dealloc(PySSLObject *self)
{
	if (self->server_cert)	/* Possible not to have one? */
		X509_free (self->server_cert);
	if (self->ssl)
	    SSL_free(self->ssl);
	if (self->ctx)
	    SSL_CTX_free(self->ctx);
	Py_XDECREF(self->Socket);
	PyObject_Del(self);
}

/* If the socket has a timeout, do a select() on the socket.
   The argument writing indicates the direction.
   Return non-zero if the socket timed out, zero otherwise.
 */
static int
wait_for_timeout(PySocketSockObject *s, int writing)
{
	fd_set fds;
	struct timeval tv;
	int rc;

	/* Nothing to do unless we're in timeout mode (not non-blocking) */
	if (s->sock_timeout <= 0.0)
		return 0;

	/* Guard against closed socket */
	if (s->sock_fd < 0)
		return 0;

	/* Construct the arguments to select */
	tv.tv_sec = (int)s->sock_timeout;
	tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
	FD_ZERO(&fds);
	FD_SET(s->sock_fd, &fds);

	/* See if the socket is ready */
	Py_BEGIN_ALLOW_THREADS
	if (writing)
		rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv);
	else
		rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv);
	Py_END_ALLOW_THREADS

	/* Return 1 on timeout, 0 otherwise */
	return rc == 0;
}

static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
{
	char *data;
	int len;
	int timedout;
	int err;

	if (!PyArg_ParseTuple(args, "s#:write", &data, &len))
		return NULL;

	timedout = wait_for_timeout(self->Socket, 1);
	if (timedout) {
		PyErr_SetString(PySSLErrorObject, "The write operation timed out");
		return NULL;
	}
	do {
		err = 0;
		Py_BEGIN_ALLOW_THREADS
		len = SSL_write(self->ssl, data, len);
		err = SSL_get_error(self->ssl, len);
		Py_END_ALLOW_THREADS
		if (err == SSL_ERROR_WANT_READ) {
			timedout = wait_for_timeout(self->Socket, 0);
		} else if (err == SSL_ERROR_WANT_WRITE) {
			timedout = wait_for_timeout(self->Socket, 1);
		}
		if (timedout) {
			PyErr_SetString(PySSLErrorObject, "The write operation timed out");
			return NULL;
		}
	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
	if (len > 0)
		return PyInt_FromLong(len);
	else
		return PySSL_SetError(self, len);
}

PyDoc_STRVAR(PySSL_SSLwrite_doc,
"write(s) -> len\n\
\n\
Writes the string s into the SSL object.  Returns the number\n\
of bytes written.");

static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
{
	PyObject *buf;
	int count = 0;
	int len = 1024;
	int timedout;
	int err;

	if (!PyArg_ParseTuple(args, "|i:read", &len))
		return NULL;

	if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
		return NULL;

	timedout = wait_for_timeout(self->Socket, 0);
	if (timedout) {
		PyErr_SetString(PySSLErrorObject, "The read operation timed out");
		return NULL;
	}
	do {
		err = 0;
		Py_BEGIN_ALLOW_THREADS
		count = SSL_read(self->ssl, PyString_AsString(buf), len);
		err = SSL_get_error(self->ssl, count);
		Py_END_ALLOW_THREADS
		if (err == SSL_ERROR_WANT_READ) {
			timedout = wait_for_timeout(self->Socket, 0);
		} else if (err == SSL_ERROR_WANT_WRITE) {
			timedout = wait_for_timeout(self->Socket, 1);
		}
		if (timedout) {
			PyErr_SetString(PySSLErrorObject, "The read operation timed out");
			return NULL;
		}
	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
 	if (count <= 0) {
		Py_DECREF(buf);
		return PySSL_SetError(self, count);
	}
	if (count != len)
		_PyString_Resize(&buf, count);
	return buf;
}

PyDoc_STRVAR(PySSL_SSLread_doc,
"read([len]) -> string\n\
\n\
Read up to len bytes from the SSL socket.");

static PyMethodDef PySSLMethods[] = {
	{"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
	          PySSL_SSLwrite_doc},
	{"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
	          PySSL_SSLread_doc},
	{"server", (PyCFunction)PySSL_server, METH_NOARGS},
	{"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
	{NULL, NULL}
};

static PyObject *PySSL_getattr(PySSLObject *self, char *name)
{
	return Py_FindMethod(PySSLMethods, (PyObject *)self, name);
}

static PyTypeObject PySSL_Type = {
	PyObject_HEAD_INIT(NULL)
	0,				/*ob_size*/
	"socket.SSL",			/*tp_name*/
	sizeof(PySSLObject),		/*tp_basicsize*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)PySSL_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)PySSL_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
	0,				/*tp_as_number*/
	0,				/*tp_as_sequence*/
	0,				/*tp_as_mapping*/
	0,				/*tp_hash*/
};

#ifdef HAVE_OPENSSL_RAND

/* helper routines for seeding the SSL PRNG */
static PyObject *
PySSL_RAND_add(PyObject *self, PyObject *args)
{
    char *buf;
    int len;
    double entropy;

    if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
	return NULL;
    RAND_add(buf, len, entropy);
    Py_INCREF(Py_None);
    return Py_None;
}

PyDoc_STRVAR(PySSL_RAND_add_doc,
"RAND_add(string, entropy)\n\
\n\
Mix string into the OpenSSL PRNG state.  entropy (a float) is a lower\n\
bound on the entropy contained in string.");

static PyObject *
PySSL_RAND_status(PyObject *self)
{
    return PyInt_FromLong(RAND_status());
}

PyDoc_STRVAR(PySSL_RAND_status_doc,
"RAND_status() -> 0 or 1\n\
\n\
Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
using the ssl() function.");

static PyObject *
PySSL_RAND_egd(PyObject *self, PyObject *arg)
{
    int bytes;

    if (!PyString_Check(arg))
	return PyErr_Format(PyExc_TypeError,
			    "RAND_egd() expected string, found %s",
			    arg->ob_type->tp_name);
    bytes = RAND_egd(PyString_AS_STRING(arg));
    if (bytes == -1) {
	PyErr_SetString(PySSLErrorObject,
			"EGD connection failed or EGD did not return "
			"enough data to seed the PRNG");
	return NULL;
    }
    return PyInt_FromLong(bytes);
}

PyDoc_STRVAR(PySSL_RAND_egd_doc,
"RAND_egd(path) -> bytes\n\
\n\
Queries the entropy gather daemon (EGD) on socket path.  Returns number\n\
of bytes read.  Raises socket.sslerror if connection to EGD fails or\n\
if it does provide enough data to seed PRNG.");

#endif

/* List of functions exported by this module. */

static PyMethodDef PySSL_methods[] = {
	{"ssl",			PySocket_ssl,
	 METH_VARARGS, ssl_doc},
#ifdef HAVE_OPENSSL_RAND
	{"RAND_add",            PySSL_RAND_add, METH_VARARGS, 
	 PySSL_RAND_add_doc},
	{"RAND_egd",            PySSL_RAND_egd, METH_O,
	 PySSL_RAND_egd_doc},
	{"RAND_status",         (PyCFunction)PySSL_RAND_status, METH_NOARGS,
	 PySSL_RAND_status_doc},
#endif
	{NULL,			NULL}		 /* Sentinel */
};


PyDoc_STRVAR(module_doc,
"Implementation module for SSL socket operations.  See the socket module\n\
for documentation.");

PyMODINIT_FUNC
init_ssl(void)
{
	PyObject *m, *d;

	PySSL_Type.ob_type = &PyType_Type;

	m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
	d = PyModule_GetDict(m);

	/* Load _socket module and its C API */
	if (PySocketModule_ImportModuleAndAPI())
 	    	return;

	/* Init OpenSSL */
	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();

	/* Add symbols to module dict */
	PySSLErrorObject = PyErr_NewException("socket.sslerror", NULL, NULL);
	if (PySSLErrorObject == NULL)
		return;
	PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
	if (PyDict_SetItemString(d, "SSLType",
				 (PyObject *)&PySSL_Type) != 0)
		return;
	PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
				PY_SSL_ERROR_ZERO_RETURN);
	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
				PY_SSL_ERROR_WANT_READ);
	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
				PY_SSL_ERROR_WANT_WRITE);
	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
				PY_SSL_ERROR_WANT_X509_LOOKUP);
	PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
				PY_SSL_ERROR_SYSCALL);
	PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
				PY_SSL_ERROR_SSL);
	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
				PY_SSL_ERROR_WANT_CONNECT);
	/* non ssl.h errorcodes */
	PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
				PY_SSL_ERROR_EOF);
	PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
				PY_SSL_ERROR_INVALID_ERROR_CODE);

}
