| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 1 | /* SSL socket module  | 
 | 2 |  | 
 | 3 |    SSL support based on patches by Brian E Gallew and Laszlo Kovacs. | 
 | 4 |  | 
 | 5 |    This module is imported by socket.py. It should *not* be used | 
 | 6 |    directly. | 
 | 7 |  | 
 | 8 | */ | 
 | 9 |  | 
 | 10 | #include "Python.h" | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 11 | enum py_ssl_error { | 
 | 12 | 	/* these mirror ssl.h */ | 
 | 13 | 	PY_SSL_ERROR_NONE,                  | 
 | 14 | 	PY_SSL_ERROR_SSL,                    | 
 | 15 | 	PY_SSL_ERROR_WANT_READ,              | 
 | 16 | 	PY_SSL_ERROR_WANT_WRITE,             | 
 | 17 | 	PY_SSL_ERROR_WANT_X509_LOOKUP,       | 
 | 18 | 	PY_SSL_ERROR_SYSCALL,     /* look at error stack/return value/errno */ | 
 | 19 | 	PY_SSL_ERROR_ZERO_RETURN,            | 
 | 20 | 	PY_SSL_ERROR_WANT_CONNECT, | 
 | 21 | 	/* start of non ssl.h errorcodes */  | 
 | 22 | 	PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */ | 
 | 23 | 	PY_SSL_ERROR_INVALID_ERROR_CODE | 
 | 24 | }; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 25 |  | 
 | 26 | /* Include symbols from _socket module */ | 
 | 27 | #include "socketmodule.h" | 
 | 28 |  | 
| Anthony Baxter | 93ab5fa | 2006-07-11 02:04:09 +0000 | [diff] [blame] | 29 | #if defined(HAVE_POLL_H)  | 
 | 30 | #include <poll.h> | 
 | 31 | #elif defined(HAVE_SYS_POLL_H) | 
 | 32 | #include <sys/poll.h> | 
 | 33 | #endif | 
 | 34 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 35 | /* Include OpenSSL header files */ | 
 | 36 | #include "openssl/rsa.h" | 
 | 37 | #include "openssl/crypto.h" | 
 | 38 | #include "openssl/x509.h" | 
 | 39 | #include "openssl/pem.h" | 
 | 40 | #include "openssl/ssl.h" | 
 | 41 | #include "openssl/err.h" | 
 | 42 | #include "openssl/rand.h" | 
 | 43 |  | 
 | 44 | /* SSL error object */ | 
 | 45 | static PyObject *PySSLErrorObject; | 
 | 46 |  | 
 | 47 | /* SSL socket object */ | 
 | 48 |  | 
 | 49 | #define X509_NAME_MAXLEN 256 | 
 | 50 |  | 
 | 51 | /* RAND_* APIs got added to OpenSSL in 0.9.5 */ | 
 | 52 | #if OPENSSL_VERSION_NUMBER >= 0x0090500fL | 
 | 53 | # define HAVE_OPENSSL_RAND 1 | 
 | 54 | #else | 
 | 55 | # undef HAVE_OPENSSL_RAND | 
 | 56 | #endif | 
 | 57 |  | 
 | 58 | typedef struct { | 
 | 59 | 	PyObject_HEAD | 
 | 60 | 	PySocketSockObject *Socket;	/* Socket on which we're layered */ | 
 | 61 | 	SSL_CTX* 	ctx; | 
 | 62 | 	SSL*     	ssl; | 
 | 63 | 	X509*    	server_cert; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 64 | 	char    	server[X509_NAME_MAXLEN]; | 
 | 65 | 	char		issuer[X509_NAME_MAXLEN]; | 
 | 66 |  | 
 | 67 | } PySSLObject; | 
 | 68 |  | 
| Jeremy Hylton | 938ace6 | 2002-07-17 16:30:39 +0000 | [diff] [blame] | 69 | static PyTypeObject PySSL_Type; | 
 | 70 | static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args); | 
 | 71 | static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args); | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 72 | static int check_socket_and_wait_for_timeout(PySocketSockObject *s,  | 
 | 73 | 					     int writing); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 74 |  | 
 | 75 | #define PySSLObject_Check(v)	((v)->ob_type == &PySSL_Type) | 
 | 76 |  | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 77 | typedef enum { | 
 | 78 | 	SOCKET_IS_NONBLOCKING, | 
 | 79 | 	SOCKET_IS_BLOCKING, | 
 | 80 | 	SOCKET_HAS_TIMED_OUT, | 
 | 81 | 	SOCKET_HAS_BEEN_CLOSED, | 
| Neal Norwitz | 389cea8 | 2006-02-13 00:35:21 +0000 | [diff] [blame] | 82 | 	SOCKET_TOO_LARGE_FOR_SELECT, | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 83 | 	SOCKET_OPERATION_OK | 
 | 84 | } timeout_state; | 
 | 85 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 86 | /* XXX It might be helpful to augment the error message generated | 
 | 87 |    below with the name of the SSL function that generated the error. | 
 | 88 |    I expect it's obvious most of the time. | 
 | 89 | */ | 
 | 90 |  | 
 | 91 | static PyObject * | 
 | 92 | PySSL_SetError(PySSLObject *obj, int ret) | 
 | 93 | { | 
 | 94 | 	PyObject *v, *n, *s; | 
 | 95 | 	char *errstr; | 
 | 96 | 	int err; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 97 | 	enum py_ssl_error p; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 98 |  | 
 | 99 | 	assert(ret <= 0); | 
 | 100 |      | 
 | 101 | 	err = SSL_get_error(obj->ssl, ret); | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 102 |  | 
 | 103 | 	switch (err) { | 
 | 104 | 	case SSL_ERROR_ZERO_RETURN: | 
 | 105 | 		errstr = "TLS/SSL connection has been closed"; | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 106 | 		p = PY_SSL_ERROR_ZERO_RETURN; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 107 | 		break; | 
 | 108 | 	case SSL_ERROR_WANT_READ: | 
 | 109 | 		errstr = "The operation did not complete (read)"; | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 110 | 		p = PY_SSL_ERROR_WANT_READ; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 111 | 		break; | 
 | 112 | 	case SSL_ERROR_WANT_WRITE: | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 113 | 		p = PY_SSL_ERROR_WANT_WRITE; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 114 | 		errstr = "The operation did not complete (write)"; | 
 | 115 | 		break; | 
 | 116 | 	case SSL_ERROR_WANT_X509_LOOKUP: | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 117 | 		p = PY_SSL_ERROR_WANT_X509_LOOKUP; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 118 | 		errstr = "The operation did not complete (X509 lookup)"; | 
 | 119 | 		break; | 
 | 120 | 	case SSL_ERROR_WANT_CONNECT: | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 121 | 		p = PY_SSL_ERROR_WANT_CONNECT; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 122 | 		errstr = "The operation did not complete (connect)"; | 
 | 123 | 		break; | 
 | 124 | 	case SSL_ERROR_SYSCALL: | 
 | 125 | 	{ | 
 | 126 | 		unsigned long e = ERR_get_error(); | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 127 | 		if (e == 0) { | 
| Neal Norwitz | a9002f8 | 2003-06-30 03:25:20 +0000 | [diff] [blame] | 128 | 			if (ret == 0 || !obj->Socket) { | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 129 | 				p = PY_SSL_ERROR_EOF; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 130 | 				errstr = "EOF occurred in violation of protocol"; | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 131 | 			} else if (ret == -1) { | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 132 | 				/* the underlying BIO reported an I/O error */ | 
 | 133 | 				return obj->Socket->errorhandler(); | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 134 | 			} else {  /* possible? */ | 
 | 135 | 				p = PY_SSL_ERROR_SYSCALL; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 136 | 				errstr = "Some I/O error occurred"; | 
 | 137 | 			} | 
 | 138 | 		} else { | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 139 | 			p = PY_SSL_ERROR_SYSCALL; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 140 | 			/* XXX Protected by global interpreter lock */ | 
 | 141 | 			errstr = ERR_error_string(e, NULL); | 
 | 142 | 		} | 
 | 143 | 		break; | 
 | 144 | 	}    | 
 | 145 | 	case SSL_ERROR_SSL: | 
 | 146 | 	{ | 
 | 147 | 		unsigned long e = ERR_get_error(); | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 148 | 		p = PY_SSL_ERROR_SSL; | 
 | 149 | 		if (e != 0)  | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 150 | 			/* XXX Protected by global interpreter lock */ | 
 | 151 | 			errstr = ERR_error_string(e, NULL); | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 152 | 		else { /* possible? */ | 
 | 153 | 			errstr = "A failure in the SSL library occurred"; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 154 | 		} | 
 | 155 | 		break; | 
 | 156 | 	} | 
 | 157 | 	default: | 
| Jeremy Hylton | 4e54730 | 2002-07-02 18:25:00 +0000 | [diff] [blame] | 158 | 		p = PY_SSL_ERROR_INVALID_ERROR_CODE; | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 159 | 		errstr = "Invalid error code"; | 
 | 160 | 	} | 
 | 161 | 	n = PyInt_FromLong((long) p); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 162 | 	if (n == NULL) | 
 | 163 | 		return NULL; | 
 | 164 | 	v = PyTuple_New(2); | 
 | 165 | 	if (v == NULL) { | 
 | 166 | 		Py_DECREF(n); | 
 | 167 | 		return NULL; | 
 | 168 | 	} | 
 | 169 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 170 | 	s = PyString_FromString(errstr); | 
 | 171 | 	if (s == NULL) { | 
 | 172 | 		Py_DECREF(v); | 
 | 173 | 		Py_DECREF(n); | 
 | 174 | 	} | 
 | 175 | 	PyTuple_SET_ITEM(v, 0, n); | 
 | 176 | 	PyTuple_SET_ITEM(v, 1, s); | 
 | 177 | 	PyErr_SetObject(PySSLErrorObject, v); | 
| Michael W. Hudson | 5910d81 | 2004-08-04 14:59:00 +0000 | [diff] [blame] | 178 | 	Py_DECREF(v); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 179 | 	return NULL; | 
 | 180 | } | 
 | 181 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 182 | static PySSLObject * | 
 | 183 | newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file) | 
 | 184 | { | 
 | 185 | 	PySSLObject *self; | 
 | 186 | 	char *errstr = NULL; | 
 | 187 | 	int ret; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 188 | 	int err; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 189 | 	int sockstate; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 190 |  | 
 | 191 | 	self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */ | 
| Neal Norwitz | 38e3b7d | 2006-05-11 07:51:59 +0000 | [diff] [blame] | 192 | 	if (self == NULL) | 
| Neal Norwitz | c6a989a | 2006-05-10 06:57:58 +0000 | [diff] [blame] | 193 | 		return NULL; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 194 | 	memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN); | 
 | 195 | 	memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN); | 
 | 196 | 	self->server_cert = NULL; | 
 | 197 | 	self->ssl = NULL; | 
 | 198 | 	self->ctx = NULL; | 
 | 199 | 	self->Socket = NULL; | 
 | 200 |  | 
 | 201 | 	if ((key_file && !cert_file) || (!key_file && cert_file)) { | 
 | 202 | 		errstr = "Both the key & certificate files must be specified"; | 
 | 203 | 		goto fail; | 
 | 204 | 	} | 
 | 205 |  | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 206 | 	Py_BEGIN_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 207 | 	self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */ | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 208 | 	Py_END_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 209 | 	if (self->ctx == NULL) { | 
 | 210 | 		errstr = "SSL_CTX_new error"; | 
 | 211 | 		goto fail; | 
 | 212 | 	} | 
 | 213 |  | 
 | 214 | 	if (key_file) { | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 215 | 		Py_BEGIN_ALLOW_THREADS | 
 | 216 | 		ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file, | 
 | 217 | 						SSL_FILETYPE_PEM); | 
 | 218 | 		Py_END_ALLOW_THREADS | 
 | 219 | 		if (ret < 1) { | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 220 | 			errstr = "SSL_CTX_use_PrivateKey_file error"; | 
 | 221 | 			goto fail; | 
 | 222 | 		} | 
 | 223 |  | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 224 | 		Py_BEGIN_ALLOW_THREADS | 
 | 225 | 		ret = SSL_CTX_use_certificate_chain_file(self->ctx, | 
 | 226 | 						       cert_file); | 
 | 227 | 		Py_END_ALLOW_THREADS | 
| Andrew M. Kuchling | 27d3dda | 2004-07-10 21:36:55 +0000 | [diff] [blame] | 228 | 		SSL_CTX_set_options(self->ctx, SSL_OP_ALL); /* ssl compatibility */ | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 229 | 		if (ret < 1) { | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 230 | 			errstr = "SSL_CTX_use_certificate_chain_file error"; | 
 | 231 | 			goto fail; | 
 | 232 | 		} | 
 | 233 | 	} | 
 | 234 |  | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 235 | 	Py_BEGIN_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 236 | 	SSL_CTX_set_verify(self->ctx, | 
 | 237 | 			   SSL_VERIFY_NONE, NULL); /* set verify lvl */ | 
 | 238 | 	self->ssl = SSL_new(self->ctx); /* New ssl struct */ | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 239 | 	Py_END_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 240 | 	SSL_set_fd(self->ssl, Sock->sock_fd);	/* Set the socket for SSL */ | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 241 |  | 
| Walter Dörwald | f0dfc7a | 2003-10-20 14:01:56 +0000 | [diff] [blame] | 242 | 	/* If the socket is in non-blocking mode or timeout mode, set the BIO | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 243 | 	 * to non-blocking mode (blocking is the default) | 
 | 244 | 	 */ | 
 | 245 | 	if (Sock->sock_timeout >= 0.0) { | 
 | 246 | 		/* Set both the read and write BIO's to non-blocking mode */ | 
 | 247 | 		BIO_set_nbio(SSL_get_rbio(self->ssl), 1); | 
 | 248 | 		BIO_set_nbio(SSL_get_wbio(self->ssl), 1); | 
 | 249 | 	} | 
 | 250 |  | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 251 | 	Py_BEGIN_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 252 | 	SSL_set_connect_state(self->ssl); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 253 | 	Py_END_ALLOW_THREADS | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 254 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 255 | 	/* Actually negotiate SSL connection */ | 
 | 256 | 	/* XXX If SSL_connect() returns 0, it's also a failure. */ | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 257 | 	sockstate = 0; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 258 | 	do { | 
 | 259 | 		Py_BEGIN_ALLOW_THREADS | 
 | 260 | 		ret = SSL_connect(self->ssl); | 
 | 261 | 		err = SSL_get_error(self->ssl, ret); | 
 | 262 | 		Py_END_ALLOW_THREADS | 
| Martin v. Löwis | afec8e3 | 2003-06-28 07:40:23 +0000 | [diff] [blame] | 263 | 		if(PyErr_CheckSignals()) { | 
 | 264 |                         goto fail; | 
 | 265 | 		} | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 266 | 		if (err == SSL_ERROR_WANT_READ) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 267 | 			sockstate = check_socket_and_wait_for_timeout(Sock, 0); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 268 | 		} else if (err == SSL_ERROR_WANT_WRITE) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 269 | 			sockstate = check_socket_and_wait_for_timeout(Sock, 1); | 
 | 270 | 		} else { | 
 | 271 | 			sockstate = SOCKET_OPERATION_OK; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 272 | 		} | 
| Neal Norwitz | 19cbcad | 2006-02-07 06:59:20 +0000 | [diff] [blame] | 273 | 	        if (sockstate == SOCKET_HAS_TIMED_OUT) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 274 | 			PyErr_SetString(PySSLErrorObject, "The connect operation timed out"); | 
| Martin v. Löwis | afec8e3 | 2003-06-28 07:40:23 +0000 | [diff] [blame] | 275 | 			goto fail; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 276 | 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { | 
 | 277 | 			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed."); | 
 | 278 | 			goto fail; | 
| Neal Norwitz | 389cea8 | 2006-02-13 00:35:21 +0000 | [diff] [blame] | 279 | 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { | 
| Neal Norwitz | 082b2df | 2006-02-07 07:04:46 +0000 | [diff] [blame] | 280 | 			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); | 
 | 281 | 			goto fail; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 282 | 		} else if (sockstate == SOCKET_IS_NONBLOCKING) { | 
 | 283 | 			break; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 284 | 		} | 
 | 285 | 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 286 | 	if (ret <= 0) { | 
 | 287 | 		PySSL_SetError(self, ret); | 
 | 288 | 		goto fail; | 
 | 289 | 	} | 
 | 290 | 	self->ssl->debug = 1; | 
 | 291 |  | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 292 | 	Py_BEGIN_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 293 | 	if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) { | 
 | 294 | 		X509_NAME_oneline(X509_get_subject_name(self->server_cert), | 
 | 295 | 				  self->server, X509_NAME_MAXLEN); | 
 | 296 | 		X509_NAME_oneline(X509_get_issuer_name(self->server_cert), | 
 | 297 | 				  self->issuer, X509_NAME_MAXLEN); | 
 | 298 | 	} | 
| Martin v. Löwis | 09c35f7 | 2002-07-28 09:57:45 +0000 | [diff] [blame] | 299 | 	Py_END_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 300 | 	self->Socket = Sock; | 
 | 301 | 	Py_INCREF(self->Socket); | 
 | 302 | 	return self; | 
 | 303 |  fail: | 
 | 304 | 	if (errstr) | 
 | 305 | 		PyErr_SetString(PySSLErrorObject, errstr); | 
 | 306 | 	Py_DECREF(self); | 
 | 307 | 	return NULL; | 
 | 308 | } | 
 | 309 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 310 | static PyObject * | 
 | 311 | PySocket_ssl(PyObject *self, PyObject *args) | 
 | 312 | { | 
 | 313 | 	PySSLObject *rv; | 
 | 314 | 	PySocketSockObject *Sock; | 
 | 315 | 	char *key_file = NULL; | 
 | 316 | 	char *cert_file = NULL; | 
 | 317 |  | 
 | 318 | 	if (!PyArg_ParseTuple(args, "O!|zz:ssl", | 
 | 319 | 			      PySocketModule.Sock_Type, | 
| Martin v. Löwis | a811c38 | 2006-10-19 11:00:37 +0000 | [diff] [blame] | 320 | 			      &Sock, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 321 | 			      &key_file, &cert_file)) | 
 | 322 | 		return NULL; | 
 | 323 |  | 
 | 324 | 	rv = newPySSLObject(Sock, key_file, cert_file); | 
 | 325 | 	if (rv == NULL) | 
 | 326 | 		return NULL; | 
 | 327 | 	return (PyObject *)rv; | 
 | 328 | } | 
 | 329 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 330 | PyDoc_STRVAR(ssl_doc, | 
 | 331 | "ssl(socket, [keyfile, certfile]) -> sslobject"); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 332 |  | 
 | 333 | /* SSL object methods */ | 
 | 334 |  | 
 | 335 | static PyObject * | 
 | 336 | PySSL_server(PySSLObject *self) | 
 | 337 | { | 
 | 338 | 	return PyString_FromString(self->server); | 
 | 339 | } | 
 | 340 |  | 
 | 341 | static PyObject * | 
 | 342 | PySSL_issuer(PySSLObject *self) | 
 | 343 | { | 
 | 344 | 	return PyString_FromString(self->issuer); | 
 | 345 | } | 
 | 346 |  | 
 | 347 |  | 
 | 348 | static void PySSL_dealloc(PySSLObject *self) | 
 | 349 | { | 
 | 350 | 	if (self->server_cert)	/* Possible not to have one? */ | 
 | 351 | 		X509_free (self->server_cert); | 
 | 352 | 	if (self->ssl) | 
 | 353 | 	    SSL_free(self->ssl); | 
 | 354 | 	if (self->ctx) | 
 | 355 | 	    SSL_CTX_free(self->ctx); | 
 | 356 | 	Py_XDECREF(self->Socket); | 
 | 357 | 	PyObject_Del(self); | 
 | 358 | } | 
 | 359 |  | 
| Anthony Baxter | 93ab5fa | 2006-07-11 02:04:09 +0000 | [diff] [blame] | 360 | /* If the socket has a timeout, do a select()/poll() on the socket. | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 361 |    The argument writing indicates the direction. | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 362 |    Returns one of the possibilities in the timeout_state enum (above). | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 363 |  */ | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 364 |  | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 365 | static int | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 366 | check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 367 | { | 
 | 368 | 	fd_set fds; | 
 | 369 | 	struct timeval tv; | 
 | 370 | 	int rc; | 
 | 371 |  | 
 | 372 | 	/* Nothing to do unless we're in timeout mode (not non-blocking) */ | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 373 | 	if (s->sock_timeout < 0.0) | 
 | 374 | 		return SOCKET_IS_BLOCKING; | 
 | 375 | 	else if (s->sock_timeout == 0.0) | 
 | 376 | 		return SOCKET_IS_NONBLOCKING; | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 377 |  | 
 | 378 | 	/* Guard against closed socket */ | 
 | 379 | 	if (s->sock_fd < 0) | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 380 | 		return SOCKET_HAS_BEEN_CLOSED; | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 381 |  | 
| Anthony Baxter | 93ab5fa | 2006-07-11 02:04:09 +0000 | [diff] [blame] | 382 | 	/* Prefer poll, if available, since you can poll() any fd | 
 | 383 | 	 * which can't be done with select(). */ | 
 | 384 | #ifdef HAVE_POLL | 
 | 385 | 	{ | 
 | 386 | 		struct pollfd pollfd; | 
 | 387 | 		int timeout; | 
 | 388 |  | 
 | 389 | 		pollfd.fd = s->sock_fd; | 
 | 390 | 		pollfd.events = writing ? POLLOUT : POLLIN; | 
 | 391 |  | 
 | 392 | 		/* s->sock_timeout is in seconds, timeout in ms */ | 
 | 393 | 		timeout = (int)(s->sock_timeout * 1000 + 0.5); | 
 | 394 | 		Py_BEGIN_ALLOW_THREADS | 
 | 395 | 		rc = poll(&pollfd, 1, timeout); | 
 | 396 | 		Py_END_ALLOW_THREADS | 
 | 397 |  | 
 | 398 | 		goto normal_return; | 
 | 399 | 	} | 
 | 400 | #endif | 
 | 401 |  | 
| Neal Norwitz | 082b2df | 2006-02-07 07:04:46 +0000 | [diff] [blame] | 402 | 	/* Guard against socket too large for select*/ | 
| Martin v. Löwis | f84d1b9 | 2006-02-11 09:27:05 +0000 | [diff] [blame] | 403 | #ifndef Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE | 
| Neal Norwitz | 082b2df | 2006-02-07 07:04:46 +0000 | [diff] [blame] | 404 | 	if (s->sock_fd >= FD_SETSIZE) | 
| Neal Norwitz | 389cea8 | 2006-02-13 00:35:21 +0000 | [diff] [blame] | 405 | 		return SOCKET_TOO_LARGE_FOR_SELECT; | 
| Martin v. Löwis | f84d1b9 | 2006-02-11 09:27:05 +0000 | [diff] [blame] | 406 | #endif | 
| Neal Norwitz | 082b2df | 2006-02-07 07:04:46 +0000 | [diff] [blame] | 407 |  | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 408 | 	/* Construct the arguments to select */ | 
 | 409 | 	tv.tv_sec = (int)s->sock_timeout; | 
 | 410 | 	tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); | 
 | 411 | 	FD_ZERO(&fds); | 
 | 412 | 	FD_SET(s->sock_fd, &fds); | 
 | 413 |  | 
 | 414 | 	/* See if the socket is ready */ | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 415 | 	Py_BEGIN_ALLOW_THREADS | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 416 | 	if (writing) | 
 | 417 | 		rc = select(s->sock_fd+1, NULL, &fds, NULL, &tv); | 
 | 418 | 	else | 
 | 419 | 		rc = select(s->sock_fd+1, &fds, NULL, NULL, &tv); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 420 | 	Py_END_ALLOW_THREADS | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 421 |  | 
| Anthony Baxter | 93ab5fa | 2006-07-11 02:04:09 +0000 | [diff] [blame] | 422 | normal_return: | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 423 | 	/* Return SOCKET_TIMED_OUT on timeout, SOCKET_OPERATION_OK otherwise | 
 | 424 | 	   (when we are able to write or when there's something to read) */ | 
 | 425 | 	return rc == 0 ? SOCKET_HAS_TIMED_OUT : SOCKET_OPERATION_OK; | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 426 | } | 
 | 427 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 428 | static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args) | 
 | 429 | { | 
 | 430 | 	char *data; | 
 | 431 | 	int len; | 
| Martin v. Löwis | 405a795 | 2003-10-27 14:24:37 +0000 | [diff] [blame] | 432 | 	int count; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 433 | 	int sockstate; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 434 | 	int err; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 435 |  | 
| Martin v. Löwis | 405a795 | 2003-10-27 14:24:37 +0000 | [diff] [blame] | 436 | 	if (!PyArg_ParseTuple(args, "s#:write", &data, &count)) | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 437 | 		return NULL; | 
 | 438 |  | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 439 | 	sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); | 
 | 440 | 	if (sockstate == SOCKET_HAS_TIMED_OUT) { | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 441 | 		PyErr_SetString(PySSLErrorObject, "The write operation timed out"); | 
 | 442 | 		return NULL; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 443 | 	} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { | 
 | 444 | 		PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed."); | 
 | 445 | 		return NULL; | 
| Neal Norwitz | 389cea8 | 2006-02-13 00:35:21 +0000 | [diff] [blame] | 446 | 	} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { | 
| Neal Norwitz | 082b2df | 2006-02-07 07:04:46 +0000 | [diff] [blame] | 447 | 		PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); | 
 | 448 | 		return NULL; | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 449 | 	} | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 450 | 	do { | 
 | 451 | 		err = 0; | 
 | 452 | 		Py_BEGIN_ALLOW_THREADS | 
| Martin v. Löwis | 405a795 | 2003-10-27 14:24:37 +0000 | [diff] [blame] | 453 | 		len = SSL_write(self->ssl, data, count); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 454 | 		err = SSL_get_error(self->ssl, len); | 
 | 455 | 		Py_END_ALLOW_THREADS | 
| Martin v. Löwis | afec8e3 | 2003-06-28 07:40:23 +0000 | [diff] [blame] | 456 | 		if(PyErr_CheckSignals()) { | 
 | 457 | 			return NULL; | 
 | 458 | 		} | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 459 | 		if (err == SSL_ERROR_WANT_READ) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 460 | 			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 461 | 		} else if (err == SSL_ERROR_WANT_WRITE) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 462 | 			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); | 
 | 463 | 		} else { | 
 | 464 | 			sockstate = SOCKET_OPERATION_OK; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 465 | 		} | 
| Neal Norwitz | 19cbcad | 2006-02-07 06:59:20 +0000 | [diff] [blame] | 466 | 	        if (sockstate == SOCKET_HAS_TIMED_OUT) { | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 467 | 			PyErr_SetString(PySSLErrorObject, "The write operation timed out"); | 
 | 468 | 			return NULL; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 469 | 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { | 
 | 470 | 			PyErr_SetString(PySSLErrorObject, "Underlying socket has been closed."); | 
 | 471 | 			return NULL; | 
 | 472 | 		} else if (sockstate == SOCKET_IS_NONBLOCKING) { | 
 | 473 | 			break; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 474 | 		} | 
 | 475 | 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 476 | 	if (len > 0) | 
 | 477 | 		return PyInt_FromLong(len); | 
 | 478 | 	else | 
 | 479 | 		return PySSL_SetError(self, len); | 
 | 480 | } | 
 | 481 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 482 | PyDoc_STRVAR(PySSL_SSLwrite_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 483 | "write(s) -> len\n\ | 
 | 484 | \n\ | 
 | 485 | Writes the string s into the SSL object.  Returns the number\n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 486 | of bytes written."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 487 |  | 
 | 488 | static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args) | 
 | 489 | { | 
 | 490 | 	PyObject *buf; | 
 | 491 | 	int count = 0; | 
 | 492 | 	int len = 1024; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 493 | 	int sockstate; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 494 | 	int err; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 495 |  | 
 | 496 | 	if (!PyArg_ParseTuple(args, "|i:read", &len)) | 
 | 497 | 		return NULL; | 
 | 498 |  | 
 | 499 | 	if (!(buf = PyString_FromStringAndSize((char *) 0, len))) | 
 | 500 | 		return NULL; | 
| Georg Brandl | 43f08a8 | 2006-03-31 18:01:16 +0000 | [diff] [blame] | 501 | 	 | 
 | 502 | 	/* first check if there are bytes ready to be read */ | 
 | 503 | 	Py_BEGIN_ALLOW_THREADS | 
 | 504 | 	count = SSL_pending(self->ssl); | 
 | 505 | 	Py_END_ALLOW_THREADS | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 506 |  | 
| Georg Brandl | 43f08a8 | 2006-03-31 18:01:16 +0000 | [diff] [blame] | 507 | 	if (!count) { | 
 | 508 | 		sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); | 
 | 509 | 		if (sockstate == SOCKET_HAS_TIMED_OUT) { | 
 | 510 | 			PyErr_SetString(PySSLErrorObject, "The read operation timed out"); | 
 | 511 | 			Py_DECREF(buf); | 
 | 512 | 			return NULL; | 
 | 513 | 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { | 
 | 514 | 			PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select()."); | 
 | 515 | 			return NULL; | 
 | 516 | 		} | 
| Guido van Rossum | 99d4abf | 2003-01-27 22:22:50 +0000 | [diff] [blame] | 517 | 	} | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 518 | 	do { | 
 | 519 | 		err = 0; | 
 | 520 | 		Py_BEGIN_ALLOW_THREADS | 
 | 521 | 		count = SSL_read(self->ssl, PyString_AsString(buf), len); | 
 | 522 | 		err = SSL_get_error(self->ssl, count); | 
 | 523 | 		Py_END_ALLOW_THREADS | 
| Martin v. Löwis | afec8e3 | 2003-06-28 07:40:23 +0000 | [diff] [blame] | 524 | 		if(PyErr_CheckSignals()) { | 
 | 525 | 			Py_DECREF(buf); | 
 | 526 | 			return NULL; | 
 | 527 | 		} | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 528 | 		if (err == SSL_ERROR_WANT_READ) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 529 | 			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 530 | 		} else if (err == SSL_ERROR_WANT_WRITE) { | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 531 | 			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1); | 
 | 532 | 		} else { | 
 | 533 | 			sockstate = SOCKET_OPERATION_OK; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 534 | 		} | 
| Neal Norwitz | 19cbcad | 2006-02-07 06:59:20 +0000 | [diff] [blame] | 535 | 	        if (sockstate == SOCKET_HAS_TIMED_OUT) { | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 536 | 			PyErr_SetString(PySSLErrorObject, "The read operation timed out"); | 
| Martin v. Löwis | afec8e3 | 2003-06-28 07:40:23 +0000 | [diff] [blame] | 537 | 			Py_DECREF(buf); | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 538 | 			return NULL; | 
| Andrew M. Kuchling | 9c3efe3 | 2004-07-10 21:15:17 +0000 | [diff] [blame] | 539 | 		} else if (sockstate == SOCKET_IS_NONBLOCKING) { | 
 | 540 | 			break; | 
| Guido van Rossum | 4f707ac | 2003-01-31 18:13:18 +0000 | [diff] [blame] | 541 | 		} | 
 | 542 | 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 543 |  	if (count <= 0) { | 
 | 544 | 		Py_DECREF(buf); | 
 | 545 | 		return PySSL_SetError(self, count); | 
 | 546 | 	} | 
| Tim Peters | 5de9842 | 2002-04-27 18:44:32 +0000 | [diff] [blame] | 547 | 	if (count != len) | 
 | 548 | 		_PyString_Resize(&buf, count); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 549 | 	return buf; | 
 | 550 | } | 
 | 551 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 552 | PyDoc_STRVAR(PySSL_SSLread_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 553 | "read([len]) -> string\n\ | 
 | 554 | \n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 555 | Read up to len bytes from the SSL socket."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 556 |  | 
 | 557 | static PyMethodDef PySSLMethods[] = { | 
 | 558 | 	{"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS, | 
 | 559 | 	          PySSL_SSLwrite_doc}, | 
 | 560 | 	{"read", (PyCFunction)PySSL_SSLread, METH_VARARGS, | 
 | 561 | 	          PySSL_SSLread_doc}, | 
 | 562 | 	{"server", (PyCFunction)PySSL_server, METH_NOARGS}, | 
 | 563 | 	{"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS}, | 
 | 564 | 	{NULL, NULL} | 
 | 565 | }; | 
 | 566 |  | 
 | 567 | static PyObject *PySSL_getattr(PySSLObject *self, char *name) | 
 | 568 | { | 
 | 569 | 	return Py_FindMethod(PySSLMethods, (PyObject *)self, name); | 
 | 570 | } | 
 | 571 |  | 
| Jeremy Hylton | 938ace6 | 2002-07-17 16:30:39 +0000 | [diff] [blame] | 572 | static PyTypeObject PySSL_Type = { | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 573 | 	PyObject_HEAD_INIT(NULL) | 
 | 574 | 	0,				/*ob_size*/ | 
 | 575 | 	"socket.SSL",			/*tp_name*/ | 
 | 576 | 	sizeof(PySSLObject),		/*tp_basicsize*/ | 
 | 577 | 	0,				/*tp_itemsize*/ | 
 | 578 | 	/* methods */ | 
 | 579 | 	(destructor)PySSL_dealloc,	/*tp_dealloc*/ | 
 | 580 | 	0,				/*tp_print*/ | 
 | 581 | 	(getattrfunc)PySSL_getattr,	/*tp_getattr*/ | 
 | 582 | 	0,				/*tp_setattr*/ | 
 | 583 | 	0,				/*tp_compare*/ | 
 | 584 | 	0,				/*tp_repr*/ | 
 | 585 | 	0,				/*tp_as_number*/ | 
 | 586 | 	0,				/*tp_as_sequence*/ | 
 | 587 | 	0,				/*tp_as_mapping*/ | 
 | 588 | 	0,				/*tp_hash*/ | 
 | 589 | }; | 
 | 590 |  | 
 | 591 | #ifdef HAVE_OPENSSL_RAND | 
 | 592 |  | 
 | 593 | /* helper routines for seeding the SSL PRNG */ | 
 | 594 | static PyObject * | 
 | 595 | PySSL_RAND_add(PyObject *self, PyObject *args) | 
 | 596 | { | 
 | 597 |     char *buf; | 
 | 598 |     int len; | 
 | 599 |     double entropy; | 
 | 600 |  | 
 | 601 |     if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) | 
 | 602 | 	return NULL; | 
 | 603 |     RAND_add(buf, len, entropy); | 
 | 604 |     Py_INCREF(Py_None); | 
 | 605 |     return Py_None; | 
 | 606 | } | 
 | 607 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 608 | PyDoc_STRVAR(PySSL_RAND_add_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 609 | "RAND_add(string, entropy)\n\ | 
 | 610 | \n\ | 
 | 611 | Mix string into the OpenSSL PRNG state.  entropy (a float) is a lower\n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 612 | bound on the entropy contained in string."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 613 |  | 
 | 614 | static PyObject * | 
 | 615 | PySSL_RAND_status(PyObject *self) | 
 | 616 | { | 
 | 617 |     return PyInt_FromLong(RAND_status()); | 
 | 618 | } | 
 | 619 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 620 | PyDoc_STRVAR(PySSL_RAND_status_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 621 | "RAND_status() -> 0 or 1\n\ | 
 | 622 | \n\ | 
 | 623 | Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ | 
 | 624 | It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 625 | using the ssl() function."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 626 |  | 
 | 627 | static PyObject * | 
 | 628 | PySSL_RAND_egd(PyObject *self, PyObject *arg) | 
 | 629 | { | 
 | 630 |     int bytes; | 
 | 631 |  | 
 | 632 |     if (!PyString_Check(arg)) | 
 | 633 | 	return PyErr_Format(PyExc_TypeError, | 
 | 634 | 			    "RAND_egd() expected string, found %s", | 
 | 635 | 			    arg->ob_type->tp_name); | 
 | 636 |     bytes = RAND_egd(PyString_AS_STRING(arg)); | 
 | 637 |     if (bytes == -1) { | 
 | 638 | 	PyErr_SetString(PySSLErrorObject, | 
 | 639 | 			"EGD connection failed or EGD did not return " | 
 | 640 | 			"enough data to seed the PRNG"); | 
 | 641 | 	return NULL; | 
 | 642 |     } | 
 | 643 |     return PyInt_FromLong(bytes); | 
 | 644 | } | 
 | 645 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 646 | PyDoc_STRVAR(PySSL_RAND_egd_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 647 | "RAND_egd(path) -> bytes\n\ | 
 | 648 | \n\ | 
 | 649 | Queries the entropy gather daemon (EGD) on socket path.  Returns number\n\ | 
 | 650 | of bytes read.  Raises socket.sslerror if connection to EGD fails or\n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 651 | if it does provide enough data to seed PRNG."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 652 |  | 
 | 653 | #endif | 
 | 654 |  | 
 | 655 | /* List of functions exported by this module. */ | 
 | 656 |  | 
 | 657 | static PyMethodDef PySSL_methods[] = { | 
 | 658 | 	{"ssl",			PySocket_ssl, | 
 | 659 | 	 METH_VARARGS, ssl_doc}, | 
 | 660 | #ifdef HAVE_OPENSSL_RAND | 
 | 661 | 	{"RAND_add",            PySSL_RAND_add, METH_VARARGS,  | 
 | 662 | 	 PySSL_RAND_add_doc}, | 
 | 663 | 	{"RAND_egd",            PySSL_RAND_egd, METH_O, | 
 | 664 | 	 PySSL_RAND_egd_doc}, | 
 | 665 | 	{"RAND_status",         (PyCFunction)PySSL_RAND_status, METH_NOARGS, | 
 | 666 | 	 PySSL_RAND_status_doc}, | 
 | 667 | #endif | 
 | 668 | 	{NULL,			NULL}		 /* Sentinel */ | 
 | 669 | }; | 
 | 670 |  | 
 | 671 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 672 | PyDoc_STRVAR(module_doc, | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 673 | "Implementation module for SSL socket operations.  See the socket module\n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 674 | for documentation."); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 675 |  | 
| Mark Hammond | fe51c6d | 2002-08-02 02:27:13 +0000 | [diff] [blame] | 676 | PyMODINIT_FUNC | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 677 | init_ssl(void) | 
 | 678 | { | 
 | 679 | 	PyObject *m, *d; | 
 | 680 |  | 
 | 681 | 	PySSL_Type.ob_type = &PyType_Type; | 
 | 682 |  | 
 | 683 | 	m = Py_InitModule3("_ssl", PySSL_methods, module_doc); | 
| Neal Norwitz | 1ac754f | 2006-01-19 06:09:39 +0000 | [diff] [blame] | 684 | 	if (m == NULL) | 
 | 685 | 		return; | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 686 | 	d = PyModule_GetDict(m); | 
 | 687 |  | 
 | 688 | 	/* Load _socket module and its C API */ | 
 | 689 | 	if (PySocketModule_ImportModuleAndAPI()) | 
 | 690 |  	    	return; | 
 | 691 |  | 
 | 692 | 	/* Init OpenSSL */ | 
 | 693 | 	SSL_load_error_strings(); | 
 | 694 | 	SSLeay_add_ssl_algorithms(); | 
 | 695 |  | 
 | 696 | 	/* Add symbols to module dict */ | 
| Brett Cannon | 06c3479 | 2004-03-23 23:16:54 +0000 | [diff] [blame] | 697 | 	PySSLErrorObject = PyErr_NewException("socket.sslerror", | 
 | 698 |                                                PySocketModule.error, | 
 | 699 |                                                NULL); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 700 | 	if (PySSLErrorObject == NULL) | 
 | 701 | 		return; | 
 | 702 | 	PyDict_SetItemString(d, "sslerror", PySSLErrorObject); | 
 | 703 | 	if (PyDict_SetItemString(d, "SSLType", | 
 | 704 | 				 (PyObject *)&PySSL_Type) != 0) | 
 | 705 | 		return; | 
 | 706 | 	PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 707 | 				PY_SSL_ERROR_ZERO_RETURN); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 708 | 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 709 | 				PY_SSL_ERROR_WANT_READ); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 710 | 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 711 | 				PY_SSL_ERROR_WANT_WRITE); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 712 | 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 713 | 				PY_SSL_ERROR_WANT_X509_LOOKUP); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 714 | 	PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 715 | 				PY_SSL_ERROR_SYSCALL); | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 716 | 	PyModule_AddIntConstant(m, "SSL_ERROR_SSL", | 
| Martin v. Löwis | 6af3e2d | 2002-04-20 07:47:40 +0000 | [diff] [blame] | 717 | 				PY_SSL_ERROR_SSL); | 
 | 718 | 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT", | 
 | 719 | 				PY_SSL_ERROR_WANT_CONNECT); | 
 | 720 | 	/* non ssl.h errorcodes */ | 
 | 721 | 	PyModule_AddIntConstant(m, "SSL_ERROR_EOF", | 
 | 722 | 				PY_SSL_ERROR_EOF); | 
 | 723 | 	PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE", | 
 | 724 | 				PY_SSL_ERROR_INVALID_ERROR_CODE); | 
 | 725 |  | 
| Marc-André Lemburg | a5d2b4c | 2002-02-16 18:23:30 +0000 | [diff] [blame] | 726 | } |