summaryrefslogtreecommitdiffstats
path: root/Modules/_ssl.c
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2010-05-21 09:56:06 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2010-05-21 09:56:06 (GMT)
commitb52187710e4b486b33624fbde9ba646bc8e925fc (patch)
tree3f1c6369c64536edc721855273a793339a0fba9f /Modules/_ssl.c
parent955d1b22e2b7c1e42a23565e29ba150f1fc9a0ef (diff)
downloadcpython-b52187710e4b486b33624fbde9ba646bc8e925fc.zip
cpython-b52187710e4b486b33624fbde9ba646bc8e925fc.tar.gz
cpython-b52187710e4b486b33624fbde9ba646bc8e925fc.tar.bz2
Issue #4870: Add an `options` attribute to SSL contexts, as well as
several ``OP_*`` constants to the `ssl` module. This allows to selectively disable protocol versions, when used in combination with `PROTOCOL_SSLv23`.
Diffstat (limited to 'Modules/_ssl.c')
-rw-r--r--Modules/_ssl.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index e4b6fed..a9c772a 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -113,6 +113,13 @@ static unsigned int _ssl_locks_count = 0;
# undef HAVE_OPENSSL_RAND
#endif
+/* SSL_CTX_clear_options() and SSL_clear_options() were first added in OpenSSL 0.9.8m */
+#if OPENSSL_VERSION_NUMBER >= 0x009080dfL
+# define HAVE_SSL_CTX_CLEAR_OPTIONS
+#else
+# undef HAVE_SSL_CTX_CLEAR_OPTIONS
+#endif
+
typedef struct {
PyObject_HEAD
SSL_CTX *ctx;
@@ -1514,6 +1521,35 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c)
}
static PyObject *
+get_options(PySSLContext *self, void *c)
+{
+ return PyLong_FromLong(SSL_CTX_get_options(self->ctx));
+}
+
+static int
+set_options(PySSLContext *self, PyObject *arg, void *c)
+{
+ long new_opts, opts, set, clear;
+ if (!PyArg_Parse(arg, "l", &new_opts))
+ return -1;
+ opts = SSL_CTX_get_options(self->ctx);
+ clear = opts & ~new_opts;
+ set = ~opts & new_opts;
+ if (clear) {
+#ifdef HAVE_SSL_CTX_CLEAR_OPTIONS
+ SSL_CTX_clear_options(self->ctx, clear);
+#else
+ PyErr_SetString(PyExc_ValueError,
+ "can't clear options before OpenSSL 0.9.8m");
+ return -1;
+#endif
+ }
+ if (set)
+ SSL_CTX_set_options(self->ctx, set);
+ return 0;
+}
+
+static PyObject *
load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
{
char *kwlist[] = {"certfile", "keyfile", NULL};
@@ -1636,6 +1672,8 @@ context_wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwds)
}
static PyGetSetDef context_getsetlist[] = {
+ {"options", (getter) get_options,
+ (setter) set_options, NULL},
{"verify_mode", (getter) get_verify_mode,
(setter) set_verify_mode, NULL},
{NULL}, /* sentinel */
@@ -1953,6 +1991,12 @@ PyInit__ssl(void)
PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
PY_SSL_VERSION_TLS1);
+ /* protocol options */
+ PyModule_AddIntConstant(m, "OP_ALL", SSL_OP_ALL);
+ PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
+ PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
+ PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
+
/* OpenSSL version */
/* SSLeay() gives us the version of the library linked against,
which could be different from the headers version.