/* 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#endifstatic 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) {return;}if (ssl_obj->owner)ssl_socket = PyWeakref_GetObject(ssl_obj->owner);else if (ssl_obj->Socket)ssl_socket = PyWeakref_GetObject(ssl_obj->Socket);elsessl_socket = (PyObject *)ssl_obj;Py_INCREF(ssl_socket);/* assume that OpenSSL verifies all payload and buf len is of sufficientlength */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_HEADERcase 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_TYPEcase SSL3_RT_INNER_CONTENT_TYPE:msg_type = (int)cbuf[0];break;#endifdefault:/* 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_KEYLOGstatic 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();/* 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;}}ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl);assert(PySSLSocket_Check(ssl_obj));if (ssl_obj->ctx->keylog_bio == NULL) {return;}PySSL_BEGIN_ALLOW_THREADSPyThread_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_THREADSif (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_THREADSBIO_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_THREADSif (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_THREADSSSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback);return 0;}#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。