[rtmpdump] branch master updated. 002ef6f Support rtmps in rtmpsrv
gitolite
gil at avcodec.org
Tue Oct 30 16:59:57 CET 2012
The branch, master has been updated
via 002ef6f6be2bbdf852ff64ab6981d709435a9045 (commit)
via 6df3b1f2015f928d74a675bda542c354b893c2c2 (commit)
via f14b6ac18d779cfb1431c59344bd59a0b0445e08 (commit)
via d70c3f677d3d80763adf54c4e1329c57ed8af3ba (commit)
from 294135e6eafeb1ac338ac4bb11ebd5ef62c748b9 (commit)
- Log -----------------------------------------------------------------
commit 002ef6f6be2bbdf852ff64ab6981d709435a9045
Author: Martin Storsjo <martin at martin.st>
AuthorDate: Sun May 20 23:37:35 2012 +0300
Commit: Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 08:58:36 2012 -0700
Support rtmps in rtmpsrv
diff --git a/rtmpsrv.c b/rtmpsrv.c
index fc727bc..a9e9045 100644
--- a/rtmpsrv.c
+++ b/rtmpsrv.c
@@ -92,6 +92,7 @@ typedef struct
} STREAMING_SERVER;
STREAMING_SERVER *rtmpServer = 0; // server structure pointer
+void *sslCtx = NULL;
STREAMING_SERVER *startStreaming(const char *address, int port);
void stopStreaming(STREAMING_SERVER * server);
@@ -897,6 +898,11 @@ void doServe(STREAMING_SERVER * server, // server socket and state (our listenin
{
RTMP_Init(rtmp);
rtmp->m_sb.sb_socket = sockfd;
+ if (sslCtx && !RTMP_TLS_Accept(rtmp, sslCtx))
+ {
+ RTMP_Log(RTMP_LOGERROR, "TLS handshake failed");
+ goto cleanup;
+ }
if (!RTMP_Serve(rtmp))
{
RTMP_Log(RTMP_LOGERROR, "Handshake failed");
@@ -1061,20 +1067,32 @@ int
main(int argc, char **argv)
{
int nStatus = RD_SUCCESS;
+ int i;
// http streaming server
char DEFAULT_HTTP_STREAMING_DEVICE[] = "0.0.0.0"; // 0.0.0.0 is any device
char *rtmpStreamingDevice = DEFAULT_HTTP_STREAMING_DEVICE; // streaming device, default 0.0.0.0
int nRtmpStreamingPort = 1935; // port
+ char *cert = NULL, *key = NULL;
RTMP_LogPrintf("RTMP Server %s\n", RTMPDUMP_VERSION);
RTMP_LogPrintf("(c) 2010 Andrej Stepanchuk, Howard Chu; license: GPL\n\n");
RTMP_debuglevel = RTMP_LOGINFO;
- if (argc > 1 && !strcmp(argv[1], "-z"))
- RTMP_debuglevel = RTMP_LOGALL;
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp(argv[i], "-z"))
+ RTMP_debuglevel = RTMP_LOGALL;
+ else if (!strcmp(argv[i], "-c") && i + 1 < argc)
+ cert = argv[++i];
+ else if (!strcmp(argv[i], "-k") && i + 1 < argc)
+ key = argv[++i];
+ }
+
+ if (cert && key)
+ sslCtx = RTMP_TLS_AllocServerContext(cert, key);
// init request
memset(&defaultRTMPRequest, 0, sizeof(RTMP_REQUEST));
@@ -1118,6 +1136,9 @@ main(int argc, char **argv)
}
RTMP_Log(RTMP_LOGDEBUG, "Done, exiting...");
+ if (sslCtx)
+ RTMP_TLS_FreeServerContext(sslCtx);
+
CleanupSockets();
#ifdef _DEBUG
commit 6df3b1f2015f928d74a675bda542c354b893c2c2
Author: Martin Storsjo <martin at martin.st>
AuthorDate: Tue Oct 30 08:57:43 2012 -0700
Commit: Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 08:57:43 2012 -0700
Add functions for doing server side TLS initialization
diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 682e3b8..cba8b6c 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -35,6 +35,19 @@
#ifdef USE_POLARSSL
#include <polarssl/version.h>
#include <polarssl/havege.h>
+
+static const char *my_dhm_P =
+ "E4004C1F94182000103D883A448B3F80" \
+ "2CE4B44A83301270002C20D0321CFD00" \
+ "11CCEF784C26A400F43DFB901BCA7538" \
+ "F2C6B176001CF5A0FD16D2C48B1D0C1C" \
+ "F6AC8E1DA6BCC3B4E1F96B0564965300" \
+ "FFA1D0B601EB2800F489AA512C4B248C" \
+ "01F76949A60BB7F00A40B1EAB64BDD48" \
+ "E8A700D60B7F1200FA8E77B0A979DABF";
+
+static const char *my_dhm_G = "4";
+
#elif defined(USE_GNUTLS)
#include <gnutls/gnutls.h>
#else /* USE_OPENSSL */
@@ -228,6 +241,82 @@ RTMP_TLS_Init()
#endif
}
+void *
+RTMP_TLS_AllocServerContext(const char* cert, const char* key)
+{
+ void *ctx = NULL;
+#ifdef CRYPTO
+ if (!RTMP_TLS_ctx)
+ RTMP_TLS_Init();
+#ifdef 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());
+ FILE *f = fopen(key, "r");
+ if (!f) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ EVP_PKEY *k = PEM_read_PrivateKey(f, NULL, NULL, NULL);
+ fclose(f);
+ if (!k) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ SSL_CTX_use_PrivateKey(ctx, k);
+ EVP_PKEY_free(k);
+ f = fopen(cert, "r");
+ if (!f) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ X509 *c = PEM_read_X509(f, NULL, NULL, NULL);
+ fclose(f);
+ if (!c) {
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ SSL_CTX_use_certificate(ctx, c);
+ X509_free(c);
+#endif
+#endif
+ return ctx;
+}
+
+void
+RTMP_TLS_FreeServerContext(void *ctx)
+{
+#ifdef CRYPTO
+#ifdef 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
+#endif
+}
+
RTMP *
RTMP_Alloc()
{
@@ -868,6 +957,23 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service)
}
int
+RTMP_TLS_Accept(RTMP *r, void *ctx)
+{
+#if defined(CRYPTO) && !defined(NO_SSL)
+ TLS_server(ctx, r->m_sb.sb_ssl);
+ TLS_setfd(r->m_sb.sb_ssl, r->m_sb.sb_socket);
+ if (TLS_accept(r->m_sb.sb_ssl) < 0)
+ {
+ RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+int
RTMP_Connect1(RTMP *r, RTMPPacket *cp)
{
if (r->Link.protocol & RTMP_FEATURE_SSL)
diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
index 6b2ae5b..76e01fd 100644
--- a/librtmp/rtmp.h
+++ b/librtmp/rtmp.h
@@ -307,6 +307,7 @@ extern "C"
int RTMP_Connect0(RTMP *r, struct sockaddr *svc);
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);
@@ -329,6 +330,9 @@ extern "C"
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 */
diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
index 1bf0735..2cdb705 100644
--- a/librtmp/rtmp_sys.h
+++ b/librtmp/rtmp_sys.h
@@ -72,14 +72,30 @@ 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_rand, ((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)
@@ -93,8 +109,10 @@ typedef struct tls_ctx {
} 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)
@@ -103,8 +121,10 @@ typedef struct tls_ctx {
#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)
commit f14b6ac18d779cfb1431c59344bd59a0b0445e08
Author: Martin Storsjo <martin at martin.st>
AuthorDate: Sun May 20 23:36:58 2012 +0300
Commit: Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 08:54:25 2012 -0700
Replace hardcoded constants and comments with proper named constants
diff --git a/rtmpsrv.c b/rtmpsrv.c
index 956abab..fc727bc 100644
--- a/rtmpsrv.c
+++ b/rtmpsrv.c
@@ -767,47 +767,40 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
switch (packet->m_packetType)
{
- case 0x01:
- // chunk size
+ case RTMP_PACKET_TYPE_CHUNK_SIZE:
// HandleChangeChunkSize(r, packet);
break;
- case 0x03:
- // bytes read report
+ case RTMP_PACKET_TYPE_BYTES_READ_REPORT:
break;
- case 0x04:
- // ctrl
+ case RTMP_PACKET_TYPE_CONTROL:
// HandleCtrl(r, packet);
break;
- case 0x05:
- // server bw
+ case RTMP_PACKET_TYPE_SERVER_BW:
// HandleServerBW(r, packet);
break;
- case 0x06:
- // client bw
+ case RTMP_PACKET_TYPE_CLIENT_BW:
// HandleClientBW(r, packet);
break;
- case 0x08:
- // audio data
+ case RTMP_PACKET_TYPE_AUDIO:
//RTMP_Log(RTMP_LOGDEBUG, "%s, received: audio %lu bytes", __FUNCTION__, packet.m_nBodySize);
break;
- case 0x09:
- // video data
+ case RTMP_PACKET_TYPE_VIDEO:
//RTMP_Log(RTMP_LOGDEBUG, "%s, received: video %lu bytes", __FUNCTION__, packet.m_nBodySize);
break;
- case 0x0F: // flex stream send
+ case RTMP_PACKET_TYPE_FLEX_STREAM_SEND:
break;
- case 0x10: // flex shared object
+ case RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT:
break;
- case 0x11: // flex message
+ case RTMP_PACKET_TYPE_FLEX_MESSAGE:
{
RTMP_Log(RTMP_LOGDEBUG, "%s, flex message, size %u bytes, not fully supported",
__FUNCTION__, packet->m_nBodySize);
@@ -827,16 +820,13 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
RTMP_Close(r);
break;
}
- case 0x12:
- // metadata (notify)
+ case RTMP_PACKET_TYPE_INFO:
break;
- case 0x13:
- /* shared object */
+ case RTMP_PACKET_TYPE_SHARED_OBJECT:
break;
- case 0x14:
- // invoke
+ case RTMP_PACKET_TYPE_INVOKE:
RTMP_Log(RTMP_LOGDEBUG, "%s, received: invoke %u bytes", __FUNCTION__,
packet->m_nBodySize);
//RTMP_LogHex(packet.m_body, packet.m_nBodySize);
@@ -845,8 +835,7 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
RTMP_Close(r);
break;
- case 0x16:
- /* flv */
+ case RTMP_PACKET_TYPE_FLASH_VIDEO:
break;
default:
RTMP_Log(RTMP_LOGDEBUG, "%s, unknown packet type received: 0x%02x", __FUNCTION__,
commit d70c3f677d3d80763adf54c4e1329c57ed8af3ba
Author: Martin Storsjo <martin at martin.st>
AuthorDate: Sun May 20 23:36:57 2012 +0300
Commit: Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 08:53:51 2012 -0700
Allocate the RTMP struct dynamically
This struct is over 1 MB in size, and doesn't fit on the stack
on OS X.
diff --git a/rtmpsrv.c b/rtmpsrv.c
index 9aa62f3..956abab 100644
--- a/rtmpsrv.c
+++ b/rtmpsrv.c
@@ -886,7 +886,7 @@ void doServe(STREAMING_SERVER * server, // server socket and state (our listenin
{
server->state = STREAMING_IN_PROGRESS;
- RTMP rtmp = { 0 }; /* our session with the real client */
+ RTMP *rtmp = RTMP_Alloc(); /* our session with the real client */
RTMPPacket packet = { 0 };
// timeout for http requests
@@ -906,38 +906,39 @@ void doServe(STREAMING_SERVER * server, // server socket and state (our listenin
}
else
{
- RTMP_Init(&rtmp);
- rtmp.m_sb.sb_socket = sockfd;
- if (!RTMP_Serve(&rtmp))
+ RTMP_Init(rtmp);
+ rtmp->m_sb.sb_socket = sockfd;
+ if (!RTMP_Serve(rtmp))
{
RTMP_Log(RTMP_LOGERROR, "Handshake failed");
goto cleanup;
}
}
server->arglen = 0;
- while (RTMP_IsConnected(&rtmp) && RTMP_ReadPacket(&rtmp, &packet))
+ while (RTMP_IsConnected(rtmp) && RTMP_ReadPacket(rtmp, &packet))
{
if (!RTMPPacket_IsReady(&packet))
continue;
- ServePacket(server, &rtmp, &packet);
+ ServePacket(server, rtmp, &packet);
RTMPPacket_Free(&packet);
}
cleanup:
RTMP_LogPrintf("Closing connection... ");
- RTMP_Close(&rtmp);
+ RTMP_Close(rtmp);
/* Should probably be done by RTMP_Close() ... */
- rtmp.Link.playpath.av_val = NULL;
- rtmp.Link.tcUrl.av_val = NULL;
- rtmp.Link.swfUrl.av_val = NULL;
- rtmp.Link.pageUrl.av_val = NULL;
- rtmp.Link.app.av_val = NULL;
- rtmp.Link.flashVer.av_val = NULL;
- if (rtmp.Link.usherToken.av_val)
+ rtmp->Link.playpath.av_val = NULL;
+ rtmp->Link.tcUrl.av_val = NULL;
+ rtmp->Link.swfUrl.av_val = NULL;
+ rtmp->Link.pageUrl.av_val = NULL;
+ rtmp->Link.app.av_val = NULL;
+ rtmp->Link.flashVer.av_val = NULL;
+ if (rtmp->Link.usherToken.av_val)
{
- free(rtmp.Link.usherToken.av_val);
- rtmp.Link.usherToken.av_val = NULL;
+ free(rtmp->Link.usherToken.av_val);
+ rtmp->Link.usherToken.av_val = NULL;
}
+ RTMP_Free(rtmp);
RTMP_LogPrintf("done!\n\n");
quit:
-----------------------------------------------------------------------
Summary of changes:
librtmp/rtmp.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++
librtmp/rtmp.h | 4 ++
librtmp/rtmp_sys.h | 20 ++++++++++
rtmpsrv.c | 97 ++++++++++++++++++++++++++---------------------
4 files changed, 184 insertions(+), 43 deletions(-)
hooks/post-receive
--
More information about the rtmpdump
mailing list