Added RTMPS listening port support
This commit is contained in:
parent
8fd4f29b06
commit
78a30e212e
4 changed files with 156 additions and 0 deletions
|
@ -807,6 +807,51 @@ static void my_debug(void *ctx, int level, const char *file, int line, const cha
|
|||
fprintf((FILE *)ctx, "%s:%04d: %s", file, line, str);
|
||||
fflush((FILE *)ctx);
|
||||
}
|
||||
|
||||
/// Takes a just-accepted socket and SSL-ifies it.
|
||||
bool Socket::Connection::sslAccept(mbedtls_ssl_config * sslConf, mbedtls_ctr_drbg_context * dbgCtx){
|
||||
int ret;
|
||||
server_fd = new mbedtls_net_context;
|
||||
mbedtls_net_init(server_fd);
|
||||
server_fd->fd = getSocket();
|
||||
|
||||
ssl = new mbedtls_ssl_context;
|
||||
mbedtls_ssl_init(ssl);
|
||||
if ((ret = mbedtls_ctr_drbg_reseed(dbgCtx, (const unsigned char *)"child", 5)) != 0){
|
||||
FAIL_MSG("Could not reseed");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up the SSL connection
|
||||
if ((ret = mbedtls_ssl_setup(ssl, sslConf)) != 0){
|
||||
FAIL_MSG("Could not set up SSL connection");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inform mbedtls how we'd like to use the connection (uses default bio handlers)
|
||||
// We tell it to use non-blocking IO here
|
||||
mbedtls_net_set_nonblock(server_fd);
|
||||
Blocking = false;
|
||||
mbedtls_ssl_set_bio(ssl, server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
|
||||
// do the SSL handshake
|
||||
while ((ret = mbedtls_ssl_handshake(ssl)) != 0){
|
||||
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE){
|
||||
char error_buf[200];
|
||||
mbedtls_strerror(ret, error_buf, 200);
|
||||
WARN_MSG("Could not handshake, SSL error: %s (%d)", error_buf, ret);
|
||||
close();
|
||||
return false;
|
||||
}else{
|
||||
Util::sleep(20);
|
||||
}
|
||||
}
|
||||
sslConnected = true;
|
||||
HIGH_MSG("Started SSL connection handler");
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// Create a new TCP Socket. This socket will (try to) connect to the given host/port right away.
|
||||
|
|
|
@ -144,6 +144,9 @@ namespace Socket{
|
|||
void open(std::string hostname, int port, bool nonblock, bool with_ssl = false); // Open TCP connection.
|
||||
void open(std::string adres, bool nonblock = false); // Open Unix connection.
|
||||
void open(int write, int read); // Open from two existing file descriptors.
|
||||
#ifdef SSL
|
||||
bool sslAccept(mbedtls_ssl_config * sslConf, mbedtls_ctr_drbg_context * dbgCtx);
|
||||
#endif
|
||||
void close(); ///< Close connection.
|
||||
void drop(); ///< Close connection without shutdown.
|
||||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||
|
|
|
@ -21,7 +21,19 @@ const char * trackType(char ID){
|
|||
|
||||
|
||||
namespace Mist{
|
||||
#ifdef SSL
|
||||
bool sslEnabled = false;
|
||||
mbedtls_entropy_context OutRTMP::entropy;
|
||||
mbedtls_ctr_drbg_context OutRTMP::ctr_drbg;
|
||||
mbedtls_ssl_config OutRTMP::sslConf;
|
||||
mbedtls_x509_crt OutRTMP::srvcert;
|
||||
mbedtls_pk_context OutRTMP::pkey;
|
||||
#endif
|
||||
|
||||
OutRTMP::OutRTMP(Socket::Connection &conn) : Output(conn){
|
||||
#ifdef SSL
|
||||
if (sslEnabled){myConn.sslAccept(&sslConf, &ctr_drbg);}
|
||||
#endif
|
||||
lastSilence = 0;
|
||||
hasSilence = false;
|
||||
lastAudioInserted = 0;
|
||||
|
@ -90,6 +102,74 @@ namespace Mist{
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SSL
|
||||
/// Listens for HTTPS requests, accepting them and connecting them to a HTTP socket
|
||||
void OutRTMP::listener(Util::Config &conf, int (*callback)(Socket::Connection &S)){
|
||||
// No cert or key? Non-SSL mode.
|
||||
if (config->getOption("cert", true).size() < 2 || config->getOption("key", true).size() < 2){
|
||||
INFO_MSG("No cert or key set, regular RTMP mode");
|
||||
Output::listener(conf, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_MSG("Cert and key set, RTMPS mode");
|
||||
sslEnabled = true;
|
||||
|
||||
// Declare and set up all required mbedtls structures
|
||||
int ret;
|
||||
mbedtls_ssl_config_init(&sslConf);
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_pk_init(&pkey);
|
||||
mbedtls_x509_crt_init(&srvcert);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
// seed the rng
|
||||
if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
||||
(const unsigned char *)APPNAME, strlen(APPNAME))) != 0){
|
||||
FAIL_MSG("Could not seed the random number generator!");
|
||||
}
|
||||
|
||||
// Read certificate chain(s) from cmdline option(s)
|
||||
JSON::Value certs = config->getOption("cert", true);
|
||||
jsonForEach(certs, it){
|
||||
if (it->asStringRef().size()){// Ignore empty entries (default is empty)
|
||||
ret = mbedtls_x509_crt_parse_file(&srvcert, it->asStringRef().c_str());
|
||||
if (ret != 0){
|
||||
WARN_MSG("Could not load any certificates from file: %s", it->asStringRef().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read key from cmdline option
|
||||
ret = mbedtls_pk_parse_keyfile(&pkey, config->getString("key").c_str(), 0);
|
||||
if (ret != 0){
|
||||
FAIL_MSG("Could not load any keys from file: %s", config->getString("key").c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = mbedtls_ssl_config_defaults(&sslConf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0){
|
||||
FAIL_MSG("SSL config defaults failed");
|
||||
return;
|
||||
}
|
||||
mbedtls_ssl_conf_rng(&sslConf, mbedtls_ctr_drbg_random, &ctr_drbg);
|
||||
mbedtls_ssl_conf_ca_chain(&sslConf, srvcert.next, NULL);
|
||||
if ((ret = mbedtls_ssl_conf_own_cert(&sslConf, &srvcert, &pkey)) != 0){
|
||||
FAIL_MSG("SSL config own certificate failed");
|
||||
return;
|
||||
}
|
||||
|
||||
Output::listener(conf, callback);
|
||||
|
||||
// Free all the mbedtls structures
|
||||
mbedtls_x509_crt_free(&srvcert);
|
||||
mbedtls_pk_free(&pkey);
|
||||
mbedtls_ssl_config_free(&sslConf);
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
}
|
||||
#endif
|
||||
|
||||
void OutRTMP::startPushOut(const char *args){
|
||||
|
||||
myConn.close();
|
||||
|
@ -277,6 +357,22 @@ namespace Mist{
|
|||
capa["optional"]["maxkbps"]["short"] = "K";
|
||||
capa["optional"]["maxkbps"]["default"] = 0;
|
||||
capa["optional"]["maxkbps"]["type"] = "uint";
|
||||
|
||||
#ifdef SSL
|
||||
capa["optional"]["cert"]["name"] = "Certificate";
|
||||
capa["optional"]["cert"]["help"] = "(Root) certificate(s) file(s) to append to chain";
|
||||
capa["optional"]["cert"]["option"] = "--cert";
|
||||
capa["optional"]["cert"]["short"] = "C";
|
||||
capa["optional"]["cert"]["default"] = "";
|
||||
capa["optional"]["cert"]["type"] = "str";
|
||||
capa["optional"]["key"]["name"] = "Key";
|
||||
capa["optional"]["key"]["help"] = "Private key for SSL";
|
||||
capa["optional"]["key"]["option"] = "--key";
|
||||
capa["optional"]["key"]["short"] = "k";
|
||||
capa["optional"]["key"]["default"] = "";
|
||||
capa["optional"]["key"]["type"] = "str";
|
||||
#endif
|
||||
|
||||
cfg->addConnectorOptions(1935, capa);
|
||||
config = cfg;
|
||||
config->addStandardPushCapabilities(capa);
|
||||
|
|
|
@ -19,6 +19,9 @@ namespace Mist{
|
|||
static bool listenMode();
|
||||
void requestHandler();
|
||||
bool onFinish();
|
||||
#ifdef SSL
|
||||
static void listener(Util::Config &conf, int (*callback)(Socket::Connection &S));
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::string streamOut; ///< When pushing out, the output stream name
|
||||
|
@ -52,6 +55,15 @@ namespace Mist{
|
|||
void sendLoopedAudio(uint64_t untilTimestamp);
|
||||
// Gets the next ADTS frame in AAC file. Loops if EOF reached
|
||||
void calcNextFrameInfo();
|
||||
|
||||
#ifdef SSL
|
||||
// TLS-related
|
||||
static mbedtls_entropy_context entropy;
|
||||
static mbedtls_ctr_drbg_context ctr_drbg;
|
||||
static mbedtls_ssl_config sslConf;
|
||||
static mbedtls_x509_crt srvcert;
|
||||
static mbedtls_pk_context pkey;
|
||||
#endif
|
||||
};
|
||||
}// namespace Mist
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue