[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