You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.3 KiB

  1. /* Debug helpers */
  2. #ifndef SSL3_MT_CHANGE_CIPHER_SPEC
  3. /* Dummy message type for handling CCS like a normal handshake message
  4. * not defined in OpenSSL 1.0.2
  5. */
  6. #define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101
  7. #endif
  8. static void
  9. _PySSL_msg_callback(int write_p, int version, int content_type,
  10. const void *buf, size_t len, SSL *ssl, void *arg)
  11. {
  12. const char *cbuf = (const char *)buf;
  13. PyGILState_STATE threadstate;
  14. PyObject *res = NULL;
  15. PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */
  16. PyObject *ssl_socket = NULL; /* ssl.SSLSocket or ssl.SSLObject */
  17. int msg_type;
  18. threadstate = PyGILState_Ensure();
  19. ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl);
  20. assert(PySSLSocket_Check(ssl_obj));
  21. if (ssl_obj->ctx->msg_cb == NULL) {
  22. PyGILState_Release(threadstate);
  23. return;
  24. }
  25. if (ssl_obj->owner)
  26. ssl_socket = PyWeakref_GetObject(ssl_obj->owner);
  27. else if (ssl_obj->Socket)
  28. ssl_socket = PyWeakref_GetObject(ssl_obj->Socket);
  29. else
  30. ssl_socket = (PyObject *)ssl_obj;
  31. Py_INCREF(ssl_socket);
  32. /* assume that OpenSSL verifies all payload and buf len is of sufficient
  33. length */
  34. switch(content_type) {
  35. case SSL3_RT_CHANGE_CIPHER_SPEC:
  36. msg_type = SSL3_MT_CHANGE_CIPHER_SPEC;
  37. break;
  38. case SSL3_RT_ALERT:
  39. /* byte 0: level */
  40. /* byte 1: alert type */
  41. msg_type = (int)cbuf[1];
  42. break;
  43. case SSL3_RT_HANDSHAKE:
  44. msg_type = (int)cbuf[0];
  45. break;
  46. #ifdef SSL3_RT_HEADER
  47. case SSL3_RT_HEADER:
  48. /* frame header encodes version in bytes 1..2 */
  49. version = cbuf[1] << 8 | cbuf[2];
  50. msg_type = (int)cbuf[0];
  51. break;
  52. #endif
  53. #ifdef SSL3_RT_INNER_CONTENT_TYPE
  54. case SSL3_RT_INNER_CONTENT_TYPE:
  55. msg_type = (int)cbuf[0];
  56. break;
  57. #endif
  58. default:
  59. /* never SSL3_RT_APPLICATION_DATA */
  60. msg_type = -1;
  61. break;
  62. }
  63. res = PyObject_CallFunction(
  64. ssl_obj->ctx->msg_cb, "Osiiiy#",
  65. ssl_socket, write_p ? "write" : "read",
  66. version, content_type, msg_type,
  67. buf, len
  68. );
  69. if (res == NULL) {
  70. PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb);
  71. } else {
  72. Py_DECREF(res);
  73. }
  74. Py_XDECREF(ssl_socket);
  75. PyGILState_Release(threadstate);
  76. }
  77. static PyObject *
  78. _PySSLContext_get_msg_callback(PySSLContext *self, void *c) {
  79. if (self->msg_cb != NULL) {
  80. Py_INCREF(self->msg_cb);
  81. return self->msg_cb;
  82. } else {
  83. Py_RETURN_NONE;
  84. }
  85. }
  86. static int
  87. _PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) {
  88. Py_CLEAR(self->msg_cb);
  89. if (arg == Py_None) {
  90. SSL_CTX_set_msg_callback(self->ctx, NULL);
  91. }
  92. else {
  93. if (!PyCallable_Check(arg)) {
  94. SSL_CTX_set_msg_callback(self->ctx, NULL);
  95. PyErr_SetString(PyExc_TypeError,
  96. "not a callable object");
  97. return -1;
  98. }
  99. Py_INCREF(arg);
  100. self->msg_cb = arg;
  101. SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback);
  102. }
  103. return 0;
  104. }
  105. static void
  106. _PySSL_keylog_callback(const SSL *ssl, const char *line)
  107. {
  108. PyGILState_STATE threadstate;
  109. PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */
  110. int res, e;
  111. static PyThread_type_lock *lock = NULL;
  112. threadstate = PyGILState_Ensure();
  113. ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl);
  114. assert(PySSLSocket_Check(ssl_obj));
  115. if (ssl_obj->ctx->keylog_bio == NULL) {
  116. return;
  117. }
  118. /* Allocate a static lock to synchronize writes to keylog file.
  119. * The lock is neither released on exit nor on fork(). The lock is
  120. * also shared between all SSLContexts although contexts may write to
  121. * their own files. IMHO that's good enough for a non-performance
  122. * critical debug helper.
  123. */
  124. if (lock == NULL) {
  125. lock = PyThread_allocate_lock();
  126. if (lock == NULL) {
  127. PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock");
  128. PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value,
  129. &ssl_obj->exc_tb);
  130. return;
  131. }
  132. }
  133. PySSL_BEGIN_ALLOW_THREADS
  134. PyThread_acquire_lock(lock, 1);
  135. res = BIO_printf(ssl_obj->ctx->keylog_bio, "%s\n", line);
  136. e = errno;
  137. (void)BIO_flush(ssl_obj->ctx->keylog_bio);
  138. PyThread_release_lock(lock);
  139. PySSL_END_ALLOW_THREADS
  140. if (res == -1) {
  141. errno = e;
  142. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError,
  143. ssl_obj->ctx->keylog_filename);
  144. PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb);
  145. }
  146. PyGILState_Release(threadstate);
  147. }
  148. static PyObject *
  149. _PySSLContext_get_keylog_filename(PySSLContext *self, void *c) {
  150. if (self->keylog_filename != NULL) {
  151. Py_INCREF(self->keylog_filename);
  152. return self->keylog_filename;
  153. } else {
  154. Py_RETURN_NONE;
  155. }
  156. }
  157. static int
  158. _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) {
  159. FILE *fp;
  160. /* Reset variables and callback first */
  161. SSL_CTX_set_keylog_callback(self->ctx, NULL);
  162. Py_CLEAR(self->keylog_filename);
  163. if (self->keylog_bio != NULL) {
  164. BIO *bio = self->keylog_bio;
  165. self->keylog_bio = NULL;
  166. PySSL_BEGIN_ALLOW_THREADS
  167. BIO_free_all(bio);
  168. PySSL_END_ALLOW_THREADS
  169. }
  170. if (arg == Py_None) {
  171. /* None disables the callback */
  172. return 0;
  173. }
  174. /* _Py_fopen_obj() also checks that arg is of proper type. */
  175. fp = _Py_fopen_obj(arg, "a" PY_STDIOTEXTMODE);
  176. if (fp == NULL)
  177. return -1;
  178. self->keylog_bio = BIO_new_fp(fp, BIO_CLOSE | BIO_FP_TEXT);
  179. if (self->keylog_bio == NULL) {
  180. PyErr_SetString(PySSLErrorObject,
  181. "Can't malloc memory for keylog file");
  182. return -1;
  183. }
  184. Py_INCREF(arg);
  185. self->keylog_filename = arg;
  186. /* Write a header for seekable, empty files (this excludes pipes). */
  187. PySSL_BEGIN_ALLOW_THREADS
  188. if (BIO_tell(self->keylog_bio) == 0) {
  189. BIO_puts(self->keylog_bio,
  190. "# TLS secrets log file, generated by OpenSSL / Python\n");
  191. (void)BIO_flush(self->keylog_bio);
  192. }
  193. PySSL_END_ALLOW_THREADS
  194. SSL_CTX_set_keylog_callback(self->ctx, _PySSL_keylog_callback);
  195. return 0;
  196. }