diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/tools/python3/src/Modules/_ssl/debughelpers.c | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Modules/_ssl/debughelpers.c')
-rw-r--r-- | contrib/tools/python3/src/Modules/_ssl/debughelpers.c | 446 |
1 files changed, 223 insertions, 223 deletions
diff --git a/contrib/tools/python3/src/Modules/_ssl/debughelpers.c b/contrib/tools/python3/src/Modules/_ssl/debughelpers.c index af56f9d28d..5ee781e159 100644 --- a/contrib/tools/python3/src/Modules/_ssl/debughelpers.c +++ b/contrib/tools/python3/src/Modules/_ssl/debughelpers.c @@ -1,223 +1,223 @@ -/* Debug helpers */ - -#ifndef SSL3_MT_CHANGE_CIPHER_SPEC -/* Dummy message type for handling CCS like a normal handshake message - * not defined in OpenSSL 1.0.2 - */ -#define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 -#endif - -static void -_PySSL_msg_callback(int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg) -{ - const char *cbuf = (const char *)buf; - PyGILState_STATE threadstate; - PyObject *res = NULL; - PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ - PyObject *ssl_socket = NULL; /* ssl.SSLSocket or ssl.SSLObject */ - int msg_type; - - threadstate = PyGILState_Ensure(); - - ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); - assert(PySSLSocket_Check(ssl_obj)); - if (ssl_obj->ctx->msg_cb == NULL) { - PyGILState_Release(threadstate); - return; - } - - if (ssl_obj->owner) - ssl_socket = PyWeakref_GetObject(ssl_obj->owner); - else if (ssl_obj->Socket) - ssl_socket = PyWeakref_GetObject(ssl_obj->Socket); - else - ssl_socket = (PyObject *)ssl_obj; - Py_INCREF(ssl_socket); - - /* assume that OpenSSL verifies all payload and buf len is of sufficient - length */ - switch(content_type) { - case SSL3_RT_CHANGE_CIPHER_SPEC: - msg_type = SSL3_MT_CHANGE_CIPHER_SPEC; - break; - case SSL3_RT_ALERT: - /* byte 0: level */ - /* byte 1: alert type */ - msg_type = (int)cbuf[1]; - break; - case SSL3_RT_HANDSHAKE: - msg_type = (int)cbuf[0]; - break; -#ifdef SSL3_RT_HEADER - case SSL3_RT_HEADER: - /* frame header encodes version in bytes 1..2 */ - version = cbuf[1] << 8 | cbuf[2]; - msg_type = (int)cbuf[0]; - break; -#endif -#ifdef SSL3_RT_INNER_CONTENT_TYPE - case SSL3_RT_INNER_CONTENT_TYPE: - msg_type = (int)cbuf[0]; - break; -#endif - default: - /* never SSL3_RT_APPLICATION_DATA */ - msg_type = -1; - break; - } - - res = PyObject_CallFunction( - ssl_obj->ctx->msg_cb, "Osiiiy#", - ssl_socket, write_p ? "write" : "read", - version, content_type, msg_type, - buf, len - ); - if (res == NULL) { - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); - } else { - Py_DECREF(res); - } - Py_XDECREF(ssl_socket); - - PyGILState_Release(threadstate); -} - - -static PyObject * -_PySSLContext_get_msg_callback(PySSLContext *self, void *c) { - if (self->msg_cb != NULL) { - Py_INCREF(self->msg_cb); - return self->msg_cb; - } else { - Py_RETURN_NONE; - } -} - -static int -_PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { - Py_CLEAR(self->msg_cb); - if (arg == Py_None) { - SSL_CTX_set_msg_callback(self->ctx, NULL); - } - else { - if (!PyCallable_Check(arg)) { - SSL_CTX_set_msg_callback(self->ctx, NULL); - PyErr_SetString(PyExc_TypeError, - "not a callable object"); - return -1; - } - Py_INCREF(arg); - self->msg_cb = arg; - SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); - } - return 0; -} - -#ifdef HAVE_OPENSSL_KEYLOG - -static void -_PySSL_keylog_callback(const SSL *ssl, const char *line) -{ - PyGILState_STATE threadstate; - PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ - int res, e; - static PyThread_type_lock *lock = NULL; - - threadstate = PyGILState_Ensure(); - - ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); - assert(PySSLSocket_Check(ssl_obj)); - if (ssl_obj->ctx->keylog_bio == NULL) { - return; - } - - /* Allocate a static lock to synchronize writes to keylog file. - * The lock is neither released on exit nor on fork(). The lock is - * also shared between all SSLContexts although contexts may write to - * their own files. IMHO that's good enough for a non-performance - * critical debug helper. - */ - if (lock == NULL) { - lock = PyThread_allocate_lock(); - if (lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, - &ssl_obj->exc_tb); - return; - } - } - - PySSL_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(lock, 1); - res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line); - e = errno; - (void)BIO_flush(ssl_obj->ctx->keylog_bio); - PyThread_release_lock(lock); - PySSL_END_ALLOW_THREADS - - if (res == -1) { - errno = e; - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, - ssl_obj->ctx->keylog_filename); - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); - } - PyGILState_Release(threadstate); -} - -static PyObject * -_PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { - if (self->keylog_filename != NULL) { - Py_INCREF(self->keylog_filename); - return self->keylog_filename; - } else { - Py_RETURN_NONE; - } -} - -static int -_PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { - FILE *fp; - /* Reset variables and callback first */ - SSL_CTX_set_keylog_callback(self->ctx, NULL); - Py_CLEAR(self->keylog_filename); - if (self->keylog_bio != NULL) { - BIO *bio = self->keylog_bio; - self->keylog_bio = NULL; - PySSL_BEGIN_ALLOW_THREADS - BIO_free_all(bio); - PySSL_END_ALLOW_THREADS - } - - if (arg == Py_None) { - /* None disables the callback */ - return 0; - } - - /* _Py_fopen_obj() also checks that arg is of proper type. */ - fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE); - if (fp == NULL) - return -1; - - self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT); - if (self->keylog_bio == NULL) { - PyErr_SetString(PySSLErrorObject, - "Can't malloc memory for keylog file"); - return -1; - } - Py_INCREF(arg); - self->keylog_filename = arg; - - /* Write a header for seekable, empty files (this excludes pipes). */ - PySSL_BEGIN_ALLOW_THREADS - if (BIO_tell(self->keylog_bio) == 0) { - BIO_puts(self->keylog_bio, - "# TLS secrets log file, generated by OpenSSL / Python\n"); - (void)BIO_flush(self->keylog_bio); - } - PySSL_END_ALLOW_THREADS - SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); - return 0; -} - -#endif +/* Debug helpers */ + +#ifndef SSL3_MT_CHANGE_CIPHER_SPEC +/* Dummy message type for handling CCS like a normal handshake message + * not defined in OpenSSL 1.0.2 + */ +#define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 +#endif + +static void +_PySSL_msg_callback(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + const char *cbuf = (const char *)buf; + PyGILState_STATE threadstate; + PyObject *res = NULL; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + PyObject *ssl_socket = NULL; /* ssl.SSLSocket or ssl.SSLObject */ + int msg_type; + + threadstate = PyGILState_Ensure(); + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->msg_cb == NULL) { + PyGILState_Release(threadstate); + return; + } + + if (ssl_obj->owner) + ssl_socket = PyWeakref_GetObject(ssl_obj->owner); + else if (ssl_obj->Socket) + ssl_socket = PyWeakref_GetObject(ssl_obj->Socket); + else + ssl_socket = (PyObject *)ssl_obj; + Py_INCREF(ssl_socket); + + /* assume that OpenSSL verifies all payload and buf len is of sufficient + length */ + switch(content_type) { + case SSL3_RT_CHANGE_CIPHER_SPEC: + msg_type = SSL3_MT_CHANGE_CIPHER_SPEC; + break; + case SSL3_RT_ALERT: + /* byte 0: level */ + /* byte 1: alert type */ + msg_type = (int)cbuf[1]; + break; + case SSL3_RT_HANDSHAKE: + msg_type = (int)cbuf[0]; + break; +#ifdef SSL3_RT_HEADER + case SSL3_RT_HEADER: + /* frame header encodes version in bytes 1..2 */ + version = cbuf[1] << 8 | cbuf[2]; + msg_type = (int)cbuf[0]; + break; +#endif +#ifdef SSL3_RT_INNER_CONTENT_TYPE + case SSL3_RT_INNER_CONTENT_TYPE: + msg_type = (int)cbuf[0]; + break; +#endif + default: + /* never SSL3_RT_APPLICATION_DATA */ + msg_type = -1; + break; + } + + res = PyObject_CallFunction( + ssl_obj->ctx->msg_cb, "Osiiiy#", + ssl_socket, write_p ? "write" : "read", + version, content_type, msg_type, + buf, len + ); + if (res == NULL) { + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } else { + Py_DECREF(res); + } + Py_XDECREF(ssl_socket); + + PyGILState_Release(threadstate); +} + + +static PyObject * +_PySSLContext_get_msg_callback(PySSLContext *self, void *c) { + if (self->msg_cb != NULL) { + Py_INCREF(self->msg_cb); + return self->msg_cb; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { + Py_CLEAR(self->msg_cb); + if (arg == Py_None) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + } + else { + if (!PyCallable_Check(arg)) { + SSL_CTX_set_msg_callback(self->ctx, NULL); + PyErr_SetString(PyExc_TypeError, + "not a callable object"); + return -1; + } + Py_INCREF(arg); + self->msg_cb = arg; + SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); + } + return 0; +} + +#ifdef HAVE_OPENSSL_KEYLOG + +static void +_PySSL_keylog_callback(const SSL *ssl, const char *line) +{ + PyGILState_STATE threadstate; + PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ + int res, e; + static PyThread_type_lock *lock = NULL; + + threadstate = PyGILState_Ensure(); + + ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); + assert(PySSLSocket_Check(ssl_obj)); + if (ssl_obj->ctx->keylog_bio == NULL) { + return; + } + + /* Allocate a static lock to synchronize writes to keylog file. + * The lock is neither released on exit nor on fork(). The lock is + * also shared between all SSLContexts although contexts may write to + * their own files. IMHO that's good enough for a non-performance + * critical debug helper. + */ + if (lock == NULL) { + lock = PyThread_allocate_lock(); + if (lock == NULL) { + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, + &ssl_obj->exc_tb); + return; + } + } + + PySSL_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(lock, 1); + res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line); + e = errno; + (void)BIO_flush(ssl_obj->ctx->keylog_bio); + PyThread_release_lock(lock); + PySSL_END_ALLOW_THREADS + + if (res == -1) { + errno = e; + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, + ssl_obj->ctx->keylog_filename); + PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + } + PyGILState_Release(threadstate); +} + +static PyObject * +_PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { + if (self->keylog_filename != NULL) { + Py_INCREF(self->keylog_filename); + return self->keylog_filename; + } else { + Py_RETURN_NONE; + } +} + +static int +_PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { + FILE *fp; + /* Reset variables and callback first */ + SSL_CTX_set_keylog_callback(self->ctx, NULL); + Py_CLEAR(self->keylog_filename); + if (self->keylog_bio != NULL) { + BIO *bio = self->keylog_bio; + self->keylog_bio = NULL; + PySSL_BEGIN_ALLOW_THREADS + BIO_free_all(bio); + PySSL_END_ALLOW_THREADS + } + + if (arg == Py_None) { + /* None disables the callback */ + return 0; + } + + /* _Py_fopen_obj() also checks that arg is of proper type. */ + fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE); + if (fp == NULL) + return -1; + + self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT); + if (self->keylog_bio == NULL) { + PyErr_SetString(PySSLErrorObject, + "Can't malloc memory for keylog file"); + return -1; + } + Py_INCREF(arg); + self->keylog_filename = arg; + + /* Write a header for seekable, empty files (this excludes pipes). */ + PySSL_BEGIN_ALLOW_THREADS + if (BIO_tell(self->keylog_bio) == 0) { + BIO_puts(self->keylog_bio, + "# TLS secrets log file, generated by OpenSSL / Python\n"); + (void)BIO_flush(self->keylog_bio); + } + PySSL_END_ALLOW_THREADS + SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback); + return 0; +} + +#endif |