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
parent
44dc06ede4
commit
2b131d212f
|
@ -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);
|
||||
|
|
|
@ -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!",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue