obs-outputs: Fix librtmp mbedtls thread safety

Per mbedtls documentation, "If you share a context between threads, you
need to call these functions only from the main thread, at the beginning
and end of the context's lifetime.". OBS violated this since librtmp
uses a global context and it was allocated and freed in different
threads such as the auto config test.

This commit attaches the mbedtls context to an RTMP structure so there
is no more global state. It also fixes a rare double-free crash that
could occur if RTMP_TLS_Free was called twice (this happened in rare
situations such as the auto config running followed by a mode change
from Advanced to Simple).
master
Richard Stanway 2020-01-23 00:11:23 +01:00
parent 44dc06ede4
commit 2b131d212f
7 changed files with 222 additions and 209 deletions

View File

@ -51,13 +51,13 @@ typedef struct MDH
#define MDH_new() calloc(1,sizeof(MDH))
#define MDH_free(vp) {MDH *_dh = vp; mbedtls_dhm_free(&_dh->ctx); MP_free(_dh->p); MP_free(_dh->g); MP_free(_dh->pub_key); MP_free(_dh->priv_key); free(_dh);}
static int MDH_generate_key(MDH *dh)
static int MDH_generate_key(RTMP *r, MDH *dh)
{
unsigned char out[2];
MP_set(&dh->ctx.P, dh->p);
MP_set(&dh->ctx.G, dh->g);
dh->ctx.len = 128;
mbedtls_dhm_make_public(&dh->ctx, 1024, out, 1, mbedtls_ctr_drbg_random, &RTMP_TLS_ctx->ctr_drbg);
mbedtls_dhm_make_public(&dh->ctx, 1024, out, 1, mbedtls_ctr_drbg_random, &r->RTMP_TLS_ctx->ctr_drbg);
MP_new(dh->pub_key);
MP_new(dh->priv_key);
MP_set(dh->pub_key, &dh->ctx.GX);
@ -251,7 +251,7 @@ failed:
}
static MDH *
DHInit(int nKeyBits)
DHInit(RTMP *r, int nKeyBits)
{
size_t res;
MDH *dh = MDH_new();
@ -283,8 +283,9 @@ failed:
}
static int
DHGenerateKey(MDH *dh)
DHGenerateKey(RTMP *r)
{
MDH *dh = r->Link.dh;
size_t res = 0;
if (!dh)
return 0;
@ -293,7 +294,7 @@ DHGenerateKey(MDH *dh)
{
MP_t q1 = NULL;
if (!MDH_generate_key(dh))
if (!MDH_generate_key(r, dh))
return 0;
MP_gethex(q1, Q1024, res);

View File

@ -879,7 +879,7 @@ HandShake(RTMP * r, int FP9HandShake)
if (encrypted)
{
/* generate Diffie-Hellmann parameters */
r->Link.dh = DHInit(1024);
r->Link.dh = DHInit(r, 1024);
if (!r->Link.dh)
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
@ -890,7 +890,7 @@ HandShake(RTMP * r, int FP9HandShake)
dhposClient = getdh(clientsig, RTMP_SIG_SIZE);
RTMP_Log(RTMP_LOGDEBUG, "%s: DH pubkey position: %d", __FUNCTION__, dhposClient);
if (!DHGenerateKey(r->Link.dh))
if (!DHGenerateKey(r))
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't generate Diffie-Hellmann public key!",
__FUNCTION__);
@ -1271,7 +1271,7 @@ SHandShake(RTMP * r)
if (encrypted)
{
/* generate Diffie-Hellmann parameters */
r->Link.dh = DHInit(1024);
r->Link.dh = DHInit(r, 1024);
if (!r->Link.dh)
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",

View File

@ -20,6 +20,7 @@
* http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef USE_HASHSWF
#include "rtmp_sys.h"
#include "log.h"
#include "http.h"
@ -77,9 +78,6 @@ typedef mbedtls_md_context_t *HMAC_CTX;
#define HMAC_close(ctx) HMAC_CTX_cleanup(&ctx)
#endif
extern void RTMP_TLS_Init();
extern TLS_CTX RTMP_TLS_ctx;
#include <zlib.h>
#endif /* CRYPTO */
@ -692,3 +690,4 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
return -1;
}
#endif
#endif

View File

@ -87,7 +87,6 @@ static const char *my_dhm_G = "4";
#include <openssl/buffer.h>
#endif
TLS_CTX RTMP_TLS_ctx = NULL;
#endif
#define RTMP_SIG_SIZE 1536
@ -285,9 +284,9 @@ RTMP_LibVersion()
}
void
RTMP_TLS_LoadCerts() {
RTMP_TLS_LoadCerts(RTMP *r) {
#ifdef USE_MBEDTLS
mbedtls_x509_crt *chain = RTMP_TLS_ctx->cacert = calloc(1, sizeof(struct mbedtls_x509_crt));
mbedtls_x509_crt *chain = r->RTMP_TLS_ctx->cacert = calloc(1, sizeof(struct mbedtls_x509_crt));
mbedtls_x509_crt_init(chain);
#if defined(_WIN32)
@ -349,35 +348,35 @@ RTMP_TLS_LoadCerts() {
}
#endif
mbedtls_ssl_conf_ca_chain(&RTMP_TLS_ctx->conf, chain, NULL);
mbedtls_ssl_conf_ca_chain(&r->RTMP_TLS_ctx->conf, chain, NULL);
return;
error:
mbedtls_x509_crt_free(chain);
free(chain);
RTMP_TLS_ctx->cacert = NULL;
r->RTMP_TLS_ctx->cacert = NULL;
#endif /* USE_MBEDTLS */
}
void
RTMP_TLS_Init()
RTMP_TLS_Init(RTMP *r)
{
#ifdef CRYPTO
#if defined(USE_MBEDTLS)
const char * pers = "RTMP_TLS";
RTMP_TLS_ctx = calloc(1,sizeof(struct tls_ctx));
r->RTMP_TLS_ctx = calloc(1,sizeof(struct tls_ctx));
mbedtls_ssl_config_init(&RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_init(&RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_init(&RTMP_TLS_ctx->entropy);
mbedtls_ssl_config_init(&r->RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_init(&r->RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_init(&r->RTMP_TLS_ctx->entropy);
mbedtls_ctr_drbg_seed(&RTMP_TLS_ctx->ctr_drbg,
mbedtls_ctr_drbg_seed(&r->RTMP_TLS_ctx->ctr_drbg,
mbedtls_entropy_func,
&RTMP_TLS_ctx->entropy,
&r->RTMP_TLS_ctx->entropy,
(const unsigned char *)pers,
strlen(pers));
RTMP_TLS_LoadCerts();
RTMP_TLS_LoadCerts(r);
#elif defined(USE_POLARSSL)
/* Do this regardless of NO_SSL, we use havege for rtmpe too */
RTMP_TLS_ctx = calloc(1,sizeof(struct tls_ctx));
@ -407,35 +406,38 @@ RTMP_TLS_Init()
}
void
RTMP_TLS_Free() {
RTMP_TLS_Free(RTMP *r) {
#ifdef USE_MBEDTLS
mbedtls_ssl_config_free(&RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_free(&RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_free(&RTMP_TLS_ctx->entropy);
if (RTMP_TLS_ctx->cacert) {
mbedtls_x509_crt_free(RTMP_TLS_ctx->cacert);
free(RTMP_TLS_ctx->cacert);
RTMP_TLS_ctx->cacert = NULL;
if (!r->RTMP_TLS_ctx)
return;
mbedtls_ssl_config_free(&r->RTMP_TLS_ctx->conf);
mbedtls_ctr_drbg_free(&r->RTMP_TLS_ctx->ctr_drbg);
mbedtls_entropy_free(&r->RTMP_TLS_ctx->entropy);
if (r->RTMP_TLS_ctx->cacert) {
mbedtls_x509_crt_free(r->RTMP_TLS_ctx->cacert);
free(r->RTMP_TLS_ctx->cacert);
r->RTMP_TLS_ctx->cacert = NULL;
}
// NO mbedtls_net_free() BECAUSE WE SET IT UP BY HAND!
free(RTMP_TLS_ctx);
RTMP_TLS_ctx = NULL;
free(r->RTMP_TLS_ctx);
r->RTMP_TLS_ctx = NULL;
#endif
}
void *
RTMP_TLS_AllocServerContext(const char* cert, const char* key)
RTMP_TLS_AllocServerContext(RTMP *r, const char* cert, const char* key)
{
void *ctx = NULL;
#ifdef CRYPTO
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
if (!r->RTMP_TLS_ctx)
RTMP_TLS_Init(r);
#if defined(USE_MBEDTLS)
tls_server_ctx *tc = ctx = calloc(1, sizeof(struct tls_server_ctx));
tc->conf = &RTMP_TLS_ctx->conf;
tc->ctr_drbg = &RTMP_TLS_ctx->ctr_drbg;
tc->conf = &r->RTMP_TLS_ctx->conf;
tc->ctr_drbg = &r->RTMP_TLS_ctx->ctr_drbg;
mbedtls_x509_crt_init(&tc->cert);
if (mbedtls_x509_crt_parse_file(&tc->cert, cert))
@ -528,8 +530,7 @@ void
RTMP_Free(RTMP *r)
{
#if defined(CRYPTO) && defined(USE_MBEDTLS)
if (RTMP_TLS_ctx)
RTMP_TLS_Free();
RTMP_TLS_Free(r);
#endif
free(r);
}
@ -537,11 +538,6 @@ RTMP_Free(RTMP *r)
void
RTMP_Init(RTMP *r)
{
#ifdef CRYPTO
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
#endif
memset(r, 0, sizeof(RTMP));
r->m_sb.sb_socket = -1;
r->m_inChunkSize = RTMP_DEFAULT_CHUNKSIZE;
@ -557,6 +553,11 @@ RTMP_Init(RTMP *r)
r->Link.nStreams = 0;
r->Link.timeout = 30;
r->Link.swfAge = 30;
#ifdef CRYPTO
RTMP_TLS_Init(r);
#endif
}
void
@ -780,8 +781,12 @@ int RTMP_SetupURL(RTMP *r, char *url)
#ifdef CRYPTO
if ((r->Link.lFlags & RTMP_LF_SWFV) && r->Link.swfUrl.av_len)
#ifdef USE_HASHSWF
RTMP_HashSWF(r->Link.swfUrl.av_val, &r->Link.SWFSize,
(unsigned char *)r->Link.SWFHash, r->Link.swfAge);
#else
return FALSE;
#endif
#endif
SocksSetup(r, &r->Link.sockshost);
@ -1016,7 +1021,7 @@ RTMP_TLS_Accept(RTMP *r, void *ctx)
TLS_server(srv_ctx, r->m_sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *client_fd = &RTMP_TLS_ctx->net;
mbedtls_net_context *client_fd = &r->RTMP_TLS_ctx->net;
mbedtls_net_init(client_fd);
client_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, client_fd);
@ -1044,10 +1049,10 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
if (r->Link.protocol & RTMP_FEATURE_SSL)
{
#if defined(CRYPTO) && !defined(NO_SSL)
TLS_client(RTMP_TLS_ctx, r->m_sb.sb_ssl);
TLS_client(r->RTMP_TLS_ctx, r->m_sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *server_fd = &RTMP_TLS_ctx->net;
mbedtls_net_context *server_fd = &r->RTMP_TLS_ctx->net;
server_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, server_fd);

View File

@ -49,6 +49,163 @@
#include "amf.h"
#ifdef CRYPTO
#if defined(USE_MBEDTLS)
#include <mbedtls/version.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#define my_dhm_P \
"E4004C1F94182000103D883A448B3F80" \
"2CE4B44A83301270002C20D0321CFD00" \
"11CCEF784C26A400F43DFB901BCA7538" \
"F2C6B176001CF5A0FD16D2C48B1D0C1C" \
"F6AC8E1DA6BCC3B4E1F96B0564965300" \
"FFA1D0B601EB2800F489AA512C4B248C" \
"01F76949A60BB7F00A40B1EAB64BDD48" \
"E8A700D60B7F1200FA8E77B0A979DABF"
#define my_dhm_G "4"
#define SSL_SET_SESSION(S,resume,timeout,ctx) mbedtls_ssl_set_session(S,ctx)
typedef struct tls_ctx
{
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_config conf;
mbedtls_ssl_session ssn;
mbedtls_x509_crt *cacert;
mbedtls_net_context net;
} tls_ctx;
typedef struct tls_server_ctx
{
mbedtls_ssl_config *conf;
mbedtls_ctr_drbg_context *ctr_drbg;
mbedtls_pk_context key;
mbedtls_x509_crt cert;
} tls_server_ctx;
typedef tls_ctx *TLS_CTX;
#define TLS_client(ctx,s) \
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, &ctx->conf);\
mbedtls_ssl_config_defaults(&ctx->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);\
mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(&ctx->conf, mbedtls_ctr_drbg_random, &ctx->ctr_drbg)
#define TLS_server(ctx,s)\
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, ctx->conf);\
mbedtls_ssl_conf_endpoint(ctx->conf, MBEDTLS_SSL_IS_SERVER);\
mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(ctx->conf, mbedtls_ctr_drbg_random, ctx->ctr_drbg);\
mbedtls_ssl_conf_own_cert(ctx->conf, &ctx->cert, &ctx->key);\
mbedtls_ssl_conf_dh_param_bin(ctx->conf,\
(const unsigned char *)my_dhm_P, strlen(my_dhm_P),\
(const unsigned char *)my_dhm_G, strlen(my_dhm_G))
#define TLS_setfd(s,fd) mbedtls_ssl_set_bio(s, fd, mbedtls_net_send, mbedtls_net_recv, NULL)
#define TLS_connect(s) mbedtls_ssl_handshake(s)
#define TLS_accept(s) mbedtls_ssl_handshake(s)
#define TLS_read(s,b,l) mbedtls_ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) mbedtls_ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) mbedtls_ssl_close_notify(s)
#define TLS_close(s) mbedtls_ssl_free(s); free(s)
#elif defined(USE_POLARSSL)
#include <polarssl/version.h>
#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include <polarssl/havege.h>
#if POLARSSL_VERSION_NUMBER < 0x01010000
#define havege_random havege_rand
#endif
#if POLARSSL_VERSION_NUMBER >= 0x01020000
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,ctx)
#else
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,resume,timeout,ctx)
#endif
typedef struct tls_ctx
{
havege_state hs;
ssl_session ssn;
} tls_ctx;
typedef struct tls_server_ctx
{
havege_state *hs;
x509_cert cert;
rsa_context key;
ssl_session ssn;
const char *dhm_P, *dhm_G;
} tls_server_ctx;
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\
ssl_set_rng(s, havege_random, &ctx->hs);\
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
SSL_SET_SESSION(s, 1, 600, &ctx->ssn)
#define TLS_server(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
ssl_set_endpoint(s, SSL_IS_SERVER); ssl_set_authmode(s, SSL_VERIFY_NONE);\
ssl_set_rng(s, havege_random, ((tls_server_ctx*)ctx)->hs);\
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
SSL_SET_SESSION(s, 1, 600, &((tls_server_ctx*)ctx)->ssn);\
ssl_set_own_cert(s, &((tls_server_ctx*)ctx)->cert, &((tls_server_ctx*)ctx)->key);\
ssl_set_dh_param(s, ((tls_server_ctx*)ctx)->dhm_P, ((tls_server_ctx*)ctx)->dhm_G)
#define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
#define TLS_connect(s) ssl_handshake(s)
#define TLS_accept(s) ssl_handshake(s)
#define TLS_read(s,b,l) ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) ssl_close_notify(s)
#define TLS_close(s) ssl_free(s); free(s)
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
typedef struct tls_ctx
{
gnutls_certificate_credentials_t cred;
gnutls_priority_t prios;
} tls_ctx;
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_CLIENT); gnutls_priority_set(s, ctx->prios); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx->cred)
#define TLS_server(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_SERVER); gnutls_priority_set_direct(s, "NORMAL", NULL); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx)
#define TLS_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd)
#define TLS_connect(s) gnutls_handshake(s)
#define TLS_accept(s) gnutls_handshake(s)
#define TLS_read(s,b,l) gnutls_record_recv(s,b,l)
#define TLS_write(s,b,l) gnutls_record_send(s,b,l)
#define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR)
#define TLS_close(s) gnutls_deinit(s)
#elif defined(USE_ONLY_MD5)
#include "md5.h"
#include "cencode.h"
#define MD5_DIGEST_LENGTH 16
#else /* USE_OPENSSL */
#define TLS_CTX SSL_CTX *
#define TLS_client(ctx,s) s = SSL_new(ctx)
#define TLS_server(ctx,s) s = SSL_new(ctx)
#define TLS_setfd(s,fd) SSL_set_fd(s,fd)
#define TLS_connect(s) SSL_connect(s)
#define TLS_accept(s) SSL_accept(s)
#define TLS_read(s,b,l) SSL_read(s,b,l)
#define TLS_write(s,b,l) SSL_write(s,b,l)
#define TLS_shutdown(s) SSL_shutdown(s)
#define TLS_close(s) SSL_free(s)
#endif
#endif
#ifdef __cplusplus
extern "C"
{
@ -326,6 +483,10 @@ extern "C"
RTMP_LNK Link;
int connect_time_ms;
int last_error_code;
#ifdef CRYPTO
TLS_CTX RTMP_TLS_ctx;
#endif
} RTMP;
int RTMP_ParseURL(const char *url, int *protocol, AVal *host,
@ -381,11 +542,11 @@ extern "C"
void RTMP_Init(RTMP *r);
void RTMP_Close(RTMP *r);
RTMP *RTMP_Alloc(void);
void RTMP_TLS_Free();
void RTMP_TLS_Free(RTMP *r);
void RTMP_Free(RTMP *r);
void RTMP_EnableWrite(RTMP *r);
void *RTMP_TLS_AllocServerContext(const char* cert, const char* key);
void *RTMP_TLS_AllocServerContext(RTMP *r, const char* cert, const char* key);
void RTMP_TLS_FreeServerContext(void *ctx);
int RTMP_LibVersion(void);
@ -415,10 +576,11 @@ extern "C"
int RTMP_Read(RTMP *r, char *buf, int size);
int RTMP_Write(RTMP *r, const char *buf, int size, int streamIdx);
#ifdef USE_HASHSWF
/* hashswf.c */
int RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
int age);
#endif
#ifdef __cplusplus
};
#endif

View File

@ -79,159 +79,4 @@
#endif
#include "rtmp.h"
#if defined(USE_MBEDTLS)
#include <mbedtls/version.h>
#include <mbedtls/net_sockets.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#define my_dhm_P \
"E4004C1F94182000103D883A448B3F80" \
"2CE4B44A83301270002C20D0321CFD00" \
"11CCEF784C26A400F43DFB901BCA7538" \
"F2C6B176001CF5A0FD16D2C48B1D0C1C" \
"F6AC8E1DA6BCC3B4E1F96B0564965300" \
"FFA1D0B601EB2800F489AA512C4B248C" \
"01F76949A60BB7F00A40B1EAB64BDD48" \
"E8A700D60B7F1200FA8E77B0A979DABF"
#define my_dhm_G "4"
#define SSL_SET_SESSION(S,resume,timeout,ctx) mbedtls_ssl_set_session(S,ctx)
typedef struct tls_ctx
{
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_config conf;
mbedtls_ssl_session ssn;
mbedtls_x509_crt *cacert;
mbedtls_net_context net;
} tls_ctx;
typedef struct tls_server_ctx
{
mbedtls_ssl_config *conf;
mbedtls_ctr_drbg_context *ctr_drbg;
mbedtls_pk_context key;
mbedtls_x509_crt cert;
} tls_server_ctx;
typedef tls_ctx *TLS_CTX;
#define TLS_client(ctx,s) \
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, &ctx->conf);\
mbedtls_ssl_config_defaults(&ctx->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);\
mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(&ctx->conf, mbedtls_ctr_drbg_random, &ctx->ctr_drbg)
#define TLS_server(ctx,s)\
s = malloc(sizeof(mbedtls_ssl_context));\
mbedtls_ssl_init(s);\
mbedtls_ssl_setup(s, ctx->conf);\
mbedtls_ssl_conf_endpoint(ctx->conf, MBEDTLS_SSL_IS_SERVER);\
mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\
mbedtls_ssl_conf_rng(ctx->conf, mbedtls_ctr_drbg_random, ctx->ctr_drbg);\
mbedtls_ssl_conf_own_cert(ctx->conf, &ctx->cert, &ctx->key);\
mbedtls_ssl_conf_dh_param_bin(ctx->conf,\
(const unsigned char *)my_dhm_P, strlen(my_dhm_P),\
(const unsigned char *)my_dhm_G, strlen(my_dhm_G))
#define TLS_setfd(s,fd) mbedtls_ssl_set_bio(s, fd, mbedtls_net_send, mbedtls_net_recv, NULL)
#define TLS_connect(s) mbedtls_ssl_handshake(s)
#define TLS_accept(s) mbedtls_ssl_handshake(s)
#define TLS_read(s,b,l) mbedtls_ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) mbedtls_ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) mbedtls_ssl_close_notify(s)
#define TLS_close(s) mbedtls_ssl_free(s); free(s)
#elif defined(USE_POLARSSL)
#include <polarssl/version.h>
#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include <polarssl/havege.h>
#if POLARSSL_VERSION_NUMBER < 0x01010000
#define havege_random havege_rand
#endif
#if POLARSSL_VERSION_NUMBER >= 0x01020000
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,ctx)
#else
#define SSL_SET_SESSION(S,resume,timeout,ctx) ssl_set_session(S,resume,timeout,ctx)
#endif
typedef struct tls_ctx
{
havege_state hs;
ssl_session ssn;
} tls_ctx;
typedef struct tls_server_ctx
{
havege_state *hs;
x509_cert cert;
rsa_context key;
ssl_session ssn;
const char *dhm_P, *dhm_G;
} tls_server_ctx;
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
ssl_set_endpoint(s, SSL_IS_CLIENT); ssl_set_authmode(s, SSL_VERIFY_NONE);\
ssl_set_rng(s, havege_random, &ctx->hs);\
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
SSL_SET_SESSION(s, 1, 600, &ctx->ssn)
#define TLS_server(ctx,s) s = malloc(sizeof(ssl_context)); ssl_init(s);\
ssl_set_endpoint(s, SSL_IS_SERVER); ssl_set_authmode(s, SSL_VERIFY_NONE);\
ssl_set_rng(s, havege_random, ((tls_server_ctx*)ctx)->hs);\
ssl_set_ciphersuites(s, ssl_default_ciphersuites);\
SSL_SET_SESSION(s, 1, 600, &((tls_server_ctx*)ctx)->ssn);\
ssl_set_own_cert(s, &((tls_server_ctx*)ctx)->cert, &((tls_server_ctx*)ctx)->key);\
ssl_set_dh_param(s, ((tls_server_ctx*)ctx)->dhm_P, ((tls_server_ctx*)ctx)->dhm_G)
#define TLS_setfd(s,fd) ssl_set_bio(s, net_recv, &fd, net_send, &fd)
#define TLS_connect(s) ssl_handshake(s)
#define TLS_accept(s) ssl_handshake(s)
#define TLS_read(s,b,l) ssl_read(s,(unsigned char *)b,l)
#define TLS_write(s,b,l) ssl_write(s,(unsigned char *)b,l)
#define TLS_shutdown(s) ssl_close_notify(s)
#define TLS_close(s) ssl_free(s); free(s)
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
typedef struct tls_ctx
{
gnutls_certificate_credentials_t cred;
gnutls_priority_t prios;
} tls_ctx;
#define TLS_CTX tls_ctx *
#define TLS_client(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_CLIENT); gnutls_priority_set(s, ctx->prios); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx->cred)
#define TLS_server(ctx,s) gnutls_init((gnutls_session_t *)(&s), GNUTLS_SERVER); gnutls_priority_set_direct(s, "NORMAL", NULL); gnutls_credentials_set(s, GNUTLS_CRD_CERTIFICATE, ctx)
#define TLS_setfd(s,fd) gnutls_transport_set_ptr(s, (gnutls_transport_ptr_t)(long)fd)
#define TLS_connect(s) gnutls_handshake(s)
#define TLS_accept(s) gnutls_handshake(s)
#define TLS_read(s,b,l) gnutls_record_recv(s,b,l)
#define TLS_write(s,b,l) gnutls_record_send(s,b,l)
#define TLS_shutdown(s) gnutls_bye(s, GNUTLS_SHUT_RDWR)
#define TLS_close(s) gnutls_deinit(s)
#elif defined(USE_ONLY_MD5)
#include "md5.h"
#include "cencode.h"
#define MD5_DIGEST_LENGTH 16
#else /* USE_OPENSSL */
#define TLS_CTX SSL_CTX *
#define TLS_client(ctx,s) s = SSL_new(ctx)
#define TLS_server(ctx,s) s = SSL_new(ctx)
#define TLS_setfd(s,fd) SSL_set_fd(s,fd)
#define TLS_connect(s) SSL_connect(s)
#define TLS_accept(s) SSL_accept(s)
#define TLS_read(s,b,l) SSL_read(s,b,l)
#define TLS_write(s,b,l) SSL_write(s,b,l)
#define TLS_shutdown(s) SSL_shutdown(s)
#define TLS_close(s) SSL_free(s)
#endif
#endif

View File

@ -110,7 +110,7 @@ static void rtmp_stream_destroy(void *data)
}
}
RTMP_TLS_Free();
RTMP_TLS_Free(&stream->rtmp);
free_packets(stream);
dstr_free(&stream->path);
dstr_free(&stream->key);
@ -934,7 +934,8 @@ static int try_connect(struct rtmp_stream *stream)
info("Connecting to RTMP URL %s...", stream->path.array);
RTMP_Init(&stream->rtmp);
// this should have been called already by rtmp_stream_create
//RTMP_Init(&stream->rtmp);
if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
return OBS_OUTPUT_BAD_PATH;