New upstream version 22.0.3+dfsg1

This commit is contained in:
Sebastian Ramacher 2018-12-16 17:14:58 +01:00
parent 665f64a933
commit cdc9a9fc87
334 changed files with 14525 additions and 2639 deletions

View file

@ -1,20 +1,25 @@
project(obs-outputs)
option(USE_SSL "Enable rtmps support with OpenSSL" OFF)
set(WITH_RTMPS AUTO CACHE STRING "Enable RTMPS support with mbedTLS")
set_property(CACHE WITH_RTMPS PROPERTY STRINGS AUTO ON OFF)
if (USE_SSL)
find_package(SSL QUIET)
option(STATIC_MBEDTLS "Statically link mbedTLS into binary" OFF)
if (WITH_RTMPS OR (WITH_RTMPS STREQUAL "AUTO"))
find_package(MbedTLS QUIET)
find_package(ZLIB QUIET)
endif()
if (SSL_FOUND AND ZLIB_FOUND)
add_definitions(-DCRYPTO -DUSE_OPENSSL)
include_directories(${SSL_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
if (LIBMBEDTLS_FOUND AND ZLIB_FOUND)
add_definitions(-DCRYPTO -DUSE_MBEDTLS)
include_directories(${LIBMBEDTLS_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
else()
if (USE_SSL)
message(WARNING "SSL enabled by user, but OpenSSL was not found")
if(WITH_RTMPS STREQUAL "AUTO")
message(WARNING "mbedTLS was not found, RTMPS will be auto-disabled")
elseif (WITH_RTMPS)
message(FATAL_ERROR "RTMPS enabled by user, but mbedTLS was not found")
endif()
unset(SSL_LIBRARIES)
unset(LIBMBEDTLS_LIBRARIES)
unset(ZLIB_LIBRARIES)
add_definitions(-DNO_CRYPTO)
endif()
@ -84,6 +89,12 @@ if(WIN32)
ws2_32
winmm
Iphlpapi)
if (WITH_RTMPS OR (WITH_RTMPS STREQUAL "AUTO"))
SET(obs-outputs_PLATFORM_DEPS
${obs-outputs_PLATFORM_DEPS}
crypt32)
endif()
endif()
if(MSVC)
@ -92,6 +103,16 @@ if(MSVC)
w32-pthreads)
endif()
if(APPLE AND (WITH_RTMPS OR (WITH_RTMPS STREQUAL "AUTO")))
find_library(FOUNDATION_FRAMEWORK Foundation)
find_library(SECURITY_FRAMEWORK Security)
set(obs-outputs_PLATFORM_DEPS
${obs-outputs_PLATFORM_DEPS}
${FOUNDATION_FRAMEWORK}
${SECURITY_FRAMEWORK})
endif()
set(obs-outputs_librtmp_HEADERS
librtmp/amf.h
librtmp/bytes.h
@ -133,7 +154,7 @@ set(obs-outputs_SOURCES
flv-output.c
flv-mux.c
net-if.c)
add_library(obs-outputs MODULE
${ftl_SOURCES}
${ftl_HEADERS}
@ -143,7 +164,7 @@ add_library(obs-outputs MODULE
${obs-outputs_librtmp_HEADERS})
target_link_libraries(obs-outputs
libobs
${SSL_LIBRARIES}
${LIBMBEDTLS_LIBRARIES}
${ZLIB_LIBRARIES}
${ftl_IMPORTS}
${obs-outputs_PLATFORM_DEPS})

View file

@ -2,5 +2,8 @@ RTMPStream="تيار RTMP"
RTMPStream.DropThreshold="انخفاض البداية (مللي ثانية)"
FLVOutput="اخراج الملف بصيغة FLV"
FLVOutput.FilePath="مسار الملف"
Default="Default"
ConnectionTimedOut="انتهت مهلة الاتصال. تأكد من أن قمت بتكوين خدمة البث صالحة ولا جدار الحماية بحظر الاتصال."
ConnectionReset="The connection was reset by the peer. This usually indicates internet connection problems between you and the streaming service."

View file

@ -11,4 +11,5 @@ ConnectionReset="La connexió s'ha acabat. Normalment això indica que hi ha pro
HostNotFound="Nom d'amfitrió no trobat. Assegureu-vos que hi hagi configurat un servidor de transmissió vàlid i que la seva connexió a Internet / DNS estiguin funcionant correctament."
NoData="Nom d'amfitrió trobat, però no hi ha dades del tipus sol·licitat. Això pot passar si heu enllaçat a una adreça IPv6 i el seu servei de transmissió només té adreces IPv4 (veure configuració / avançada)."
AddressNotAvailable="Direcció no disponible. Potser heu intentat enllaçar amb una adreça IP no vàlida (veure configuració / avançada)."
SSLCertVerifyFailed="El servidor RTMP ha enviat un certificat SSL no vàlid."

View file

@ -11,4 +11,5 @@ ConnectionReset="Připojení bylo resetováno druhou stranou. Toto obvykle zname
HostNotFound="Hostitel nebyl nalezen. Zkontrolujte, zda jste zadali správný vysílací server a že vaše připojení k internetu / DNS funguje jak má."
NoData="Hostitel byl nalezen, ale žádná data požadovaného typu. Toto se může stát, pokud používáte IPv6 adresu, ale vaše vysílací služba podporuje pouze připojení přes svou IPv4 adresu (viz. Nastavení / Rozšířené)."
AddressNotAvailable="Adresa není k dispozici. Možná jste se snažili použít chybnou IP adresu (viz. Nastavení / Rozšířené)."
SSLCertVerifyFailed="RTMP server odeslal neplatný SSL certifikát."

View file

@ -11,4 +11,5 @@ ConnectionReset="Forbindelsen blev afbrudt. Dette indikerer typisk et problem me
HostNotFound="Værtsnavn ikke fundet. Tjek at du har angivet en gyldig streaming-server, og at din Internetforbindelse/DNS fungerer korrekt."
NoData="Værtsnavn fundet, men ingen data af den ønskede type. Dette kan forekomme, hvis du har tildelt en IPv6-adresse, og din streaming-tjeneste kun benytter IPv4-adresser (se Indstillinger/Avanceret)."
AddressNotAvailable="Adresse utilgængelig. Du kan have forsøgt at tildele en ugyldig IP-adresse (se Indstillinger/Avanceret)."
SSLCertVerifyFailed="RTMP-serveren har sendt et ugyldig SSL-certifikat."

View file

@ -11,4 +11,5 @@ ConnectionReset="Die Verbindung wurde durch Kommunikationspartner zurückgesetzt
HostNotFound="Hostname nicht gefunden. Stellen Sie sicher, dass Sie einen gültigen Streaming-Server eingegeben haben und Ihre Internetverbindung / DNS korrekt arbeiten."
NoData="Hostname gefunden, aber keine Daten des angeforderten Typs. Dies kann auftreten, wenn Sie eine IPv6-Adresse verwenden und Ihr Streaming-Dienst nur über IPv4-Adressen verfügt (siehe Einstellungen / Erweitert)."
AddressNotAvailable="Adresse nicht Verfügbar. Sie haben möglicherweise versucht, eine ungültige IP-Adresse zu verwenden (siehe Einstellungen / Erweitert)."
SSLCertVerifyFailed="Der RTMP-Server hat ein ungültiges SSL-Zertifikat gesendet."

View file

@ -4,4 +4,11 @@ FLVOutput="FLV Αρχείο Εξόδου"
FLVOutput.FilePath="Διαδρομή Αρχείου"
Default="Προεπιλογή"
ConnectionTimedOut="Εξαντλήθηκε το χρονικό όριο της σύνδεσης. Βεβαιωθείτε ότι έχετε ρυθμίσει μια έγκυρη υπηρεσία συνεχούς ροής και το τείχος προστασίας δεν εμποδίζει τη σύνδεση."
PermissionDenied="Αποκλείστηκε η σύνδεση. Ελέγξτε το τείχος προστασίας / ρυθμίσεις προστασίας από ιούς για να βεβαιωθείτε οτι στο OBS επιτρέπεται να έχει πλήρης πρόσβαση στο διαδίκτυο."
ConnectionAborted="Η σύνδεση ματαιώθηκε. Αυτό συνήθως υποδεικνύει προβλήματα σύνδεσης στο διαδίκτυο ανάμεσα σε εσάς και την υπηρεσία συνεχούς ροής."
ConnectionReset="Η σύνδεση ήταν επαναφέρθηκε στον ομότιμο υπολογιστή. Αυτό συνήθως υποδεικνύει προβλήματα σύνδεσης στο διαδίκτυο ανάμεσα σε εσάς και την υπηρεσία συνεχούς ροής."
HostNotFound="Το όνομα του κεντρικού υπολογιστή δεν βρέθηκε. Βεβαιωθείτε ότι πληκτρολογήσατε έναν έγκυρο διακομιστή συνεχούς ροής και η σύνδεση στο διαδίκτυο / DNS λειτουργεί σωστά."
NoData="Το όνομα του κεντρικού υπολογιστή βρέθηκε, αλλά χωρίς δεδομένα του ζητούμενου τύπου. Αυτό μπορεί να συμβεί αν έχετε δεσμεύσει μια διεύθυνση IPv6 και για την υπηρεσία συνεχούς ροής μόνο διευθύνσεις IPv4 (ανατρέξτε στην ενότητα ρυθμίσεις)."
AddressNotAvailable="Η διεύθυνση δεν είναι διαθέσιμη. Μπορεί να έχετε δοκιμάσει να συνδεθείτε σε μια άκυρη διεύθυνση IP (βλ. ρυθμίσεις)."

View file

@ -11,3 +11,4 @@ ConnectionReset="The connection was reset by the peer. This usually indicates in
HostNotFound="Hostname not found. Make sure you entered a valid streaming server and your internet connection / DNS are working correctly."
NoData="Hostname found, but no data of the requested type. This can occur if you have bound to an IPv6 address and your streaming service only has IPv4 addresses (see Settings / Advanced)."
AddressNotAvailable="Address not available. You may have tried to bind to an invalid IP address (see Settings / Advanced)."
SSLCertVerifyFailed="The RTMP server sent an invalid SSL certificate."

View file

@ -11,4 +11,5 @@ ConnectionReset="La conexión se ha terminado. Normalmente esto indica que hay p
HostNotFound="Nombre de host no encontrado. Asegúrese que haya configurado un servidor de transmisión valido y que su conexión a Internet / DNS estén funcionando correctamente."
NoData="Nombre de host encontrado, pero no hay datos del tipo solicitado. Esto puede ocurrir si has enlazado a una dirección IPv6 y su servicio de streaming sólo tiene direcciones IPv4 (ver Configuración / Avanzada)."
AddressNotAvailable="Dirección no disponible. Puede que hayas intentado enlazar con una dirección IP no valida (vea Configuración / Avanzado)."
SSLCertVerifyFailed="El servidor RTMP envió un certificado SSL no válido."

View file

@ -11,4 +11,5 @@ ConnectionReset="Pareak berrezarri du konexioa. Transmisioaren zerbitzurekin kon
HostNotFound="Ez da ostalari-izena topatu. Egiaztatu baliozko transmisio zerbitzaria jarri duzula eta zure Internet-konexioa eta DNSa zuzen ari direla lanean."
NoData="Ostalari-izena topatu da baina eskatutako datu motatik batere ez. Gerta daiteke IPv6 helbide bat eskatu izana eta zure transmisio zerbitzuak bakarrik onartzea IPv4 helbideak (Ikus ezarpen aurreratuak)."
AddressNotAvailable="Helbidea ez dago eskuragarri. Agian saiatu zara baliozkoa ez den IP helbide batera konektatzen (ikus ezarpen aurreratuak)."
SSLCertVerifyFailed="RTMP zerbitzariak baliorik gabeko SSL ziurtagiria bidali du."

View file

@ -11,4 +11,5 @@ ConnectionReset="Yhteys katkaistiin. Tämä tarkoittaa yleensä yhteysongelmia s
HostNotFound="Isäntänimeä ei löytynyt. Varmista että syötit voimassaolevan lähetyspalvelimen ja että internet-yhteytesi tai DNS-palvelimesi toimivat oikein."
NoData="Isäntänimi löytyi, mutta ei oikeanlaista pyydettyä dataa. Näin voi tapahtua jos olet rajannut yhteytesi IPv6 -osoitteeseen ja lähetyspalvelusi tukee vain IPv4-osoitteita (Katso Asetukset / Lisäasetukset)."
AddressNotAvailable="Osoite ei ole saatavilla. Voi olla että yritit kiinnittää väärän IP-osoitteen (Katso Asetukset / Lisäasetukset)."
SSLCertVerifyFailed="RTMP-palvelin lähetti virheellisen SSL-sertifikaatin."

View file

@ -11,4 +11,5 @@ ConnectionReset="La connexion à été interrompue. Cela indique généralement
HostNotFound="Nom dhôte non trouvé. Assurez-vous que vous avez spécifié un serveur de diffusion valide et que votre connexion internet / DNS fonctionnent correctement."
NoData="Nom dhôte trouvé, mais aucune donnée du type requis. Cela peut se produire si vous avez lié à une adresse IPv6 et votre service de diffusion ne possède que des adresses IPv4 (voir Paramètres / Avancé)."
AddressNotAvailable="Adresse non disponible. Vous avez peut-être essayé de la lier à une adresse IP non valide (voir Paramètres / Avancé)."
SSLCertVerifyFailed="Le serveur RTMP a fourni un certificat SSL incorrect."

View file

@ -0,0 +1,7 @@
RTMPStream="Sruthadh RTMP"
RTMPStream.DropThreshold="Stairsneach an tuiteim (mille-dhiog)"
FLVOutput="Às-chur faidhle FLV"
FLVOutput.FilePath="Slighe an fhaidhle"
Default="Bun-roghainn"

View file

@ -11,4 +11,5 @@ ConnectionReset="A kapcsolat a peer által megszakítva. Ez általában azt jelz
HostNotFound="A hostnév nem található. Győződjön meg róla, hogy érvényes stream szervert adott meg és az internetkapcsolata / DNS szerver megfelelően működik."
NoData="Hostnév megtalálva, viszont a kért típusú állomány nem elérhető. Ez akkor fordul elő, ha IPv6 címhez van rendelve és a stream kiszolgálójának csak IPv4 címei állnak rendelkezésre (lásd: Beállítások / Haladó)."
AddressNotAvailable="A cím nem elérhető. Valószínűleg egy érvénytelen IP címet adott meg (Lásd: Beállítások / Haladó)."
SSLCertVerifyFailed="Az RTMP kiszolgáló által küldött SSL tanúsítvány érvénytelen."

View file

@ -11,4 +11,5 @@ ConnectionReset="接続はピアによってリセットされました。 ス
HostNotFound="ホスト名が見つかりません。 有効なストリーミングサーバーを入力していることとインターネット接続/DNSが正しく機能していることを確認してください。"
NoData="ホスト名が見つかりましたが、要求されたタイプのデータがありません。 これはIPv6アドレスにバインドしている状態でストリーミングサービスにIPv4アドレスしかない場合に発生します。 (設定 / 詳細設定 を参照)"
AddressNotAvailable="アドレスを利用できません。 無効なIPアドレスにバインドしようとした可能性があります。 (設定 / 詳細設定 を参照)"
SSLCertVerifyFailed="RTMPサーバーが無効なSSL証明書を送信しました。"

View file

@ -0,0 +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

@ -11,4 +11,5 @@ ConnectionReset="상호 연결 문제로 초기화되었습니다. 보통 사용
HostNotFound="호스트 이름을 찾을 수 없습니다. 방송 서버 정보가 제대로 입력되었는지 확인하고, 인터넷 접속 혹은 DNS가 제대로 작동하고 있는지 점검하십시오."
NoData="호스트 이름은 찾았지만 요청한 형식의 데이터가 없습니다. 이 문제는 보통 사용자가 IPv6 형식의 주소를 고정하여 사용하면서 IPv4 형식의 주소만 지원하는 방송 서비스에 접속을 시도한 경우 나타납니다 (설정 / 고급 창을 확인하십시오)."
AddressNotAvailable="주소를 사용할 수 없습니다. 잘못된 IP주소를 고정하고 있습니다 (설정 / 고급 창을 확인하십시오)."
SSLCertVerifyFailed="해당 RTMP 서버는 잘못된 SSL 인증서를 보냈습니다."

View file

@ -11,4 +11,5 @@ ConnectionReset="Tilkoblingen ble avbrutt. Dette betyr vanligvis at det er probl
HostNotFound="Tjeneren ble ikke funnet. Kontroller at du har angitt en gyldig streaming server og at tilkoblingen / DNS fungerer."
NoData="Tjeneren funnet, men ingen data for den forespurte typen. Dette kan skje hvis du har bundet til en IPv6-adresse og streaming tjeneste har bare IPv4-adresser (se Snnstillinger / Avansert)."
AddressNotAvailable="Adresse ikke tilgjengelig. Du prøvde å binde til en ugyldig IP-adresse (se Innstillinger / Avansert)."
SSLCertVerifyFailed="RTMP-tjeneren sendte et ugyldig SSL-sertifikat."

View file

@ -11,4 +11,5 @@ ConnectionReset="De verbinding was gereset door de andere partij. Dit duidt mees
HostNotFound="Hostname niet gevonden. Controleer dat je een geldige streaming service hebt ingevuld en dat je internetverbinding / DNS correct werken."
NoData="Hostname gevonden, maar geen data van het verwachte type. Dit kan gebeuren als je aan een IPv6 adres hebt gebonden, en je streaming service alleen IPv4 adressen heeft (zie Instellingen / Geavanceerd)."
AddressNotAvailable="Adres niet beschikbaar. Je hebt misschien geprobeerd om aan een ongeldig IP adres te binden (zie Instellingen / Geavanceerd)."
SSLCertVerifyFailed="De RTMP-server heeft een ongeldig SSL-certificaat verzonden."

View file

@ -11,4 +11,5 @@ ConnectionReset="Połączenie zostało przerwane po stronie serwera. Wskazuje to
HostNotFound="Nie znaleziono nazwy hosta. Upewnij się, że wprowadzono prawidłowe dane serwera przesyłania strumieniowego i połączenie z internetem / DNS są poprawne."
NoData="Nazwa serwera została znaleziona ale nie stwierdzono poprawności odbieranych danych. Dzieje się tak najczęściej po przypisaniu aplikacji do adresu IPv6, gdy usługa strumieniowania obsługuje jedynie adresy IPv4 (zobacz Ustawienia -> Zaawansowane)."
AddressNotAvailable="Adres IP niedostępny. Być może powiązano aplikację z nieprawidłowym adresem IP (zobacz Ustawienia -> Zaawansowane)."
SSLCertVerifyFailed="Serwer RTMP wysłał nieprawidłowy certyfikat SSL."

View file

@ -11,4 +11,5 @@ ConnectionReset="A conexão foi redefinida pelo usuário. Isso geralmente indica
HostNotFound="Host não encontrado. Verifique se você inseriu um servidor válido de transmissão e se sua conexão de internet / DNS estão funcionando corretamente."
NoData="Host encontrado, mas não há dados do tipo solicitado. Isso pode ocorrer se você tiver vinculado a um endereço IPv6 e seu serviço de transmissão tem apenas endereços IPv4 (consulte Configurações / Avançado)."
AddressNotAvailable="Endereço não disponível. Você pode ter tentado se vincular a um endereço IP inválido (consulte Configurações / Avançado)."
SSLCertVerifyFailed="O servidor RTMP enviou um certificado SSL inválido."

View file

@ -11,4 +11,5 @@ ConnectionReset="Соединение было сброшено одноранг
HostNotFound="Имя узла не найдено. Убедитесь, что вы ввели действительный сервер вещания и ваше подключение к интернету/DNS работают правильно."
NoData="Имя узла найдено, но нет данных запрошенного типа. Такое может случиться, если вы привязаны к IPv6-адресу, а ваш сервис вещания имеет только IPv4-адреса (смотрите Настройки - Расширенные)."
AddressNotAvailable="Адрес недоступен. Возможно вы пытались привязаться к недействительному IP-адресу (смотрите Настройки - Расширенные)."
SSLCertVerifyFailed="RTMP сервер отправил недействительный сертификат SSL."

View file

@ -11,4 +11,5 @@ ConnectionReset="Anslutningen återställdes av en peer. Detta kan indikera prob
HostNotFound="Värdnamnet hittades inte. Se till att du har angivit en giltigt strömningstjänst och att din Internetanslutning / DNS fungerar på rätt sätt."
NoData="Värdnamnet hittades, men ingen data av den begärda typen. Detta kan hända om du ansluter till en IPv6-adress och din strömningstjänst endast har IPv4-adresser (gå till Inställningar / Avancerat)."
AddressNotAvailable="Adressen är inte tillgänglig. Du kanske försökte ansluta till en ogiltig IP-adress (gå till Inställningar / Avancerat)."
SSLCertVerifyFailed="RTMP-servern skickade ett ogiltigt SSL-certifikat."

View file

@ -11,4 +11,5 @@ ConnectionReset="Bağlantı karşı taraftan sıfırlandı. Bu genellikle sizin
HostNotFound="Ana bilgisayar adı bulunamadı. Geçerli bir yayın sunucusu girdiğinizden ve internet bağlantınızın / DNS'nizin düzgün çalıştığını emin olun."
NoData="Ana bilgisayar adı bulundu, ancak istenen türde veri bulunamadı. Bu bir IPv6 adresine bağlamış ve yayın servisinizin sadece IPv4 adresleri varsa oluşabilir (bkz: Ayarlar / Gelişmiş)."
AddressNotAvailable="Adres kullanılamaz. Geçersiz bir IP adresi bağlamayı denemiş olabilirsiniz (bakın: Ayarlar / Gelişmiş)."
SSLCertVerifyFailed="RTMP sunucusu geçersiz bir SSL sertifikası gönderdi."

View file

@ -11,4 +11,5 @@ ConnectionReset="З'єднання було скинуте рівноправн
HostNotFound="Ім'я хоста, не знайдено. Переконайтеся, що ви ввели дійсний сервер трансляцій і підключення до Інтернету / DNS працює правильно."
NoData="Ім'я хоста знайдено, але нема жодних даних вказаного типу. Це може статися, якщо ви вказали прив'язку до IPv6-адресу, але ваш сервіс трансляцій підтримує лише адреси IPv4 (див. Налаштування / Розширені)."
AddressNotAvailable="Адреса недоступна. Напевно ви спробували прив'язатись до адаптера з неіснуючую IP-адресою (див. Налаштування / Розширені)."
SSLCertVerifyFailed="RTMP сервер надіслав неприпустимий сертифікат SSL."

View file

@ -11,4 +11,5 @@ ConnectionReset="对方重置连接. 这通常表明你和流媒体服务之间
HostNotFound="找不到 Hostname. 请确保您输入一个有效的流媒体服务器并且您的互联网连接 / DNS 工作正常."
NoData="Hostname 发现, 但没有请求的类型的数据的主机名. 这有可能因为你绑定到 IPv6 地址并且你的流媒体服务仅有 IPv4 地址 (请参阅设置 / 高级)."
AddressNotAvailable="没有可用的地址. 你可能在试图绑定到一个无效的 IP 地址 (请参阅设置 / 高级)."
SSLCertVerifyFailed="RTMP 服务器发送了无效的 SSL 证书。"

View file

@ -11,4 +11,5 @@ ConnectionReset="連線被對方重置。通常這代表您與串流服務之間
HostNotFound="找不到主機名稱。請確定輸入了一個有效的串流服務器且網路連線跟 DNS 工作正常。"
NoData="找到主機名稱,但沒有要求類型的資料。這可能發生在您綁定於 IPv6 位址但串流服務只有 IPv4 位址 (請看 設定/進階)。"
AddressNotAvailable="位址不可用。可能因為嘗試綁定到一個不正確 IP 位址(請確認 設定/進階 的設定)。"
SSLCertVerifyFailed="RTMP 伺服器發送了一則不合法的 SSL 憑證。"

View file

@ -74,7 +74,7 @@ static bool build_flv_meta_data(obs_output_t *context,
enc_str(&enc, end, "onMetaData");
*enc++ = AMF_ECMA_ARRAY;
enc = AMF_EncodeInt32(enc, end, a_idx == 0 ? 14 : 9);
enc = AMF_EncodeInt32(enc, end, a_idx == 0 ? 20 : 15);
enc_num_val(&enc, end, "duration", 0.0);
enc_num_val(&enc, end, "fileSize", 0.0);

View file

@ -29,6 +29,7 @@
#include "bytes.h"
static const AMFObjectProperty AMFProp_Invalid = { {0, 0}, AMF_INVALID };
static const AMFObject AMFObj_Invalid = { 0, 0 };
static const AVal AV_empty = { 0, 0 };
/* Data is Big-Endian */
@ -336,13 +337,19 @@ AMFProp_GetBoolean(AMFObjectProperty *prop)
void
AMFProp_GetString(AMFObjectProperty *prop, AVal *str)
{
*str = prop->p_vu.p_aval;
if (prop->p_type == AMF_STRING)
*str = prop->p_vu.p_aval;
else
*str = AV_empty;
}
void
AMFProp_GetObject(AMFObjectProperty *prop, AMFObject *obj)
{
*obj = prop->p_vu.p_object;
if (prop->p_type == AMF_OBJECT)
*obj = prop->p_vu.p_object;
else
*obj = AMFObj_Invalid;
}
int
@ -472,6 +479,8 @@ AMF3ReadString(const char *data, AVal *str)
RTMP_Log(RTMP_LOGDEBUG,
"%s, string reference, index: %d, not supported, ignoring!",
__FUNCTION__, refIndex);
str->av_val = NULL;
str->av_len = 0;
return len;
}
else
@ -511,9 +520,12 @@ AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
if (name.av_len <= 0)
return nRes;
nSize -= nRes;
if (nSize <= 0)
return -1;
prop->p_name = name;
pBuffer += nRes;
nSize -= nRes;
}
/* decode */
@ -601,6 +613,9 @@ AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
return -1;
}
if (nSize < 0)
return -1;
return nOriginalSize - nSize;
}
@ -994,9 +1009,18 @@ AMF_DecodeArray(AMFObject *obj, const char *pBuffer, int nSize,
int nRes;
nArrayLen--;
if (nSize <= 0)
{
bError = TRUE;
break;
}
nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
if (nRes == -1)
{
bError = TRUE;
break;
}
else
{
nSize -= nRes;
@ -1057,12 +1081,12 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
else
{
int32_t classExtRef = (classRef >> 1);
int i;
int i, cdnum;
cd.cd_externalizable = (classExtRef & 0x1) == 1;
cd.cd_dynamic = ((classExtRef >> 1) & 0x1) == 1;
cd.cd_num = classExtRef >> 2;
cdnum = classExtRef >> 2;
/* class name */
@ -1077,9 +1101,16 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
cd.cd_name.av_val, cd.cd_externalizable, cd.cd_dynamic,
cd.cd_num);
for (i = 0; i < cd.cd_num; i++)
for (i = 0; i < cdnum; i++)
{
AVal memberName = AV_empty;
if (nSize <= 0)
{
invalid:
RTMP_Log(RTMP_LOGDEBUG, "%s, invalid class encoding!",
__FUNCTION__);
return nOriginalSize;
}
len = AMF3ReadString(pBuffer, &memberName);
RTMP_Log(RTMP_LOGDEBUG, "Member: %s", memberName.av_val);
AMF3CD_AddProp(&cd, &memberName);
@ -1115,6 +1146,8 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
int nRes, i;
for (i = 0; i < cd.cd_num; i++) /* non-dynamic */
{
if (nSize <= 0)
goto invalid;
nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, FALSE);
if (nRes == -1)
RTMP_Log(RTMP_LOGDEBUG, "%s, failed to decode AMF3 property!",
@ -1132,6 +1165,8 @@ AMF3_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bAMFData)
do
{
if (nSize <= 0)
goto invalid;
nRes = AMF3Prop_Decode(&prop, pBuffer, nSize, TRUE);
AMF_AddProp(obj, &prop);
@ -1179,10 +1214,18 @@ AMF_Decode(AMFObject *obj, const char *pBuffer, int nSize, int bDecodeName)
nRes = AMFProp_Decode(&prop, pBuffer, nSize, bDecodeName);
if (nRes == -1)
{
bError = TRUE;
break;
}
else
{
nSize -= nRes;
if (nSize < 0)
{
bError = TRUE;
break;
}
pBuffer += nRes;
AMF_AddProp(obj, &prop);
}

View file

@ -21,7 +21,59 @@
* http://www.gnu.org/copyleft/lgpl.html
*/
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/dhm.h>
#include <mbedtls/bignum.h>
typedef mbedtls_mpi* MP_t;
#define MP_new(m) m = malloc(sizeof(mbedtls_mpi)); mbedtls_mpi_init(m)
#define MP_set_w(mpi, w) mbedtls_mpi_lset(mpi, w)
#define MP_cmp(u, v) mbedtls_mpi_cmp_mpi(u, v)
#define MP_set(u, v) mbedtls_mpi_copy(u, v)
#define MP_sub_w(mpi, w) mbedtls_mpi_sub_int(mpi, mpi, w)
#define MP_cmp_1(mpi) mbedtls_mpi_cmp_int(mpi, 1)
#define MP_modexp(r, y, q, p) mbedtls_mpi_exp_mod(r, y, q, p, NULL)
#define MP_free(mpi) mbedtls_mpi_free(mpi); free(mpi)
#define MP_gethex(u, hex, res) MP_new(u); res = mbedtls_mpi_read_string(u, 16, hex) == 0
#define MP_bytes(u) mbedtls_mpi_size(u)
#define MP_setbin(u,buf,len) mbedtls_mpi_write_binary(u,buf,len)
#define MP_getbin(u,buf,len) MP_new(u); mbedtls_mpi_read_binary(u,buf,len)
typedef struct MDH
{
MP_t p;
MP_t g;
MP_t pub_key;
MP_t priv_key;
long length;
mbedtls_dhm_context ctx;
} 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)
{
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);
MP_new(dh->pub_key);
MP_new(dh->priv_key);
MP_set(dh->pub_key, &dh->ctx.GX);
MP_set(dh->priv_key, &dh->ctx.X);
return 1;
}
static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
{
MP_set(&dh->ctx.GY, pub);
size_t olen;
mbedtls_dhm_calc_secret(&dh->ctx, secret, len, &olen, NULL, NULL);
return 0;
}
#elif defined(USE_POLARSSL)
#include <polarssl/dhm.h>
typedef mpi * MP_t;
#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
@ -271,7 +323,7 @@ DHGetPublicKey(MDH *dh, uint8_t *pubkey, size_t nPubkeyLen)
if (!dh || !dh->pub_key)
return 0;
len = MP_bytes(dh->pub_key);
len = (int)MP_bytes(dh->pub_key);
if (len <= 0 || len > (int) nPubkeyLen)
return 0;

View file

@ -24,7 +24,28 @@
/* This file is #included in rtmp.c, it is not meant to be compiled alone */
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/md.h>
#include <mbedtls/arc4.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#endif
typedef mbedtls_md_context_t *HMAC_CTX;
#define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \
mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len)
#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig)
#define HMAC_close(ctx) mbedtls_md_free(ctx); free(ctx); ctx = NULL
typedef mbedtls_arc4_context* RC4_handle;
#define RC4_alloc(h) *h = malloc(sizeof(mbedtls_arc4_context)); mbedtls_arc4_init(*h)
#define RC4_setkey(h,l,k) mbedtls_arc4_setup(h,k,l)
#define RC4_encrypt(h,l,d) mbedtls_arc4_crypt(h,l,(unsigned char *)d,(unsigned char *)d)
#define RC4_encrypt2(h,l,s,d) mbedtls_arc4_crypt(h,l,(unsigned char *)s,(unsigned char *)d)
#define RC4_free(h) mbedtls_arc4_free(h); free(h); h = NULL
#elif defined(USE_POLARSSL)
#include <polarssl/sha2.h>
#include <polarssl/arc4.h>
#ifndef SHA256_DIGEST_LENGTH
@ -148,6 +169,8 @@ typedef unsigned int (getoff)(uint8_t *buf, unsigned int len);
static unsigned int
GetDHOffset2(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 768;
unsigned int res;
@ -177,6 +200,8 @@ GetDHOffset2(uint8_t *handshake, unsigned int len)
static unsigned int
GetDigestOffset2(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 772;
unsigned int res;
@ -206,6 +231,8 @@ GetDigestOffset2(uint8_t *handshake, unsigned int len)
static unsigned int
GetDHOffset1(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 1532;
unsigned int res;
@ -235,6 +262,8 @@ GetDHOffset1(uint8_t *handshake, unsigned int len)
static unsigned int
GetDigestOffset1(uint8_t *handshake, unsigned int len)
{
(void) len;
unsigned int offset = 0;
uint8_t *ptr = handshake + 8;
unsigned int res;
@ -1128,6 +1157,7 @@ HandShake(RTMP * r, int FP9HandShake)
__FUNCTION__);
}
}
// TODO(mgoulet): Should this have a HMAC_finish here?
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
@ -1482,6 +1512,8 @@ SHandShake(RTMP * r)
}
}
// TODO(mgoulet): Should this have an Rc4_free?
RTMP_Log(RTMP_LOGDEBUG, "%s: Handshaking finished....", __FUNCTION__);
return TRUE;
}

View file

@ -30,7 +30,20 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#include <mbedtls/md.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
#endif
typedef mbedtls_md_context_t *HMAC_CTX;
#define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \
mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \
mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len)
#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig)
#define HMAC_close(ctx) free(ctx); mbedtls_md_free(ctx); ctx = NULL
#elif defined(USE_POLARSSL)
#include <polarssl/sha2.h>
#ifndef SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH 32
@ -40,6 +53,7 @@
#define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig)
#define HMAC_close(ctx)
#elif defined(USE_GNUTLS)
#include <nettle/hmac.h>
#ifndef SHA256_DIGEST_LENGTH
@ -51,6 +65,7 @@
#define HMAC_crunch(ctx, buf, len) hmac_sha256_update(&ctx, len, buf)
#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig)
#define HMAC_close(ctx)
#else /* USE_OPENSSL */
#include <openssl/ssl.h>
#include <openssl/sha.h>
@ -161,8 +176,17 @@ HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
goto leave;
#else
TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *server_fd = &RTMP_TLS_ctx->net;
server_fd->fd = sb.sb_socket;
TLS_setfd(sb.sb_ssl, server_fd);
#else
TLS_setfd(sb.sb_ssl, sb.sb_socket);
if (TLS_connect(sb.sb_ssl) < 0)
#endif
int connect_return = TLS_connect(sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
ret = HTTPRES_LOST_CONNECTION;
@ -318,21 +342,21 @@ swfcrunch(void *ptr, size_t size, size_t nmemb, void *stream)
{
unsigned char out[CHUNK];
i->zs->next_in = (unsigned char *)p;
i->zs->avail_in = len;
i->zs->avail_in = (uInt)len;
do
{
i->zs->avail_out = CHUNK;
i->zs->next_out = out;
inflate(i->zs, Z_NO_FLUSH);
len = CHUNK - i->zs->avail_out;
i->size += len;
i->size += (int)len;
HMAC_crunch(i->ctx, out, len);
}
while (i->zs->avail_out == 0);
}
else
{
i->size += len;
i->size += (int)len;
HMAC_crunch(i->ctx, (unsigned char *)p, len);
}
return size * nmemb;
@ -469,7 +493,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
home.av_val = "\\UserData";
#else
hpre.av_val = getenv("HOMEDRIVE");
hpre.av_len = strlen(hpre.av_val);
hpre.av_len = (int)strlen(hpre.av_val);
home.av_val = getenv("HOMEPATH");
#endif
#define DIRSEP "\\"
@ -482,7 +506,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
#endif
if (!home.av_val)
home.av_val = ".";
home.av_len = strlen(home.av_val);
home.av_len = (int)strlen(home.av_val);
/* SWF hash info is cached in a fixed-format file.
* url: <url of SWF file>
@ -528,7 +552,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
if (strncmp(buf + 5, url, hlen))
continue;
r1 = strrchr(buf, '/');
i = strlen(r1);
i = (int)strlen(r1);
r1[--i] = '\0';
if (strncmp(r1, file, i))
continue;
@ -543,7 +567,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
else if (!strncmp(buf, "hash: ", 6))
{
unsigned char *ptr = hash, *in = (unsigned char *)buf + 6;
int l = strlen((char *)in) - 1;
int l = (int)strlen((char *)in) - 1;
for (i = 0; i < l; i += 2)
*ptr++ = (HEX2BIN(in[i]) << 4) | HEX2BIN(in[i + 1]);
got++;
@ -625,7 +649,7 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash,
if (q)
i = q - url;
else
i = strlen(url);
i = (int)strlen(url);
fprintf(f, "url: %.*s\n", i, url);
}

View file

@ -40,7 +40,20 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
#if defined(_WIN32)
#include <windows.h>
#include <wincrypt.h>
#elif defined(__APPLE__)
#include <Security/Security.h>
#endif
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/md5.h>
#include <mbedtls/base64.h>
#define MD5_DIGEST_LENGTH 16
#elif defined(USE_POLARSSL)
#include <polarssl/havege.h>
#include <polarssl/md5.h>
#include <polarssl/base64.h>
@ -57,7 +70,6 @@ static const char *my_dhm_P =
"E8A700D60B7F1200FA8E77B0A979DABF";
static const char *my_dhm_G = "4";
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
#define MD5_DIGEST_LENGTH 16
@ -70,7 +82,8 @@ static const char *my_dhm_G = "4";
#include <openssl/bio.h>
#include <openssl/buffer.h>
#endif
TLS_CTX RTMP_TLS_ctx;
TLS_CTX RTMP_TLS_ctx = NULL;
#endif
#define RTMP_SIG_SIZE 1536
@ -226,9 +239,13 @@ RTMPPacket_Reset(RTMPPacket *p)
}
int
RTMPPacket_Alloc(RTMPPacket *p, int nSize)
RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize)
{
char *ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE);
char *ptr;
if (nSize > SIZE_MAX - RTMP_MAX_HEADER_SIZE)
return FALSE;
ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE);
if (!ptr)
return FALSE;
p->m_body = ptr + RTMP_MAX_HEADER_SIZE;
@ -261,11 +278,101 @@ RTMP_LibVersion()
return RTMP_LIB_VERSION;
}
void
RTMP_TLS_LoadCerts() {
#ifdef USE_MBEDTLS
mbedtls_x509_crt *chain = RTMP_TLS_ctx->cacert = calloc(1, sizeof(struct mbedtls_x509_crt));
mbedtls_x509_crt_init(chain);
#if defined(_WIN32)
HCERTSTORE hCertStore;
PCCERT_CONTEXT pCertContext = NULL;
if (!(hCertStore = CertOpenSystemStore((HCRYPTPROV)NULL, L"ROOT"))) {
goto error;
}
while (pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)) {
mbedtls_x509_crt_parse_der(chain,
(unsigned char *)pCertContext->pbCertEncoded,
pCertContext->cbCertEncoded);
}
CertFreeCertificateContext(pCertContext);
CertCloseStore(hCertStore, 0);
#elif defined(__APPLE__)
SecKeychainRef keychain_ref;
CFMutableDictionaryRef search_settings_ref;
CFArrayRef result_ref;
if (SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",
&keychain_ref)
!= errSecSuccess) {
goto error;
}
search_settings_ref = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
CFDictionarySetValue(search_settings_ref, kSecClass, kSecClassCertificate);
CFDictionarySetValue(search_settings_ref, kSecMatchLimit, kSecMatchLimitAll);
CFDictionarySetValue(search_settings_ref, kSecReturnRef, kCFBooleanTrue);
CFDictionarySetValue(search_settings_ref, kSecMatchSearchList,
CFArrayCreate(NULL, (const void **)&keychain_ref, 1, NULL));
if (SecItemCopyMatching(search_settings_ref, (CFTypeRef *)&result_ref)
!= errSecSuccess) {
goto error;
}
for (CFIndex i = 0; i < CFArrayGetCount(result_ref); i++) {
SecCertificateRef item_ref = (SecCertificateRef)
CFArrayGetValueAtIndex(result_ref, i);
CFDataRef data_ref;
if ((data_ref = SecCertificateCopyData(item_ref))) {
mbedtls_x509_crt_parse_der(chain,
(unsigned char *)CFDataGetBytePtr(data_ref),
CFDataGetLength(data_ref));
CFRelease(data_ref);
}
}
CFRelease(keychain_ref);
#elif defined(__linux__)
if (mbedtls_x509_crt_parse_path(chain, "/etc/ssl/certs/") != 0) {
goto error;
}
#endif
mbedtls_ssl_conf_ca_chain(&RTMP_TLS_ctx->conf, chain, NULL);
return;
error:
mbedtls_x509_crt_free(chain);
free(chain);
RTMP_TLS_ctx->cacert = NULL;
#endif /* USE_MBEDTLS */
}
void
RTMP_TLS_Init()
{
#ifdef CRYPTO
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
const char * pers = "RTMP_TLS";
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_ctr_drbg_seed(&RTMP_TLS_ctx->ctr_drbg,
mbedtls_entropy_func,
&RTMP_TLS_ctx->entropy,
(const unsigned char *)pers,
strlen(pers));
RTMP_TLS_LoadCerts();
#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));
havege_init(&RTMP_TLS_ctx->hs);
@ -289,6 +396,26 @@ RTMP_TLS_Init()
SSL_CTX_set_options(RTMP_TLS_ctx, SSL_OP_ALL);
SSL_CTX_set_default_verify_paths(RTMP_TLS_ctx);
#endif
#else
#endif
}
void
RTMP_TLS_Free() {
#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;
}
// NO mbedtls_net_free() BECAUSE WE SET IT UP BY HAND!
free(RTMP_TLS_ctx);
RTMP_TLS_ctx = NULL;
#endif
}
@ -299,7 +426,27 @@ RTMP_TLS_AllocServerContext(const char* cert, const char* key)
#ifdef CRYPTO
if (!RTMP_TLS_ctx)
RTMP_TLS_Init();
#ifdef USE_POLARSSL
#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;
@ -346,7 +493,11 @@ void
RTMP_TLS_FreeServerContext(void *ctx)
{
#ifdef CRYPTO
#ifdef USE_POLARSSL
#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);
@ -370,6 +521,10 @@ RTMP_Alloc()
void
RTMP_Free(RTMP *r)
{
#if defined(CRYPTO) && defined(USE_MBEDTLS)
if (RTMP_TLS_ctx)
RTMP_TLS_Free();
#endif
free(r);
}
@ -846,9 +1001,20 @@ int
RTMP_TLS_Accept(RTMP *r, void *ctx)
{
#if defined(CRYPTO) && !defined(NO_SSL)
TLS_server(ctx, r->m_sb.sb_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);
if (TLS_accept(r->m_sb.sb_ssl) < 0)
#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;
@ -868,10 +1034,59 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
{
#if defined(CRYPTO) && !defined(NO_SSL)
TLS_client(RTMP_TLS_ctx, r->m_sb.sb_ssl);
#if defined(USE_MBEDTLS)
mbedtls_net_context *server_fd = &RTMP_TLS_ctx->net;
server_fd->fd = r->m_sb.sb_socket;
TLS_setfd(r->m_sb.sb_ssl, server_fd);
// make sure we verify the certificate hostname
char hostname[MBEDTLS_SSL_MAX_HOST_NAME_LEN + 1];
if (r->Link.hostname.av_len >= MBEDTLS_SSL_MAX_HOST_NAME_LEN)
return FALSE;
memcpy(hostname, r->Link.hostname.av_val, r->Link.hostname.av_len);
hostname[r->Link.hostname.av_len] = 0;
if (mbedtls_ssl_set_hostname(r->m_sb.sb_ssl, hostname))
return FALSE;
#else
TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
if (TLS_connect(r->m_sb.sb_ssl) < 0)
#endif
int connect_return = TLS_connect(r->m_sb.sb_ssl);
if (connect_return < 0)
{
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
#if defined(USE_MBEDTLS)
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)
{
char err[256], *e;
if (mbedtls_x509_crt_verify_info(err, sizeof(err), "", verify_result) > 0)
{
e = strchr(err, '\n');
if (e)
*e = '\0';
}
else
{
strcpy(err, "unknown error");
}
RTMP_Log(RTMP_LOGERROR, "%s, Cert verify failed: %d (%s)", __FUNCTION__, verify_result, err);
RTMP_Close(r);
return FALSE;
}
}
#endif
// output the error in a format that matches mbedTLS
connect_return = abs(connect_return);
RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed: -0x%x", __FUNCTION__, connect_return);
RTMP_Close(r);
return FALSE;
}
@ -879,7 +1094,6 @@ RTMP_Connect1(RTMP *r, RTMPPacket *cp)
RTMP_Log(RTMP_LOGERROR, "%s, no SSL/TLS support", __FUNCTION__);
RTMP_Close(r);
return FALSE;
#endif
}
if (r->Link.protocol & RTMP_FEATURE_HTTP)
@ -1108,7 +1322,7 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
while (!bHasMediaPacket && RTMP_IsConnected(r)
&& RTMP_ReadPacket(r, packet))
{
if (!RTMPPacket_IsReady(packet))
if (!RTMPPacket_IsReady(packet) || !packet->m_nBodySize)
{
continue;
}
@ -2398,7 +2612,19 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
{
(void)maxsize;
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
size_t osize;
if(mbedtls_base64_encode((unsigned char *) output, maxsize, &osize, input, length) == 0)
{
output[osize] = '\0';
return 1;
}
else
{
RTMP_Log(RTMP_LOGDEBUG, "%s, error", __FUNCTION__);
return 0;
}
#elif defined(USE_POLARSSL)
size_t buf_size = maxsize;
if(base64_encode((unsigned char *) output, &buf_size, input, length) == 0)
{
@ -2457,7 +2683,13 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
return 1;
}
#ifdef USE_POLARSSL
#if defined(USE_MBEDTLS)
typedef mbedtls_md5_context MD5_CTX;
#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)
#elif defined(USE_POLARSSL)
#define MD5_CTX md5_context
#define MD5_Init(ctx) md5_starts(ctx)
#define MD5_Update(ctx,data,len) md5_update(ctx,(unsigned char *)data,len)
@ -3713,7 +3945,6 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet)
{
packet->m_nBodySize = AMF_DecodeInt24(header + 3);
packet->m_nBytesRead = 0;
RTMPPacket_Free(packet);
if (nSize > 6)
{

View file

@ -150,7 +150,7 @@ extern "C"
void RTMPPacket_Reset(RTMPPacket *p);
void RTMPPacket_Dump(RTMPPacket *p);
int RTMPPacket_Alloc(RTMPPacket *p, int nSize);
int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize);
void RTMPPacket_Free(RTMPPacket *p);
#define RTMPPacket_IsReady(a) ((a)->m_nBytesRead == (a)->m_nBodySize)

View file

@ -80,7 +80,76 @@
#include "rtmp.h"
#ifdef USE_POLARSSL
#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>
@ -128,6 +197,7 @@ typedef struct tls_server_ctx
#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

View file

@ -438,6 +438,15 @@ static void set_output_error(struct rtmp_stream *stream)
}
#endif
// non platform-specific errors
if (!msg) {
switch (stream->rtmp.last_error_code) {
case -0x2700:
msg = obs_module_text("SSLCertVerifyFailed");
break;
}
}
obs_output_set_last_error(stream->output, msg);
}

View file

@ -169,13 +169,13 @@ static enum data_ret write_data(struct rtmp_stream *stream, bool *can_write,
size_t send_len =
min(latency_packet_size, stream->write_buf_len);
ret = send(stream->rtmp.m_sb.sb_socket,
ret = RTMPSockBuf_Send(&stream->rtmp.m_sb,
(const char *)stream->write_buf,
(int)send_len, 0);
(int)send_len);
} else {
ret = send(stream->rtmp.m_sb.sb_socket,
ret = RTMPSockBuf_Send(&stream->rtmp.m_sb,
(const char *)stream->write_buf,
(int)stream->write_buf_len, 0);
(int)stream->write_buf_len);
}
if (ret > 0) {