New upstream version 25.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2020-03-25 09:07:22 +01:00
parent 04fe0efc67
commit 8b2e5f2130
569 changed files with 62491 additions and 5875 deletions

View file

@ -26,6 +26,7 @@ endif()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ftl-sdk/CMakeLists.txt")
find_package(Libcurl REQUIRED)
message(STATUS "Found ftl-sdk: ftl outputs enabled")
add_definitions(-DFTL_STATIC_COMPILE)

View file

@ -1,5 +1,5 @@
RTMPStream="RTMPStream"
RTMPStream.DropThreshold="DropThreshold (Millisekunden)"
RTMPStream.DropThreshold="DropSchwellwert (Millisekunden)"
FLVOutput="FLVDateiausgabe"
FLVOutput.FilePath="Dateipfad"
Default="Standard"
@ -7,9 +7,9 @@ Default="Standard"
ConnectionTimedOut="Zeitüberschreitung bei der Verbindung. Stellen Sie sicher, dass Sie einen gültigen Streamingdienst konfiguriert haben und keine Firewall die Verbindung blockiert."
PermissionDenied="Die Verbindung wurde blockiert. Überprüfen Sie Ihre Firewall/AntiVirusEinstellungen, um sicherzustellen, dass OBS vollen Internetzugang hat."
ConnectionAborted="Die Verbindung wurde abgebrochen. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst."
ConnectionReset="Die Verbindung wurde durch Kommunikationspartner zurückgesetzt. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst."
ConnectionReset="Die Verbindung wurde durch den Kommunikationspartner zurückgesetzt. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst."
HostNotFound="Hostname nicht gefunden. Stellen Sie sicher, dass Sie einen gültigen Streamingserver eingegeben haben und Ihre Internetverbindung/DNS korrekt arbeiten."
NoData="Hostname gefunden, aber keine Daten des angeforderten Typs vorhanden. Dies kann auftreten, wenn Sie eine IPv6Adresse verwenden, aber Ihr Streamingdienst nur über IPv4Adressen verfügt (siehe Einstellungen → Erweitert)."
AddressNotAvailable="Adresse nicht verfügbar. Sie haben möglicherweise eine ungültige IPAdresse versucht zu verwenden (siehe Einstellungen → Erweitert)."
NoData="Hostname gefunden, aber keine Daten des angeforderten Typs vorhanden. Dies kann auftreten, wenn Sie eine IPv6Adresse verwenden, aber Ihr Streamingdienst nur über IPv4Adressen verfügt. (siehe „Einstellungen“„Erweitert“)"
AddressNotAvailable="Adresse nicht verfügbar. Sie haben möglicherweise eine ungültige IPAdresse versucht zu verwenden. (siehe „Einstellungen“„Erweitert“)"
SSLCertVerifyFailed="Der RTMPServer hat ein ungültiges SSLZertifikat gesendet."

View file

@ -1,4 +1,15 @@
RTMPStream="پخش زنده RTMP"
RTMPStream.DropThreshold="کاهش آستانه (میلی ثانیه)"
FLVOutput="خروجی پرونده FLV"
FLVOutput.FilePath="مسر پرونده"
Default="پیش فرض"
ConnectionTimedOut="اتصال به پایان رسید. اطمینان حاصل کنید که یک سرویس پخش معتبر پیکربندی کرده اید و هیچ فایروالی اتصال را مسدود نمی کند."
PermissionDenied="اتصال مسدود شد. تنظیمات فایروال / آنتی ویروس خود را بررسی کنید تا مطمئن شوید OBS دسترسی کامل به اینترنت دارد."
ConnectionAborted="ارتباط قطع شد. این معمولاً نشان دهنده مشکلات اتصال به اینترنت بین شما و سرویس جریان است."
ConnectionReset="ارتباط همسان تنظیم مجدد شد. این معمولاً نشان دهنده مشکلات اتصال به اینترنت بین شما و سرویس جریان است."
HostNotFound="نام میزبان یافت نشد. اطمینان حاصل کنید که یک سرور جریان معتبر وارد کرده اید و اتصال اینترنتی / DNS شما به درستی کار می کند."
NoData="نام میزبان پیدا شد، اما داده ای از نوع درخواستی وجود ندارد. این امر می تواند در صورتی رخ دهد که به یک آدرس IPv6 متصل شده باشید و سرویس پخش شما فقط دارای آدرس های IPv4 است (به تنظیمات → پیشرفته مراجعه کنید)."
AddressNotAvailable="آدرس در دسترس نیست شاید سعی کرده اید به یک آدرس IP نامعتبر وصل شوید (به تنظیمات → پیشرفته مراجعه کنید)."
SSLCertVerifyFailed="سرور RTMP یک گواهی SSL نامعتبر ارسال کرد."

View file

@ -4,12 +4,12 @@ FLVOutput="გამოტანილი FLV-ფაილი"
FLVOutput.FilePath="ფაილის მისამართი"
Default="ნაგულისხმევი"
ConnectionTimedOut="კავშირის ვადა ამოიწურა. გადაამოწმეთ, სწორად გაქვთ თუ არა გამართული ნაკადის გაშვები მომსახურება და ქსელის ფარი ხომ არ ზღუდავს კავშირს."
ConnectionTimedOut="კავშირის ვადა ამოიწურა. გადაამოწმეთ, სწორად გაქვთ თუ არა გამართული ნაკადის გაშვები მომსახურება და ქსელის ფარი ხომ არ ზღუდავს კავშირს."
PermissionDenied="კავშირი შეიზღუდა. გადაამოწმეთ ქსელის ფარის ან ანტივირუსული პროგრამის პარამეტრები და დარწმუნდით, რომ OBS-ს აქვს სრული დაშვება ინტერნეტთან."
ConnectionAborted="კავშირი გაუქმდა. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვები მომსახურების მომწოდებელს შორის."
ConnectionReset="კავშირი გაწყდა ერთ-ერთი მხარის მიერ. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვები მომსახურების მომწოდებელს შორის."
ConnectionAborted="კავშირი გაუქმდა. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვები მომსახურების მომწოდებელს შორის."
ConnectionReset="კავშირი გაწყდა ერთ-ერთი მხარის მიერ. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვები მომსახურების მომწოდებელს შორის."
HostNotFound="დაკავშირების წერტილი ვერ მოიძებნა. დარწმუნდით, რომ სწორად უთითებთ ნაკადის გაშვების მომსახურების მონაცემებს და თქვენი DNS / ინტერნეტკავშირის პარამეტრებიც სწორადაა გამართული."
NoData="დაკავშირების წერტილი მოიძებნა, მაგრამ მოთხოვნილი სახის მონაცემები არა. ეს შეიძლება გამოწვეული იყოს იმით, რომ თქვენ უკავშირდებით IPv6 მისამართზე, ხოლო თქვენს ნაკადის გაშვების მომსახურებას, მხოლოდ IPv4 მისამართები გააჩნია (იხილეთ პარამეტრები → დამატებითი)."
NoData="დაკავშირების წერტილი მოიძებნა, მაგრამ მოთხოვნილი სახის მონაცემები არა. ეს შეიძლება გამოწვეული იყოს იმით, რომ თქვენ უკავშირდებით IPv6-მისამართზე, ხოლო თქვენს ნაკადის გაშვებ მომსახურებას, მხოლოდ IPv4-მისამართები გააჩნია (იხილეთ პარამეტრები → დამატებითი)."
AddressNotAvailable="მისამართი მიუწვდომელია. შესაძლოა, თქვენ ცდილობთ მცდარ IP-მისამართზე დაკავშირებას (იხილეთ პარამეტრები → დამატებით)."
SSLCertVerifyFailed="RTMP სერვერმა გაგზავნა არამართებული SSL სერტიფიკატი."

View file

@ -4,5 +4,12 @@ FLVOutput="Výstup do súboru FLV"
FLVOutput.FilePath="Cesta k súboru"
Default="Predvolené"
ConnectionTimedOut="Pripojenie vypršalo. Uistite sa že ste nakonfigurovali správnu službu vysielania a že firewall neblokuje toto pripojenie."
PermissionDenied="Pripojenie bolo zablokované. Pozrite si nastavenia vášho firewallu / antivirusu a uistite sa že OBS má plný prístup na internet."
ConnectionAborted="Pripojenie bolo ukončené. Toto obvykle znamená, že nastali problémy s internetovým pripojením medzi vami a službou vysielania."
ConnectionReset="Pripojenie bolo resetované druhou stranou. Toto obvykle znamená, že nastali problémy s pripojením medzi vami a streaming službou."
HostNotFound="Názov hostiteľa sa nenašiel. Uistite sa, že ste zadali platný vysielací server a že vaše internetové pripojenie / DNS fungujú správne."
NoData="Názov hostiteľa sa našiel, ale žiadne dáta požadovaného typu. K tomu môže dôjsť, ak ste viazaní na adresu IPv6 a vaša služba vysielania má iba adresy IPv4 (pozri Nastavenia → Rozšírené)."
AddressNotAvailable="Adresa nie je k dispozícii. Môžno ste sa snažili naviazať na neplatnú IP adresu (pozrite si Nastavenia → Rozšírené)."
SSLCertVerifyFailed="RTMP server poslal neplatný SSL certifikát."

View file

@ -1,12 +1,12 @@
RTMPStream="Pretok RTMP"
RTMPStream="RTMP pretok"
RTMPStream.DropThreshold="Prag padca (ms)"
FLVOutput="Izhod datoteke FLV"
FLVOutput.FilePath="Pot datoteke"
Default="Privzeto"
ConnectionTimedOut="Povezava je potekla. Prepričajte se, da ste nastavili veljavno storitev za pretakanje in da požarni zid ne blokira povezave."
ConnectionTimedOut="Povezava je potekla. Prepričajte se, da ste pravilno nastavili pretočno storitev in da požarni zid ne blokira povezave."
PermissionDenied="Povezava je bila blokirana. Preverite nastavitve požarnega zidu/protivirusnega programa in se prepričajte, da ima OBS poln dostop do interneta."
ConnectionAborted="Povezava je bila prekinjena. To običajno pomeni, da imate težave z internetno povezavo med vami in storitvijo za pretakanje."
ConnectionAborted="Povezava je bila prekinjena. To običajno pomeni, da imate težave z spletno povezavo med vami in pretočno storitvijo."
ConnectionReset="Soležnik je ponastavil povezavo. To običajno pomeni, da imate težave z internetno povezavo med vami in storitvijo za pretakanje."
HostNotFound="Imena gostitelja ni bilo mogoče najti. Prepričajte se, da ste vnesli veljaven strežnik za pretakanje in da vaša internetna povezava/DNS pravilno delujeta."
NoData="Ime gostitelja je bilo najdeno, vendar ni podatkov zahtevane vrste. To se lahko zgodi, če ste se vezali na naslov IPv6, vaša storitev za pretakanje pa ima samo naslove IPv4 (glejte Nastavitve → Napredno)."

View file

@ -5,7 +5,7 @@ FLVOutput.FilePath="Đường dẫn tệp"
Default="Mặc định"
ConnectionTimedOut="Kết nối đã hết thời. Đảm bảo bạn đã định cấu hình dịch vụ phát trực tuyến hợp lệ và không có tường lửa nào đang chặn kết nối."
PermissionDenied="Kết nối đã bị chặn. Hãy kiểm tra tường lửa / cài đặt chống virus để đảm bảo rằng OBS được cho phép truy cập internet đầy đủ."
PermissionDenied="Kết nối đã bị chặn. Hãy kiểm tra tường lửa / thiết đặt chống virus để đảm bảo rằng OBS được cho phép truy cập internet đầy đủ."
ConnectionAborted="Kết nối đã bị hủy bỏ. Điều này thường chỉ ra kết nối internet giữa bạn và dịch vụ trực tuyến có vấn đề."
ConnectionReset="Kết nối đã được đặt lại bởi peer. Điều này thường chỉ ra các sự cố kết nối Internet giữa bạn và dịch vụ truyền trực tuyến."
HostNotFound="Tên máy chủ không tìm thấy. Đảm bảo rằng bạn đã nhập vào một máy chủ stream hợp lệ và kết nối internet của bạn / DNS đang hoạt động tốt."

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);
@ -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

@ -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__);
@ -1178,358 +1178,3 @@ HandShake(RTMP * r, int FP9HandShake)
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
}
static int
SHandShake(RTMP * r)
{
int i, offalg = 0;
int dhposServer = 0;
int digestPosServer = 0;
RC4_handle keyIn = 0;
RC4_handle keyOut = 0;
int FP9HandShake = FALSE;
int encrypted;
#ifndef _DEBUG
int32_t *ip;
#endif
uint8_t clientsig[RTMP_SIG_SIZE];
uint8_t serverbuf[RTMP_SIG_SIZE + 4], *serversig = serverbuf+4;
uint8_t type;
uint32_t uptime;
getoff *getdh = NULL, *getdig = NULL;
if (ReadN(r, (char *)&type, 1) != 1) /* 0x03 or 0x06 */
return FALSE;
if (ReadN(r, (char *)clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
return FALSE;
RTMP_Log(RTMP_LOGDEBUG, "%s: Type Requested : %02X", __FUNCTION__, type);
RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
if (type == 3)
{
encrypted = FALSE;
}
else if (type == 6 || type == 8)
{
offalg = 1;
encrypted = TRUE;
FP9HandShake = TRUE;
r->Link.protocol |= RTMP_FEATURE_ENC;
/* use FP10 if client is capable */
if (clientsig[4] == 128)
type = 8;
}
else
{
RTMP_Log(RTMP_LOGERROR, "%s: Unknown version %02x",
__FUNCTION__, type);
return FALSE;
}
if (!FP9HandShake && clientsig[4])
FP9HandShake = TRUE;
serversig[-1] = type;
r->Link.rc4keyIn = r->Link.rc4keyOut = 0;
uptime = htonl(RTMP_GetTime());
memcpy(serversig, &uptime, 4);
if (FP9HandShake)
{
/* Server version */
serversig[4] = 3;
serversig[5] = 5;
serversig[6] = 1;
serversig[7] = 1;
getdig = digoff[offalg];
getdh = dhoff[offalg];
}
else
{
memset(&serversig[4], 0, 4);
}
/* generate random data */
#ifdef _DEBUG
memset(serversig+8, 0, RTMP_SIG_SIZE-8);
#else
ip = (int32_t *)(serversig+8);
for (i = 2; i < RTMP_SIG_SIZE/4; i++)
*ip++ = rand();
#endif
/* set handshake digest */
if (FP9HandShake)
{
if (encrypted)
{
/* generate Diffie-Hellmann parameters */
r->Link.dh = DHInit(1024);
if (!r->Link.dh)
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't initialize Diffie-Hellmann!",
__FUNCTION__);
return FALSE;
}
dhposServer = getdh(serversig, RTMP_SIG_SIZE);
RTMP_Log(RTMP_LOGDEBUG, "%s: DH pubkey position: %d", __FUNCTION__, dhposServer);
if (!DHGenerateKey(r->Link.dh))
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't generate Diffie-Hellmann public key!",
__FUNCTION__);
return FALSE;
}
if (!DHGetPublicKey
(r->Link.dh, (uint8_t *) &serversig[dhposServer], 128))
{
RTMP_Log(RTMP_LOGERROR, "%s: Couldn't write public key!", __FUNCTION__);
return FALSE;
}
}
digestPosServer = getdig(serversig, RTMP_SIG_SIZE); /* reuse this value in verification */
RTMP_Log(RTMP_LOGDEBUG, "%s: Server digest offset: %d", __FUNCTION__,
digestPosServer);
CalculateDigest(digestPosServer, serversig, GenuineFMSKey, 36,
&serversig[digestPosServer]);
RTMP_Log(RTMP_LOGDEBUG, "%s: Initial server digest: ", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, serversig + digestPosServer,
SHA256_DIGEST_LENGTH);
}
RTMP_Log(RTMP_LOGDEBUG2, "Serversig: ");
RTMP_LogHex(RTMP_LOGDEBUG2, serversig, RTMP_SIG_SIZE);
if (!WriteN(r, (char *)serversig-1, RTMP_SIG_SIZE + 1))
return FALSE;
/* decode client response */
memcpy(&uptime, clientsig, 4);
uptime = ntohl(uptime);
RTMP_Log(RTMP_LOGDEBUG, "%s: Client Uptime : %d", __FUNCTION__, uptime);
RTMP_Log(RTMP_LOGDEBUG, "%s: Player Version: %d.%d.%d.%d", __FUNCTION__, clientsig[4],
clientsig[5], clientsig[6], clientsig[7]);
if (FP9HandShake)
{
uint8_t digestResp[SHA256_DIGEST_LENGTH];
uint8_t *signatureResp = NULL;
/* we have to use this signature now to find the correct algorithms for getting the digest and DH positions */
int digestPosClient = getdig(clientsig, RTMP_SIG_SIZE);
if (!VerifyDigest(digestPosClient, clientsig, GenuineFPKey, 30))
{
RTMP_Log(RTMP_LOGWARNING, "Trying different position for client digest!");
offalg ^= 1;
getdig = digoff[offalg];
getdh = dhoff[offalg];
digestPosClient = getdig(clientsig, RTMP_SIG_SIZE);
if (!VerifyDigest(digestPosClient, clientsig, GenuineFPKey, 30))
{
RTMP_Log(RTMP_LOGERROR, "Couldn't verify the client digest"); /* continuing anyway will probably fail */
return FALSE;
}
}
/* generate SWFVerification token (SHA256 HMAC hash of decompressed SWF, key are the last 32 bytes of the server handshake) */
if (r->Link.SWFSize)
{
const char swfVerify[] = { 0x01, 0x01 };
char *vend = r->Link.SWFVerificationResponse+sizeof(r->Link.SWFVerificationResponse);
memcpy(r->Link.SWFVerificationResponse, swfVerify, 2);
AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2], vend, r->Link.SWFSize);
AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6], vend, r->Link.SWFSize);
HMACsha256(r->Link.SWFHash, SHA256_DIGEST_LENGTH,
&serversig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
SHA256_DIGEST_LENGTH,
(uint8_t *)&r->Link.SWFVerificationResponse[10]);
}
/* do Diffie-Hellmann Key exchange for encrypted RTMP */
if (encrypted)
{
int dhposClient, len;
/* compute secret key */
uint8_t secretKey[128] = { 0 };
dhposClient = getdh(clientsig, RTMP_SIG_SIZE);
RTMP_Log(RTMP_LOGDEBUG, "%s: Client DH public key offset: %d", __FUNCTION__,
dhposClient);
len =
DHComputeSharedSecretKey(r->Link.dh,
(uint8_t *) &clientsig[dhposClient], 128,
secretKey);
if (len < 0)
{
RTMP_Log(RTMP_LOGDEBUG, "%s: Wrong secret key position!", __FUNCTION__);
return FALSE;
}
RTMP_Log(RTMP_LOGDEBUG, "%s: Secret key: ", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, secretKey, 128);
InitRC4Encryption(secretKey,
(uint8_t *) &clientsig[dhposClient],
(uint8_t *) &serversig[dhposServer],
&keyIn, &keyOut);
}
/* calculate response now */
signatureResp = clientsig+RTMP_SIG_SIZE-SHA256_DIGEST_LENGTH;
HMACsha256(&clientsig[digestPosClient], SHA256_DIGEST_LENGTH,
GenuineFMSKey, sizeof(GenuineFMSKey), digestResp);
HMACsha256(clientsig, RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH, digestResp,
SHA256_DIGEST_LENGTH, signatureResp);
#ifdef FP10
if (type == 8 )
{
uint8_t *dptr = digestResp;
uint8_t *sig = signatureResp;
/* encrypt signatureResp */
for (i=0; i<SHA256_DIGEST_LENGTH; i+=8)
rtmpe8_sig(sig+i, sig+i, dptr[i] % 15);
}
else if (type == 9)
{
uint8_t *dptr = digestResp;
uint8_t *sig = signatureResp;
/* encrypt signatureResp */
for (i=0; i<SHA256_DIGEST_LENGTH; i+=8)
rtmpe9_sig(sig+i, sig+i, dptr[i] % 15);
}
#endif
/* some info output */
RTMP_Log(RTMP_LOGDEBUG,
"%s: Calculated digest key from secure key and server digest: ",
__FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, digestResp, SHA256_DIGEST_LENGTH);
RTMP_Log(RTMP_LOGDEBUG, "%s: Server signature calculated:", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, signatureResp, SHA256_DIGEST_LENGTH);
}
#if 0
else
{
uptime = htonl(RTMP_GetTime());
memcpy(clientsig+4, &uptime, 4);
}
#endif
RTMP_Log(RTMP_LOGDEBUG2, "%s: Sending handshake response: ",
__FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
if (!WriteN(r, (char *)clientsig, RTMP_SIG_SIZE))
return FALSE;
/* 2nd part of handshake */
if (ReadN(r, (char *)clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
return FALSE;
RTMP_Log(RTMP_LOGDEBUG2, "%s: 2nd handshake: ", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG2, clientsig, RTMP_SIG_SIZE);
if (FP9HandShake)
{
uint8_t signature[SHA256_DIGEST_LENGTH];
uint8_t digest[SHA256_DIGEST_LENGTH];
RTMP_Log(RTMP_LOGDEBUG, "%s: Client sent signature:", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, &clientsig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
SHA256_DIGEST_LENGTH);
/* verify client response */
HMACsha256(&serversig[digestPosServer], SHA256_DIGEST_LENGTH,
GenuineFPKey, sizeof(GenuineFPKey), digest);
HMACsha256(clientsig, RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH, digest,
SHA256_DIGEST_LENGTH, signature);
#ifdef FP10
if (type == 8 )
{
uint8_t *dptr = digest;
uint8_t *sig = signature;
/* encrypt signatureResp */
for (i=0; i<SHA256_DIGEST_LENGTH; i+=8)
rtmpe8_sig(sig+i, sig+i, dptr[i] % 15);
}
else if (type == 9)
{
uint8_t *dptr = digest;
uint8_t *sig = signature;
/* encrypt signatureResp */
for (i=0; i<SHA256_DIGEST_LENGTH; i+=8)
rtmpe9_sig(sig+i, sig+i, dptr[i] % 15);
}
#endif
/* show some information */
RTMP_Log(RTMP_LOGDEBUG, "%s: Digest key: ", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, digest, SHA256_DIGEST_LENGTH);
RTMP_Log(RTMP_LOGDEBUG, "%s: Signature calculated:", __FUNCTION__);
RTMP_LogHex(RTMP_LOGDEBUG, signature, SHA256_DIGEST_LENGTH);
if (memcmp
(signature, &clientsig[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH],
SHA256_DIGEST_LENGTH) != 0)
{
RTMP_Log(RTMP_LOGWARNING, "%s: Client not genuine Adobe!", __FUNCTION__);
return FALSE;
}
else
{
RTMP_Log(RTMP_LOGDEBUG, "%s: Genuine Adobe Flash Player", __FUNCTION__);
}
if (encrypted)
{
char buff[RTMP_SIG_SIZE];
/* set keys for encryption from now on */
r->Link.rc4keyIn = keyIn;
r->Link.rc4keyOut = keyOut;
/* update the keystreams */
if (r->Link.rc4keyIn)
{
RC4_encrypt(r->Link.rc4keyIn, RTMP_SIG_SIZE, (uint8_t *) buff);
}
if (r->Link.rc4keyOut)
{
RC4_encrypt(r->Link.rc4keyOut, RTMP_SIG_SIZE, (uint8_t *) buff);
}
}
}
else
{
if (memcmp(serversig, clientsig, RTMP_SIG_SIZE) != 0)
{
RTMP_Log(RTMP_LOGWARNING, "%s: client signature does not match!",
__FUNCTION__);
}
}
// TODO(mgoulet): Should this have an Rc4_free?
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
}

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)
@ -344,40 +343,45 @@ RTMP_TLS_LoadCerts() {
CFRelease(keychain_ref);
#elif defined(__linux__)
if (mbedtls_x509_crt_parse_path(chain, "/etc/ssl/certs/") != 0) {
if (mbedtls_x509_crt_parse_path(chain, "/etc/ssl/certs/") < 0) {
RTMP_Log(RTMP_LOGERROR, "mbedtls_x509_crt_parse_path: Couldn't parse "
"/etc/ssl/certs");
goto error;
}
#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:
RTMP_Log(RTMP_LOGERROR, "RTMP_TLS_LoadCerts: Failed to load "
"root certificate chains, RTMPS connections will likely "
"fail");
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,114 +411,24 @@ 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;
#endif
}
void *
RTMP_TLS_AllocServerContext(const char* cert, const char* key)
{
void *ctx = NULL;
#ifdef CRYPTO
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
#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;
mbedtls_x509_crt_init(&tc->cert);
if (mbedtls_x509_crt_parse_file(&tc->cert, cert))
{
free(tc);
return NULL;
}
mbedtls_pk_init(&tc->key);
if (mbedtls_pk_parse_keyfile(&tc->key, key, NULL))
{
mbedtls_x509_crt_free(&tc->cert);
mbedtls_pk_free(&tc->key);
free(tc);
return NULL;
}
#elif defined(USE_POLARSSL)
tls_server_ctx *tc = ctx = calloc(1, sizeof(struct tls_server_ctx));
tc->dhm_P = my_dhm_P;
tc->dhm_G = my_dhm_G;
tc->hs = &RTMP_TLS_ctx->hs;
if (x509parse_crtfile(&tc->cert, cert))
{
free(tc);
return NULL;
}
if (x509parse_keyfile(&tc->key, key, NULL))
{
x509_free(&tc->cert);
free(tc);
return NULL;
}
#elif defined(USE_GNUTLS) && !defined(NO_SSL)
gnutls_certificate_allocate_credentials((gnutls_certificate_credentials*) &ctx);
if (gnutls_certificate_set_x509_key_file(ctx, cert, key, GNUTLS_X509_FMT_PEM) != 0)
{
gnutls_certificate_free_credentials(ctx);
return NULL;
}
#elif !defined(NO_SSL) /* USE_OPENSSL */
ctx = SSL_CTX_new(SSLv23_server_method());
if (!SSL_CTX_use_certificate_chain_file(ctx, cert))
{
SSL_CTX_free(ctx);
return NULL;
}
if (!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
{
SSL_CTX_free(ctx);
return NULL;
}
#endif
#else
(void)cert;
(void)key;
#endif
return ctx;
}
void
RTMP_TLS_FreeServerContext(void *ctx)
{
#ifdef CRYPTO
#if defined(USE_MBEDTLS)
mbedtls_x509_crt_free(&((tls_server_ctx*)ctx)->cert);
mbedtls_pk_free(&((tls_server_ctx*)ctx)->key);
free(ctx);
#elif defined(USE_POLARSSL)
x509_free(&((tls_server_ctx*)ctx)->cert);
rsa_free(&((tls_server_ctx*)ctx)->key);
free(ctx);
#elif defined(USE_GNUTLS) && !defined(NO_SSL)
gnutls_certificate_free_credentials(ctx);
#elif !defined(NO_SSL) /* USE_OPENSSL */
SSL_CTX_free(ctx);
#endif
#else
(void)ctx;
free(r->RTMP_TLS_ctx);
r->RTMP_TLS_ctx = NULL;
#endif
}
@ -528,8 +442,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 +450,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 +465,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 +693,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);
@ -1008,46 +925,16 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen)
return TRUE;
}
int
RTMP_TLS_Accept(RTMP *r, void *ctx)
{
#if defined(CRYPTO) && !defined(NO_SSL)
tls_server_ctx *srv_ctx = 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_init(client_fd);
client_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, client_fd);
#else
TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
#endif
int connect_return = TLS_connect(r->m_sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
return FALSE;
}
return TRUE;
#else
(void)r;
(void)ctx;
return FALSE;
#endif
}
int
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);
@ -1070,10 +957,9 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
if (connect_return < 0)
{
#if defined(USE_MBEDTLS)
r->last_error_code = connect_return;
if (connect_return == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)
{
r->last_error_code = connect_return;
// show a more detailed error in the log if possible
int verify_result = mbedtls_ssl_get_verify_result(r->m_sb.sb_ssl);
if (verify_result)
@ -2696,9 +2582,16 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
#if defined(USE_MBEDTLS)
typedef mbedtls_md5_context MD5_CTX;
#if MBEDTLS_VERSION_NUMBER >= 0x02070000
#define MD5_Init(ctx) mbedtls_md5_init(ctx); mbedtls_md5_starts_ret(ctx)
#define MD5_Update(ctx,data,len) mbedtls_md5_update_ret(ctx,(unsigned char *)data,len)
#define MD5_Final(dig,ctx) mbedtls_md5_finish_ret(ctx,dig); mbedtls_md5_free(ctx)
#else
#define MD5_Init(ctx) mbedtls_md5_init(ctx); mbedtls_md5_starts(ctx)
#define MD5_Update(ctx,data,len) mbedtls_md5_update(ctx,(unsigned char *)data,len)
#define MD5_Final(dig,ctx) mbedtls_md5_finish(ctx,dig); mbedtls_md5_free(ctx)
#endif
#elif defined(USE_POLARSSL)
#define MD5_CTX md5_context
@ -4115,69 +4008,6 @@ HandShake(RTMP *r, int FP9HandShake)
(void)FP9HandShake;
return TRUE;
}
static int
SHandShake(RTMP *r)
{
int i;
char serverbuf[RTMP_SIG_SIZE + 1], *serversig = serverbuf + 1;
char clientsig[RTMP_SIG_SIZE];
uint32_t uptime;
int bMatch;
if (ReadN(r, serverbuf, 1) != 1) /* 0x03 or 0x06 */
return FALSE;
RTMP_Log(RTMP_LOGDEBUG, "%s: Type Request : %02X", __FUNCTION__, serverbuf[0]);
if (serverbuf[0] != 3)
{
RTMP_Log(RTMP_LOGERROR, "%s: Type unknown: client sent %02X",
__FUNCTION__, serverbuf[0]);
return FALSE;
}
uptime = htonl(RTMP_GetTime());
memcpy(serversig, &uptime, 4);
memset(&serversig[4], 0, 4);
#ifdef _DEBUG
for (i = 8; i < RTMP_SIG_SIZE; i++)
serversig[i] = 0xff;
#else
for (i = 8; i < RTMP_SIG_SIZE; i++)
serversig[i] = (char)(rand() % 256);
#endif
if (!WriteN(r, serverbuf, RTMP_SIG_SIZE + 1))
return FALSE;
if (ReadN(r, clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
return FALSE;
/* decode client response */
memcpy(&uptime, clientsig, 4);
uptime = ntohl(uptime);
RTMP_Log(RTMP_LOGDEBUG, "%s: Client Uptime : %d", __FUNCTION__, uptime);
RTMP_Log(RTMP_LOGDEBUG, "%s: Player Version: %d.%d.%d.%d", __FUNCTION__,
clientsig[4], clientsig[5], clientsig[6], clientsig[7]);
/* 2nd part of handshake */
if (!WriteN(r, clientsig, RTMP_SIG_SIZE))
return FALSE;
if (ReadN(r, clientsig, RTMP_SIG_SIZE) != RTMP_SIG_SIZE)
return FALSE;
bMatch = (memcmp(serversig, clientsig, RTMP_SIG_SIZE) == 0);
if (!bMatch)
{
RTMP_Log(RTMP_LOGWARNING, "%s, client signature does not match!", __FUNCTION__);
}
return TRUE;
}
#endif
int
@ -4421,12 +4251,6 @@ RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
return TRUE;
}
int
RTMP_Serve(RTMP *r)
{
return SHandShake(r);
}
void
RTMP_Close(RTMP *r)
{

View file

@ -49,6 +49,131 @@
#include "amf.h"
#ifdef CRYPTO
#if defined(USE_MBEDTLS)
#include <mbedtls/version.h>
#if MBEDTLS_VERSION_NUMBER >= 0x02040000
#include <mbedtls/net_sockets.h>
#else
#include <mbedtls/net.h>
#endif
#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 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_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;
#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_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_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)
#else /* USE_OPENSSL */
#define TLS_CTX SSL_CTX *
#define TLS_client(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
#elif defined(USE_ONLY_MD5)
#include "md5.h"
#include "cencode.h"
#define MD5_DIGEST_LENGTH 16
#endif
#ifdef __cplusplus
extern "C"
{
@ -326,6 +451,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,
@ -360,8 +489,6 @@ extern "C"
struct sockaddr;
int RTMP_Connect0(RTMP *r, struct sockaddr *svc, socklen_t addrlen);
int RTMP_Connect1(RTMP *r, RTMPPacket *cp);
int RTMP_Serve(RTMP *r);
int RTMP_TLS_Accept(RTMP *r, void *ctx);
int RTMP_ReadPacket(RTMP *r, RTMPPacket *packet);
int RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue);
@ -381,13 +508,10 @@ 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_FreeServerContext(void *ctx);
int RTMP_LibVersion(void);
void RTMP_UserInterrupt(void); /* user typed Ctrl-C */
@ -415,10 +539,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.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);
@ -145,8 +145,8 @@ static void *rtmp_stream_create(obs_data_t *settings, obs_output_t *output)
stream->output = output;
pthread_mutex_init_value(&stream->packets_mutex);
RTMP_Init(&stream->rtmp);
RTMP_LogSetCallback(log_rtmp);
RTMP_Init(&stream->rtmp);
RTMP_LogSetLevel(RTMP_LOGWARNING);
if (pthread_mutex_init(&stream->packets_mutex, NULL) != 0)
@ -407,6 +407,8 @@ static int send_packet(struct rtmp_stream *stream,
int recv_size = 0;
int ret = 0;
assert(idx < RTMP_MAX_STREAMS);
if (!stream->new_socket_loop) {
#ifdef _WIN32
ret = ioctlsocket(stream->rtmp.m_sb.sb_socket, FIONREAD,
@ -514,10 +516,18 @@ static void set_output_error(struct rtmp_stream *stream)
case -0x2700:
msg = obs_module_text("SSLCertVerifyFailed");
break;
case -0x7680:
msg = "Failed to load root certificates for a secure TLS connection."
#if defined(__linux__)
" Check you have an up to date root certificate bundle in /etc/ssl/certs."
#endif
;
break;
}
}
obs_output_set_last_error(stream->output, msg);
if (msg)
obs_output_set_last_error(stream->output, msg);
}
static void dbr_add_frame(struct rtmp_stream *stream, struct dbr_frame *back)
@ -934,7 +944,15 @@ 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);
// since we don't call RTMP_Init above, there's no other good place
// to reset this as doing it in RTMP_Close breaks the ugly RTMP
// authentication system
memset(&stream->rtmp.Link, 0, sizeof(stream->rtmp.Link));
stream->rtmp.last_error_code = 0;
if (!RTMP_SetupURL(&stream->rtmp, stream->path.array))
return OBS_OUTPUT_BAD_PATH;