summaryrefslogtreecommitdiffstats
path: root/src/librtmp-2-master.patch
diff options
context:
space:
mode:
Diffstat (limited to 'src/librtmp-2-master.patch')
-rw-r--r--src/librtmp-2-master.patch5371
1 files changed, 0 insertions, 5371 deletions
diff --git a/src/librtmp-2-master.patch b/src/librtmp-2-master.patch
deleted file mode 100644
index 19ec2e5..0000000
--- a/src/librtmp-2-master.patch
+++ /dev/null
@@ -1,5371 +0,0 @@
-This file is part of MXE.
-See index.html for further information.
-
-From dc762e41a090b5c238bd7daedab13def69eb140b Mon Sep 17 00:00:00 2001
-From: toine512 <toine512@gmail.com>
-Date: Thu, 21 Jul 2011 17:10:13 -0700
-Subject: [PATCH 01/64] Squashed commit of the following:
-
-commit 84b160fdc8e6aaff9b5b214d90e8f002cc4185dd
-Author: toine512 <toine512@gmail.com>
-Date: Wed Jul 20 23:09:26 2011 +0200
-
- Updates man .. again
-
-commit 717c562b844595f5b24da268a5f5203d921ebc89
-Author: toine512 <toine512@gmail.com>
-Date: Wed Jul 20 21:00:44 2011 +0200
-
- More updates in man files, regenerating HTML files needed
-
-commit 8196cf03b2ff7b9483166302bf79a0760fed2772
-Author: toine512 <toine512@gmail.com>
-Date: Wed Jul 20 20:42:41 2011 +0200
-
- Updates ChangeLog
-
-commit 7a6931cffd0ffd2d0997ffed2bd7609e9a043387
-Author: toine512 <toine512@gmail.com>
-Date: Wed Jul 20 20:37:40 2011 +0200
-
- Updates man files, regenerating HTML files is needed
-
-commit 1cb67af20bb4085b87123299956c6b4d2d2b1484
-Author: toine512 <toine512@gmail.com>
-Date: Wed Jul 20 20:03:16 2011 +0200
-
- Implements Justin.tv support (NetStream.Authenticate.UsherToken)
-
-diff --git a/ChangeLog b/ChangeLog
-index fb2319f..c3b1a14 100644
---- a/ChangeLog
-+++ b/ChangeLog
-@@ -4,6 +4,9 @@ Copyright 2009-2011 Howard Chu
- Copyright 2009 The Flvstreamer Team
- http://rtmpdump.mplayerhq.hu/
-
-+20 July 2011
-+- add NetStream.Authenticate.UsherToken for Justin.tv
-+
- 11 July 2011, v2.4
- - add RTMPE type 9 handshake support
-
-diff --git a/librtmp/librtmp.3 b/librtmp/librtmp.3
-index 66197d5..7c424aa 100644
---- a/librtmp/librtmp.3
-+++ b/librtmp/librtmp.3
-@@ -1,5 +1,5 @@
--.TH LIBRTMP 3 "2010-07-03" "RTMPDump v2.3"
--.\" Copyright 2010 Howard Chu.
-+.TH LIBRTMP 3 "2011-07-20" "RTMPDump v2.4"
-+.\" Copyright 2011 Howard Chu.
- .\" Copying permitted according to the GNU General Public License V2.
- .SH NAME
- librtmp \- RTMPDump Real-Time Messaging Protocol API
-@@ -161,6 +161,9 @@ These options handle additional authentication requests from the server.
- Key for SecureToken response, used if the server requires SecureToken
- authentication.
- .TP
-+.BI jtv= JSON
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+.TP
- .BI swfVfy= 0|1
- If the value is 1 or TRUE, the SWF player is retrieved from the
- specified
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 5ef3ae9..adcff1f 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -96,6 +96,7 @@ static int SendDeleteStream(RTMP *r, double dStreamId);
- static int SendFCSubscribe(RTMP *r, AVal *subscribepath);
- static int SendPlay(RTMP *r);
- static int SendBytesReceived(RTMP *r);
-+static int SendUsherToken(RTMP *r, AVal *usherToken);
-
- #if 0 /* unused */
- static int SendBGHasStream(RTMP *r, double dId, AVal *playpath);
-@@ -335,6 +336,7 @@ RTMP_SetupStream(RTMP *r,
- uint32_t swfSize,
- AVal *flashVer,
- AVal *subscribepath,
-+ AVal *usherToken,
- int dStart,
- int dStop, int bLiveStream, long int timeout)
- {
-@@ -355,6 +357,8 @@ RTMP_SetupStream(RTMP *r,
- RTMP_Log(RTMP_LOGDEBUG, "auth : %s", auth->av_val);
- if (subscribepath && subscribepath->av_val)
- RTMP_Log(RTMP_LOGDEBUG, "subscribepath : %s", subscribepath->av_val);
-+ if (usherToken && usherToken->av_val)
-+ RTMP_Log(RTMP_LOGDEBUG, "NetStream.Authenticate.UsherToken : %s", usherToken->av_val);
- if (flashVer && flashVer->av_val)
- RTMP_Log(RTMP_LOGDEBUG, "flashVer : %s", flashVer->av_val);
- if (dStart > 0)
-@@ -420,6 +424,8 @@ RTMP_SetupStream(RTMP *r,
- r->Link.flashVer = RTMP_DefaultFlashVer;
- if (subscribepath && subscribepath->av_len)
- r->Link.subscribepath = *subscribepath;
-+ if (usherToken && usherToken->av_len)
-+ r->Link.usherToken = *usherToken;
- r->Link.seekTime = dStart;
- r->Link.stopTime = dStop;
- if (bLiveStream)
-@@ -477,6 +483,8 @@ static struct urlopt {
- "Stream is live, no seeking possible" },
- { AVC("subscribe"), OFF(Link.subscribepath), OPT_STR, 0,
- "Stream to subscribe to" },
-+ { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0,
-+ "Justin.tv authentication token" },
- { AVC("token"), OFF(Link.token), OPT_STR, 0,
- "Key for SecureToken response" },
- { AVC("swfVfy"), OFF(Link.lFlags), OPT_BOOL, RTMP_LF_SWFV,
-@@ -1641,6 +1649,39 @@ SendFCSubscribe(RTMP *r, AVal *subscribepath)
- return RTMP_SendPacket(r, &packet, TRUE);
- }
-
-+//Justin.tv specific authentication
-+static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken"); //SAVC() isn't suitable for that
-+
-+static int
-+SendUsherToken(RTMP *r, AVal *usherToken)
-+{
-+ RTMPPacket packet;
-+ char pbuf[1024], *pend = pbuf + sizeof(pbuf);
-+ char *enc;
-+ packet.m_nChannel = 0x03; /* control channel (invoke) */
-+ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
-+ packet.m_packetType = RTMP_PACKET_TYPE_INVOKE;
-+ packet.m_nTimeStamp = 0;
-+ packet.m_nInfoField2 = 0;
-+ packet.m_hasAbsTimestamp = 0;
-+ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "UsherToken: %s", usherToken->av_val);
-+ enc = packet.m_body;
-+ enc = AMF_EncodeString(enc, pend, &av_NetStream_Authenticate_UsherToken);
-+ enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);
-+ *enc++ = AMF_NULL;
-+ enc = AMF_EncodeString(enc, pend, usherToken);
-+
-+ if (!enc)
-+ return FALSE;
-+
-+ packet.m_nBodySize = enc - packet.m_body;
-+
-+ return RTMP_SendPacket(r, &packet, FALSE);
-+}
-+/******************************************/
-+
- SAVC(releaseStream);
-
- static int
-@@ -2364,6 +2405,9 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
-
- if (!(r->Link.protocol & RTMP_FEATURE_WRITE))
- {
-+ /* Authenticate on Justin.tv legacy servers before sending FCSubscribe */
-+ if (r->Link.usherToken.av_len)
-+ SendUsherToken(r, &r->Link.usherToken);
- /* Send the FCSubscribe if live stream or if subscribepath is set */
- if (r->Link.subscribepath.av_len)
- SendFCSubscribe(r, &r->Link.subscribepath);
-diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
-index 1ece207..6b2ae5b 100644
---- a/librtmp/rtmp.h
-+++ b/librtmp/rtmp.h
-@@ -155,6 +155,7 @@ extern "C"
- AVal auth;
- AVal flashVer;
- AVal subscribepath;
-+ AVal usherToken;
- AVal token;
- AMFObject extras;
- int edepth;
-@@ -297,6 +298,7 @@ extern "C"
- uint32_t swfSize,
- AVal *flashVer,
- AVal *subscribepath,
-+ AVal *usherToken,
- int dStart,
- int dStop, int bLiveStream, long int timeout);
-
-diff --git a/rtmpdump.1 b/rtmpdump.1
-index 2395de9..0d9de8d 100644
---- a/rtmpdump.1
-+++ b/rtmpdump.1
-@@ -1,5 +1,5 @@
--.TH RTMPDUMP 1 "2010-05-02" "RTMPDump v2.2e"
--.\" Copyright 2010 Howard Chu.
-+.TH RTMPDUMP 1 "2011-07-20" "RTMPDump v2.4"
-+.\" Copyright 2011 Howard Chu.
- .\" Copying permitted according to the GNU General Public License V2.
- .SH NAME
- rtmpdump \- RTMP streaming media client
-@@ -51,6 +51,8 @@ rtmpdump \- RTMP streaming media client
- [\c
- .BI \-T \ key\fR]
- [\c
-+.BI \-j \ JSON\fR]
-+[\c
- .BI \-w \ swfHash\fR]
- [\c
- .BI \-x \ swfSize\fR]
-@@ -210,6 +212,9 @@ These options handle additional authentication requests from the server.
- Key for SecureToken response, used if the server requires SecureToken
- authentication.
- .TP
-+\fB\-\-jtv \-j\fP\ \fIJSON\fP
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+.TP
- \fB\-\-swfhash \-w\fP\ \fIhexstring\fP
- SHA256 hash of the decompressed SWF file. This option may be needed if
- the server uses SWF Verification, but see the
-diff --git a/rtmpdump.c b/rtmpdump.c
-index c1cd95b..ec1de85 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -692,6 +692,8 @@ void usage(char *prog)
- RTMP_LogPrintf
- ("--token|-T key Key for SecureToken response\n");
- RTMP_LogPrintf
-+ ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
-+ RTMP_LogPrintf
- ("--hashes|-# Display progress with hashes, not with the byte counter\n");
- RTMP_LogPrintf
- ("--buffer|-b Buffer time in milliseconds (default: %lu)\n",
-@@ -738,6 +740,7 @@ main(int argc, char **argv)
- AVal hostname = { 0, 0 };
- AVal playpath = { 0, 0 };
- AVal subscribepath = { 0, 0 };
-+ AVal usherToken = { 0, 0 }; //Justin.tv auth token
- int port = -1;
- int protocol = RTMP_PROTOCOL_UNDEFINED;
- int retries = 0;
-@@ -839,12 +842,13 @@ main(int argc, char **argv)
- {"debug", 0, NULL, 'z'},
- {"quiet", 0, NULL, 'q'},
- {"verbose", 0, NULL, 'V'},
-+ {"jtv", 1, NULL, 'j'},
- {0, 0, 0, 0}
- };
-
- while ((opt =
- getopt_long(argc, argv,
-- "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#",
-+ "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
- longopts, NULL)) != -1)
- {
- switch (opt)
-@@ -1051,6 +1055,9 @@ main(int argc, char **argv)
- case 'S':
- STR2AVAL(sockshost, optarg);
- break;
-+ case 'j':
-+ STR2AVAL(usherToken, optarg);
-+ break;
- default:
- RTMP_LogPrintf("unknown option: %c\n", opt);
- usage(argv[0]);
-@@ -1167,7 +1174,7 @@ main(int argc, char **argv)
-
- RTMP_SetupStream(&rtmp, protocol, &hostname, port, &sockshost, &playpath,
- &tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize,
-- &flashVer, &subscribepath, dSeek, dStopOffset, bLiveStream, timeout);
-+ &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout);
-
- /* Try to keep the stream moving if it pauses on us */
- if (!bLiveStream && !(protocol & RTMP_FEATURE_HTTP))
-diff --git a/rtmpgw.8 b/rtmpgw.8
-index 197a2d6..0a231b4 100644
---- a/rtmpgw.8
-+++ b/rtmpgw.8
-@@ -1,5 +1,5 @@
--.TH RTMPGW 8 "2010-05-02" "RTMPDump v2.2e"
--.\" Copyright 2010 Howard Chu.
-+.TH RTMPGW 8 "2011-07-20" "RTMPDump v2.4"
-+.\" Copyright 2011 Howard Chu.
- .\" Copying permitted according to the GNU General Public License V2.
- .SH NAME
- rtmpgw \- RTMP streaming media gateway
-@@ -50,6 +50,8 @@ rtmpgw \- RTMP streaming media gateway
- [\c
- .BI \-T \ key\fR]
- [\c
-+.BI \-j \ JSON\fR]
-+[\c
- .BI \-w \ swfHash\fR]
- [\c
- .BI \-x \ swfSize\fR]
-@@ -193,6 +195,9 @@ These options handle additional authentication requests from the server.
- Key for SecureToken response, used if the server requires SecureToken
- authentication.
- .TP
-+\fB\-\-jtv \-j\fP\ \fIJSON\fP
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+.TP
- \fB\-\-swfhash \-w\fP\ \fIhexstring\fP
- SHA256 hash of the decompressed SWF file. This option may be needed if
- the server uses SWF Verification, but see the
-diff --git a/rtmpgw.c b/rtmpgw.c
-index 10a99e8..ce7319a 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -95,6 +95,7 @@ typedef struct
- AVal flashVer;
- AVal token;
- AVal subscribepath;
-+ AVal usherToken; //Justin.tv auth token
- AVal sockshost;
- AMFObject extras;
- int edepth;
-@@ -552,7 +553,7 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- RTMP_Init(&rtmp);
- RTMP_SetBufferMS(&rtmp, req.bufferTime);
- RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost,
-- &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, dSeek, req.dStopOffset,
-+ &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, dSeek, req.dStopOffset,
- req.bLiveStream, req.timeout);
- /* backward compatibility, we always sent this as true before */
- if (req.auth.av_len)
-@@ -953,6 +954,9 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
- case 'z':
- RTMP_debuglevel = RTMP_LOGALL;
- break;
-+ case 'j':
-+ STR2AVAL(req->usherToken, arg);
-+ break;
- default:
- RTMP_LogPrintf("unknown option: %c, arg: %s\n", opt, arg);
- return FALSE;
-@@ -1023,6 +1027,7 @@ main(int argc, char **argv)
- {"debug", 0, NULL, 'z'},
- {"quiet", 0, NULL, 'q'},
- {"verbose", 0, NULL, 'V'},
-+ {"jtv", 1, NULL, 'j'},
- {0, 0, 0, 0}
- };
-
-@@ -1035,7 +1040,7 @@ main(int argc, char **argv)
-
- while ((opt =
- getopt_long(argc, argv,
-- "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:", longopts,
-+ "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:", longopts,
- NULL)) != -1)
- {
- switch (opt)
-@@ -1095,6 +1100,8 @@ main(int argc, char **argv)
- ("--stop|-B num Stop at num seconds into stream\n");
- RTMP_LogPrintf
- ("--token|-T key Key for SecureToken response\n");
-+ RTMP_LogPrintf
-+ ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
- RTMP_LogPrintf
- ("--buffer|-b Buffer time in milliseconds (default: %lu)\n\n",
- defaultRTMPRequest.bufferTime);
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index f1b6c66..cf52bfa 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -116,6 +116,7 @@ typedef struct
- AVal swfHash;
- AVal flashVer;
- AVal subscribepath;
-+ AVal usherToken;
- uint32_t swfSize;
-
- uint32_t dStartOffset;
---
-1.7.10.4
-
-
-From a2fb387404cb0da99cf439d58478fff701398700 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Thu, 21 Jul 2011 17:31:14 -0700
-Subject: [PATCH 02/64] Regenerate HTML docs, minor tweaks
-
-
-diff --git a/librtmp/librtmp.3.html b/librtmp/librtmp.3.html
-index e5e6f4b..6f59851 100644
---- a/librtmp/librtmp.3.html
-+++ b/librtmp/librtmp.3.html
-@@ -6,10 +6,10 @@
- <tr><td>LIBRTMP(3)<td align="center"><td align="right">LIBRTMP(3)
- </thead>
- <tfoot>
--<tr><td>RTMPDump v2.3<td align="center">2010-07-03<td align="right">LIBRTMP(3)
-+<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">LIBRTMP(3)
- </tfoot>
- <tbody><tr><td colspan="3"><br><br><ul>
--<!-- Copyright 2010 Howard Chu.
-+<!-- Copyright 2011 Howard Chu.
- Copying permitted according to the GNU General Public License V2.-->
- </ul>
-
-@@ -238,6 +238,12 @@ authentication.
- </dl>
- <p>
- <dl compact><dt>
-+<b>jtv=</b><i>JSON</i>
-+<dd>
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+</dl>
-+<p>
-+<dl compact><dt>
- <b>swfVfy=</b><i>0|1</i>
- <dd>
- If the value is 1 or TRUE, the SWF player is retrieved from the
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index adcff1f..8d76164 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -484,7 +484,7 @@ static struct urlopt {
- { AVC("subscribe"), OFF(Link.subscribepath), OPT_STR, 0,
- "Stream to subscribe to" },
- { AVC("jtv"), OFF(Link.usherToken), OPT_STR, 0,
-- "Justin.tv authentication token" },
-+ "Justin.tv authentication token" },
- { AVC("token"), OFF(Link.token), OPT_STR, 0,
- "Key for SecureToken response" },
- { AVC("swfVfy"), OFF(Link.lFlags), OPT_BOOL, RTMP_LF_SWFV,
-@@ -1649,8 +1649,8 @@ SendFCSubscribe(RTMP *r, AVal *subscribepath)
- return RTMP_SendPacket(r, &packet, TRUE);
- }
-
--//Justin.tv specific authentication
--static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken"); //SAVC() isn't suitable for that
-+/* Justin.tv specific authentication */
-+static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken");
-
- static int
- SendUsherToken(RTMP *r, AVal *usherToken)
-diff --git a/rtmpdump.1.html b/rtmpdump.1.html
-index 7f17636..826f722 100644
---- a/rtmpdump.1.html
-+++ b/rtmpdump.1.html
-@@ -6,10 +6,10 @@
- <tr><td>RTMPDUMP(1)<td align="center"><td align="right">RTMPDUMP(1)
- </thead>
- <tfoot>
--<tr><td>RTMPDump v2.2e<td align="center">2010-05-02<td align="right">RTMPDUMP(1)
-+<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">RTMPDUMP(1)
- </tfoot>
- <tbody><tr><td colspan="3"><br><br><ul>
--<!-- Copyright 2010 Howard Chu.
-+<!-- Copyright 2011 Howard Chu.
- Copying permitted according to the GNU General Public License V2.-->
- </ul>
-
-@@ -42,6 +42,7 @@ rtmpdump &minus; RTMP streaming media client
- [<b>&minus;b</b><i>&nbsp;buffer</i>]
- [<b>&minus;m</b><i>&nbsp;timeout</i>]
- [<b>&minus;T</b><i>&nbsp;key</i>]
-+[<b>&minus;j</b><i>&nbsp;JSON</i>]
- [<b>&minus;w</b><i>&nbsp;swfHash</i>]
- [<b>&minus;x</b><i>&nbsp;swfSize</i>]
- [<b>&minus;W</b><i>&nbsp;swfUrl</i>]
-@@ -275,6 +276,12 @@ authentication.
- </dl>
- <p>
- <dl compact><dt>
-+<b>&minus;&minus;jtv &minus;j</b>&nbsp;<i>JSON</i>
-+<dd>
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+</dl>
-+<p>
-+<dl compact><dt>
- <b>&minus;&minus;swfhash &minus;w</b>&nbsp;<i>hexstring</i>
- <dd>
- SHA256 hash of the decompressed SWF file. This option may be needed if
-diff --git a/rtmpdump.c b/rtmpdump.c
-index ec1de85..89c053a 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -1055,9 +1055,9 @@ main(int argc, char **argv)
- case 'S':
- STR2AVAL(sockshost, optarg);
- break;
-- case 'j':
-- STR2AVAL(usherToken, optarg);
-- break;
-+ case 'j':
-+ STR2AVAL(usherToken, optarg);
-+ break;
- default:
- RTMP_LogPrintf("unknown option: %c\n", opt);
- usage(argv[0]);
-diff --git a/rtmpgw.8.html b/rtmpgw.8.html
-index 58b8f35..68d6734 100644
---- a/rtmpgw.8.html
-+++ b/rtmpgw.8.html
-@@ -6,10 +6,10 @@
- <tr><td>RTMPGW(8)<td align="center"><td align="right">RTMPGW(8)
- </thead>
- <tfoot>
--<tr><td>RTMPDump v2.2e<td align="center">2010-05-02<td align="right">RTMPGW(8)
-+<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">RTMPGW(8)
- </tfoot>
- <tbody><tr><td colspan="3"><br><br><ul>
--<!-- Copyright 2010 Howard Chu.
-+<!-- Copyright 2011 Howard Chu.
- Copying permitted according to the GNU General Public License V2.-->
- </ul>
-
-@@ -41,6 +41,7 @@ rtmpgw &minus; RTMP streaming media gateway
- [<b>&minus;b</b><i>&nbsp;buffer</i>]
- [<b>&minus;m</b><i>&nbsp;timeout</i>]
- [<b>&minus;T</b><i>&nbsp;key</i>]
-+[<b>&minus;j</b><i>&nbsp;JSON</i>]
- [<b>&minus;w</b><i>&nbsp;swfHash</i>]
- [<b>&minus;x</b><i>&nbsp;swfSize</i>]
- [<b>&minus;W</b><i>&nbsp;swfUrl</i>]
-@@ -249,6 +250,12 @@ authentication.
- </dl>
- <p>
- <dl compact><dt>
-+<b>&minus;&minus;jtv &minus;j</b>&nbsp;<i>JSON</i>
-+<dd>
-+JSON token used by legacy Justin.tv servers. Invokes NetStream.Authenticate.UsherToken
-+</dl>
-+<p>
-+<dl compact><dt>
- <b>&minus;&minus;swfhash &minus;w</b>&nbsp;<i>hexstring</i>
- <dd>
- SHA256 hash of the decompressed SWF file. This option may be needed if
-diff --git a/rtmpgw.c b/rtmpgw.c
-index ce7319a..733e105 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -1100,7 +1100,7 @@ main(int argc, char **argv)
- ("--stop|-B num Stop at num seconds into stream\n");
- RTMP_LogPrintf
- ("--token|-T key Key for SecureToken response\n");
-- RTMP_LogPrintf
-+ RTMP_LogPrintf
- ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
- RTMP_LogPrintf
- ("--buffer|-b Buffer time in milliseconds (default: %lu)\n\n",
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index cf52bfa..f1b6c66 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -116,7 +116,6 @@ typedef struct
- AVal swfHash;
- AVal flashVer;
- AVal subscribepath;
-- AVal usherToken;
- uint32_t swfSize;
-
- uint32_t dStartOffset;
---
-1.7.10.4
-
-
-From ed99ad05b34031fac74230760c77d4d1a6a9e706 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sat, 30 Apr 2011 14:29:58 +0300
-Subject: [PATCH 03/64] Remove the generated pkg-config file on make clean
-
-
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index d61e7a4..c95c8a6 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -76,7 +76,7 @@ OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o
- all: librtmp.a $(SO_LIB)
-
- clean:
-- rm -f *.o *.a *.$(SOX) *.$(SO_EXT)
-+ rm -f *.o *.a *.$(SOX) *.$(SO_EXT) librtmp.pc
-
- librtmp.a: $(OBJS)
- $(AR) rs $@ $?
---
-1.7.10.4
-
-
-From 749018b7c7c4e0090ea17c104dc094ab74326c08 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sat, 30 Apr 2011 14:30:00 +0300
-Subject: [PATCH 04/64] Create the SODIR, too
-
-When SYS=mingw, this differs from LIBDIR.
-
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index c95c8a6..aa4a339 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -100,7 +100,7 @@ librtmp.pc: librtmp.pc.in Makefile
- install: install_base $(SO_INST)
-
- install_base: librtmp.a librtmp.pc
-- -mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3
-+ -mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3 $(SODIR)
- cp amf.h http.h log.h rtmp.h $(INCDIR)
- cp librtmp.a $(LIBDIR)
- cp librtmp.pc $(LIBDIR)/pkgconfig
---
-1.7.10.4
-
-
-From 9931c44867d157621ae10cf489ba336091dfab6b Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sat, 30 Apr 2011 14:30:01 +0300
-Subject: [PATCH 05/64] Generate and install an import lib for the built DLL
-
-
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index aa4a339..b88baf4 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -54,9 +54,14 @@ SODIR=$(SODIR_$(SYS))
- SO_LDFLAGS_posix=-shared -Wl,-soname,$@
- SO_LDFLAGS_darwin=-dynamiclib -flat_namespace -undefined suppress -fno-common \
- -headerpad_max_install_names
--SO_LDFLAGS_mingw=-shared
-+SO_LDFLAGS_mingw=-shared -Wl,--out-implib,librtmp.dll.a
- SO_LDFLAGS=$(SO_LDFLAGS_$(SYS))
-
-+INSTALL_IMPLIB_posix=
-+INSTALL_IMPLIB_darwin=
-+INSTALL_IMPLIB_mingw=cp librtmp.dll.a $(LIBDIR)
-+INSTALL_IMPLIB=$(INSTALL_IMPLIB_$(SYS))
-+
- SHARED=yes
- SODEF_yes=-fPIC
- SOLIB_yes=librtmp.$(SO_EXT)
-@@ -108,5 +113,6 @@ install_base: librtmp.a librtmp.pc
-
- install_so: librtmp.$(SO_EXT)
- cp librtmp.$(SO_EXT) $(SODIR)
-+ $(INSTALL_IMPLIB)
- cd $(SODIR); ln -sf librtmp.$(SO_EXT) librtmp.$(SOX)
-
---
-1.7.10.4
-
-
-From 060206d121657d7e45c01ac022dd071c877b4caa Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Fri, 15 Jul 2011 13:46:02 +0300
-Subject: [PATCH 06/64] Check the return value from RTMP_SendBytesReceived()
-
-This avoids double frees in RTMP_Close(), if the
-RTMP_SendBytesReceived() call failed, which earlier led
-to RTMP_ReadPacket() writing back an already freed buffer
-(freed by RTMP_Close() within WriteN()) into m_vecChannelsIn.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 8d76164..f85cd83 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -1338,7 +1338,8 @@ ReadN(RTMP *r, char *buffer, int n)
- r->m_nBytesIn += nRead;
- if (r->m_bSendCounter
- && r->m_nBytesIn > r->m_nBytesInSent + r->m_nClientBW / 2)
-- SendBytesReceived(r);
-+ if (!SendBytesReceived(r))
-+ return FALSE;
- }
- /*RTMP_Log(RTMP_LOGDEBUG, "%s: %d bytes\n", __FUNCTION__, nBytes); */
- #ifdef _DEBUG
---
-1.7.10.4
-
-
-From 159a06ebe6d82ef20f2c77c497d55af00d2e0b78 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Fri, 15 Jul 2011 13:46:03 +0300
-Subject: [PATCH 07/64] Don't try to close an already closed socket
-
-This could happen if WriteN() (called within SendBytesReceived())
-failed.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index f85cd83..df2cb27 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -3626,7 +3626,9 @@ RTMPSockBuf_Close(RTMPSockBuf *sb)
- sb->sb_ssl = NULL;
- }
- #endif
-- return closesocket(sb->sb_socket);
-+ if (sb->sb_socket != -1)
-+ return closesocket(sb->sb_socket);
-+ return 0;
- }
-
- #define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
---
-1.7.10.4
-
-
-From 530d02fccf24f98e2e318418b2fa3e3420056fda Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Fri, 22 Jul 2011 18:04:05 -0700
-Subject: [PATCH 08/64] Fix MDH_free() for PolarSSL
-
-Reported by Reijo Tomperi <aggro80@users.sourceforge.net>
-
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index 8e285a6..efef0fd 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -53,7 +53,7 @@ typedef struct MDH {
- } MDH;
-
- #define MDH_new() calloc(1,sizeof(MDH))
--#define MDH_free(vp) {MDH *dh = vp; dhm_free(&dh->ctx); MP_free(dh->p); MP_free(dh->g); MP_free(dh->pub_key); MP_free(dh->priv_key); free(dh);}
-+#define MDH_free(vp) {MDH *_dh = vp; 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)
- {
---
-1.7.10.4
-
-
-From b627335dc37fd5265ac6d23a441ee2d89ab503c8 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Fri, 22 Jul 2011 18:06:27 -0700
-Subject: [PATCH 09/64] Plug potential memleak
-
-Reported by Reijo Tomperi <aggro80@users.sourceforge.net>
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index 89c053a..e506fa9 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -444,7 +444,7 @@ Download(RTMP * rtmp, // connected RTMP object
- {
- int32_t now, lastUpdate;
- int bufferSize = 64 * 1024;
-- char *buffer = (char *) malloc(bufferSize);
-+ char *buffer;
- int nRead = 0;
- off_t size = ftello(file);
- unsigned long lastPercent = 0;
-@@ -505,6 +505,8 @@ Download(RTMP * rtmp, // connected RTMP object
- rtmp->m_read.nMetaHeaderSize = nMetaHeaderSize;
- rtmp->m_read.nInitialFrameSize = nInitialFrameSize;
-
-+ buffer = (char *) malloc(bufferSize);
-+
- now = RTMP_GetTime();
- lastUpdate = now - 1000;
- do
---
-1.7.10.4
-
-
-From ec422962d58b8e0d9bfcf0af6e450e0e349947da Mon Sep 17 00:00:00 2001
-From: "Scott D. Davilla" <davilla@xbmc.org>
-Date: Fri, 29 Jul 2011 11:26:35 -0700
-Subject: [PATCH 10/64] Darwin dylib updates
-
-Bring in line with current practice for Darwin dynamic libs
-
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index b88baf4..a0125f1 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -52,8 +52,8 @@ SODIR_mingw=$(BINDIR)
- SODIR=$(SODIR_$(SYS))
-
- SO_LDFLAGS_posix=-shared -Wl,-soname,$@
--SO_LDFLAGS_darwin=-dynamiclib -flat_namespace -undefined suppress -fno-common \
-- -headerpad_max_install_names
-+SO_LDFLAGS_darwin=-dynamiclib -twolevel_namespace -undefined dynamic_lookup \
-+ -fno-common -headerpad_max_install_names -install_name $(libdir)/$@
- SO_LDFLAGS_mingw=-shared -Wl,--out-implib,librtmp.dll.a
- SO_LDFLAGS=$(SO_LDFLAGS_$(SYS))
-
---
-1.7.10.4
-
-
-From 024d201c36e1b40f4f4d473e87d405e1b411230f Mon Sep 17 00:00:00 2001
-From: KSV <faltuvisitor@yahoo.co.in>
-Date: Sun, 31 Jul 2011 12:33:46 -0700
-Subject: [PATCH 11/64] Justin.TV usherToken detection
-
-
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index f1b6c66..805ce0d 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -95,6 +95,7 @@ STREAMING_SERVER *rtmpServer = 0; // server structure pointer
-
- STREAMING_SERVER *startStreaming(const char *address, int port);
- void stopStreaming(STREAMING_SERVER * server);
-+char *strreplace(char *srcstr, int srclen, char *orig, char *repl);
-
- typedef struct
- {
-@@ -261,6 +262,7 @@ static const AVal av_NetStream_Play_Stop = AVC("NetStream.Play.Stop");
- static const AVal av_Stopped_playing = AVC("Stopped playing");
- SAVC(details);
- SAVC(clientid);
-+static const AVal av_NetStream_Authenticate_UsherToken = AVC("NetStream.Authenticate.UsherToken");
-
- static int
- SendPlayStart(RTMP *r)
-@@ -575,6 +577,13 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- {
- SendResultNumber(r, txn, 10.0);
- }
-+ else if (AVMATCH(&method, &av_NetStream_Authenticate_UsherToken))
-+ {
-+ AMFObjectProperty *prop = AMF_GetProp(&obj, NULL, 3);
-+ AMFProp_GetString(prop, &r->Link.usherToken);
-+ prop->p_vu.p_aval.av_len = 0;
-+ prop->p_vu.p_aval.av_val = NULL;
-+ }
- else if (AVMATCH(&method, &av_play))
- {
- char *file, *p, *q, *cmd, *ptr;
-@@ -591,10 +600,11 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- if (r->Link.tcUrl.av_len)
- {
- len = server->arglen + r->Link.playpath.av_len + 4 +
-- sizeof("rtmpdump") + r->Link.playpath.av_len + 12;
-+ sizeof("rtmpdump") + r->Link.playpath.av_len + 12 +
-+ r->Link.usherToken.av_len + 64;
- server->argc += 5;
-
-- cmd = malloc(len + server->argc * sizeof(AVal));
-+ cmd = malloc(len + (server->argc + 2) * sizeof(AVal));
- ptr = cmd;
- argv = (AVal *)(cmd + len);
- argv[0].av_val = cmd;
-@@ -640,6 +650,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- ptr += sprintf(ptr, " -p \"%s\"", r->Link.pageUrl.av_val);
- argv[argc++].av_len = r->Link.pageUrl.av_len;
- }
-+ if (r->Link.usherToken.av_val)
-+ {
-+ char *usherToken = strreplace(r->Link.usherToken.av_val, r->Link.usherToken.av_len, "\"", "\\\"");
-+ argv[argc].av_val = ptr + 1;
-+ argv[argc++].av_len = 5;
-+ argv[argc].av_val = ptr + 8;
-+ ptr += sprintf(ptr, " --jtv \"%s\"", usherToken);
-+ argv[argc++].av_len = strlen(usherToken);
-+ server->argc += 2;
-+ free(usherToken);
-+ }
- if (r->Link.extras.o_num) {
- ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc);
- AMF_Reset(&r->Link.extras);
-@@ -1111,3 +1132,39 @@ main(int argc, char **argv)
- #endif
- return nStatus;
- }
-+
-+char *
-+strreplace(char *srcstr, int srclen, char *orig, char *repl)
-+{
-+ char *ptr = NULL, *srcstrstart = srcstr;
-+ int origlen = strlen(orig);
-+ int repllen = strlen(repl);
-+ if (!srclen)
-+ srclen = strlen(srcstr);
-+ char *srcend = srcstr + srclen;
-+ int deststrbuffer = srclen / origlen * repllen;
-+ if (deststrbuffer < srclen)
-+ deststrbuffer = srclen;
-+ char *deststr = calloc(deststrbuffer + 1, sizeof(char));
-+ char *deststrstart = deststr;
-+
-+ if ( (ptr = strstr(srcstr, orig)) )
-+ {
-+ do
-+ {
-+ int len = ptr - srcstrstart;
-+ memcpy(deststrstart, srcstrstart, len);
-+ srcstrstart += len + origlen;
-+ deststrstart += len;
-+ memcpy(deststrstart, repl, repllen);
-+ deststrstart += repllen;
-+ ptr = strstr(srcstrstart, orig);
-+ }
-+ while (ptr && (ptr < srcend));
-+ strncpy(deststrstart, srcstrstart, srcend-srcstrstart);
-+ return deststr;
-+ }
-+
-+ strncpy(deststr, srcstr, srclen);
-+ return deststr;
-+}
---
-1.7.10.4
-
-
-From f1abda046ca5a3f1efa63033c542e686b43dbcf3 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Sun, 31 Jul 2011 13:21:12 -0700
-Subject: [PATCH 12/64] Cleanup previous commit
-
-
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index 805ce0d..b45aae3 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -1,6 +1,6 @@
- /* Simple RTMP Server
- * Copyright (C) 2009 Andrej Stepanchuk
-- * Copyright (C) 2009 Howard Chu
-+ * Copyright (C) 2009-2011 Howard Chu
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
-@@ -95,7 +95,10 @@ STREAMING_SERVER *rtmpServer = 0; // server structure pointer
-
- STREAMING_SERVER *startStreaming(const char *address, int port);
- void stopStreaming(STREAMING_SERVER * server);
--char *strreplace(char *srcstr, int srclen, char *orig, char *repl);
-+void AVreplace(AVal *src, const AVal *orig, const AVal *repl);
-+
-+static const AVal av_dquote = AVC("\"");
-+static const AVal av_escdquote = AVC("\\\"");
-
- typedef struct
- {
-@@ -579,10 +582,12 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- }
- else if (AVMATCH(&method, &av_NetStream_Authenticate_UsherToken))
- {
-- AMFObjectProperty *prop = AMF_GetProp(&obj, NULL, 3);
-- AMFProp_GetString(prop, &r->Link.usherToken);
-- prop->p_vu.p_aval.av_len = 0;
-- prop->p_vu.p_aval.av_val = NULL;
-+ AVal usherToken;
-+ AMFProp_GetString(AMF_GetProp(&obj, NULL, 3), &usherToken);
-+ AVreplace(&usherToken, &av_dquote, &av_escdquote);
-+ server->arglen += 6 + usherToken.av_len;
-+ server->argc += 2;
-+ r->Link.usherToken = usherToken;
- }
- else if (AVMATCH(&method, &av_play))
- {
-@@ -600,11 +605,10 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- if (r->Link.tcUrl.av_len)
- {
- len = server->arglen + r->Link.playpath.av_len + 4 +
-- sizeof("rtmpdump") + r->Link.playpath.av_len + 12 +
-- r->Link.usherToken.av_len + 64;
-+ sizeof("rtmpdump") + r->Link.playpath.av_len + 12;
- server->argc += 5;
-
-- cmd = malloc(len + (server->argc + 2) * sizeof(AVal));
-+ cmd = malloc(len + server->argc * sizeof(AVal));
- ptr = cmd;
- argv = (AVal *)(cmd + len);
- argv[0].av_val = cmd;
-@@ -650,17 +654,17 @@ ServeInvoke(STREAMING_SERVER *server, RTMP * r, RTMPPacket *packet, unsigned int
- ptr += sprintf(ptr, " -p \"%s\"", r->Link.pageUrl.av_val);
- argv[argc++].av_len = r->Link.pageUrl.av_len;
- }
-- if (r->Link.usherToken.av_val)
-- {
-- char *usherToken = strreplace(r->Link.usherToken.av_val, r->Link.usherToken.av_len, "\"", "\\\"");
-+ if (r->Link.usherToken.av_val)
-+ {
- argv[argc].av_val = ptr + 1;
-- argv[argc++].av_len = 5;
-- argv[argc].av_val = ptr + 8;
-- ptr += sprintf(ptr, " --jtv \"%s\"", usherToken);
-- argv[argc++].av_len = strlen(usherToken);
-- server->argc += 2;
-- free(usherToken);
-- }
-+ argv[argc++].av_len = 2;
-+ argv[argc].av_val = ptr + 5;
-+ ptr += sprintf(ptr, " -j \"%s\"", r->Link.usherToken.av_val);
-+ argv[argc++].av_len = r->Link.usherToken.av_len;
-+ free(r->Link.usherToken.av_val);
-+ r->Link.usherToken.av_val = NULL;
-+ r->Link.usherToken.av_len = 0;
-+ }
- if (r->Link.extras.o_num) {
- ptr = dumpAMF(&r->Link.extras, ptr, argv, &argc);
- AMF_Reset(&r->Link.extras);
-@@ -932,6 +936,11 @@ cleanup:
- 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;
-+ }
- RTMP_LogPrintf("done!\n\n");
-
- quit:
-@@ -1133,38 +1142,42 @@ main(int argc, char **argv)
- return nStatus;
- }
-
--char *
--strreplace(char *srcstr, int srclen, char *orig, char *repl)
-+void
-+AVreplace(AVal *src, const AVal *orig, const AVal *repl)
- {
-- char *ptr = NULL, *srcstrstart = srcstr;
-- int origlen = strlen(orig);
-- int repllen = strlen(repl);
-- if (!srclen)
-- srclen = strlen(srcstr);
-- char *srcend = srcstr + srclen;
-- int deststrbuffer = srclen / origlen * repllen;
-- if (deststrbuffer < srclen)
-- deststrbuffer = srclen;
-- char *deststr = calloc(deststrbuffer + 1, sizeof(char));
-- char *deststrstart = deststr;
--
-- if ( (ptr = strstr(srcstr, orig)) )
-- {
-- do
-+ char *srcbeg = src->av_val;
-+ char *srcend = src->av_val + src->av_len;
-+ char *dest, *sptr, *dptr;
-+ int n = 0;
-+
-+ /* count occurrences of orig in src */
-+ sptr = src->av_val;
-+ while (sptr < srcend && (sptr = strstr(sptr, orig->av_val)))
- {
-- int len = ptr - srcstrstart;
-- memcpy(deststrstart, srcstrstart, len);
-- srcstrstart += len + origlen;
-- deststrstart += len;
-- memcpy(deststrstart, repl, repllen);
-- deststrstart += repllen;
-- ptr = strstr(srcstrstart, orig);
-+ n++;
-+ sptr += orig->av_len;
- }
-- while (ptr && (ptr < srcend));
-- strncpy(deststrstart, srcstrstart, srcend-srcstrstart);
-- return deststr;
-- }
-+ if (!n)
-+ return;
-
-- strncpy(deststr, srcstr, srclen);
-- return deststr;
-+ dest = malloc(src->av_len + 1 + (repl->av_len - orig->av_len) * n);
-+
-+ sptr = src->av_val;
-+ dptr = dest;
-+ while (sptr < srcend && (sptr = strstr(sptr, orig->av_val)))
-+ {
-+ n = sptr - srcbeg;
-+ memcpy(dptr, srcbeg, n);
-+ srcbeg += n;
-+ dptr += n;
-+ memcpy(dptr, repl->av_val, repl->av_len);
-+ dptr += repl->av_len;
-+ sptr += orig->av_len;
-+ }
-+ n = srcend - srcbeg;
-+ memcpy(dptr, srcbeg, n);
-+ dptr += n;
-+ *dptr = '\0';
-+ src->av_val = dest;
-+ src->av_len = dptr - dest;
- }
---
-1.7.10.4
-
-
-From 8880d1456b282ee79979adbe7b6a6eb8ad371081 Mon Sep 17 00:00:00 2001
-From: Chris Larsen <clarsen@euphoriaaudio.com>
-Date: Tue, 2 Aug 2011 12:33:44 -0400
-Subject: [PATCH 13/64] Unexpected BW Response Fix
-
-Bug: SendCheckBWResult sends an invalid bw response due to casting issues
-from a double to an int.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index df2cb27..5311a8a 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2339,7 +2339,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- {
- AMFObject obj;
- AVal method;
-- int txn;
-+ double txn;
- int ret = 0, nRes;
- if (body[0] != 0x02) /* make sure it is a string method name we start with */
- {
-@@ -2357,7 +2357,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
-
- AMF_Dump(&obj);
- AMFProp_GetString(AMF_GetProp(&obj, NULL, 0), &method);
-- txn = (int)AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 1));
-+ txn = AMFProp_GetNumber(AMF_GetProp(&obj, NULL, 1));
- RTMP_Log(RTMP_LOGDEBUG, "%s, server invoking <%s>", __FUNCTION__, method.av_val);
-
- if (AVMATCH(&method, &av__result))
-@@ -2366,7 +2366,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- int i;
-
- for (i=0; i<r->m_numCalls; i++) {
-- if (r->m_methodCalls[i].num == txn) {
-+ if (r->m_methodCalls[i].num == (int)txn) {
- methodInvoked = r->m_methodCalls[i].name;
- AV_erase(r->m_methodCalls, &r->m_numCalls, i, FALSE);
- break;
---
-1.7.10.4
-
-
-From c528451068de033d7cc76eb1c5a606c10215fcfb Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Wed, 3 Aug 2011 11:46:07 -0700
-Subject: [PATCH 14/64] Fix <arpa/inet.h> include order
-
-
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index 6a3f215..638374f 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -46,10 +46,10 @@
- #include <sys/socket.h>
- #include <sys/times.h>
- #include <netdb.h>
--#include <arpa/inet.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
-+#include <arpa/inet.h>
- #define GetSockError() errno
- #define SetSockError(e) errno = e
- #undef closesocket
---
-1.7.10.4
-
-
-From a1114e09bf0d74ef1d575eb88f3aa36bc7c6d790 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 9 Aug 2011 14:44:14 -0700
-Subject: [PATCH 15/64] Fix AVreplace for usherToken
-
-
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index b45aae3..91fc4da 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -1168,11 +1168,11 @@ AVreplace(AVal *src, const AVal *orig, const AVal *repl)
- {
- n = sptr - srcbeg;
- memcpy(dptr, srcbeg, n);
-- srcbeg += n;
- dptr += n;
- memcpy(dptr, repl->av_val, repl->av_len);
- dptr += repl->av_len;
- sptr += orig->av_len;
-+ srcbeg = sptr;
- }
- n = srcend - srcbeg;
- memcpy(dptr, srcbeg, n);
---
-1.7.10.4
-
-
-From c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Thu, 11 Aug 2011 18:02:10 -0700
-Subject: [PATCH 16/64] Add RD_NO_CONNECT return code for Connect failures
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index e506fa9..01decf9 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -46,6 +46,7 @@
- #define RD_SUCCESS 0
- #define RD_FAILED 1
- #define RD_INCOMPLETE 2
-+#define RD_NO_CONNECT 3
-
- #define DEF_TIMEOUT 30 /* seconds */
- #define DEF_BUFTIME (10 * 60 * 60 * 1000) /* 10 hours default */
-@@ -1253,7 +1254,7 @@ main(int argc, char **argv)
-
- if (!RTMP_Connect(&rtmp, NULL))
- {
-- nStatus = RD_FAILED;
-+ nStatus = RD_NO_CONNECT;
- break;
- }
-
---
-1.7.10.4
-
-
-From 6230845ab0fba07289d4b2d9b97269e4b2d90766 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Sun, 25 Sep 2011 03:07:14 -0700
-Subject: [PATCH 17/64] PolarSSL support now requires version 1.0.0.
-
-
-diff --git a/README b/README
-index 865c6c4..dcf5f52 100644
---- a/README
-+++ b/README
-@@ -50,6 +50,7 @@ library. You can also turn it off if desired
- The rtmpdump programs still link to the static library, regardless.
-
- Note that if using OpenSSL, you must have version 0.9.8 or newer.
-+For Polar SSL you must have version 1.0.0 or newer.
-
- Credit goes to team boxee for the XBMC RTMP code originally used in RTMPDumper.
- The current code is based on the XBMC code but rewritten in C by Howard Chu.
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index efef0fd..a9f3763 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -30,14 +30,14 @@
- #ifdef USE_POLARSSL
- #include <polarssl/dhm.h>
- typedef mpi * MP_t;
--#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m, NULL)
-+#define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
- #define MP_set_w(mpi, w) mpi_lset(mpi, w)
- #define MP_cmp(u, v) mpi_cmp_mpi(u, v)
- #define MP_set(u, v) mpi_copy(u, v)
- #define MP_sub_w(mpi, w) mpi_sub_int(mpi, mpi, w)
- #define MP_cmp_1(mpi) mpi_cmp_int(mpi, 1)
- #define MP_modexp(r, y, q, p) mpi_exp_mod(r, y, q, p, NULL)
--#define MP_free(mpi) mpi_free(mpi, NULL); free(mpi)
-+#define MP_free(mpi) mpi_free(mpi); free(mpi)
- #define MP_gethex(u, hex, res) MP_new(u); res = mpi_read_string(u, 16, hex) == 0
- #define MP_bytes(u) mpi_size(u)
- #define MP_setbin(u,buf,len) mpi_write_binary(u,buf,len)
-@@ -71,9 +71,8 @@ static int MDH_generate_key(MDH *dh)
-
- static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
- {
-- int n = len;
- MP_set(&dh->ctx.GY, pub);
-- dhm_calc_secret(&dh->ctx, secret, &n);
-+ dhm_calc_secret(&dh->ctx, secret, &len);
- return 0;
- }
-
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index 638374f..c3fd4a6 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -71,7 +71,8 @@ typedef struct 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_rand, &ctx->hs); ssl_set_ciphers(s, ssl_default_ciphers);\
-+ ssl_set_rng(s, havege_rand, &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)
---
-1.7.10.4
-
-
-From 60218d0af0f4bd683ecdebe49986f188820cf8ce Mon Sep 17 00:00:00 2001
-From: Kirill Zorin <cyril.zorin@gmail.com>
-Date: Fri, 30 Sep 2011 13:38:23 -0400
-Subject: [PATCH 18/64] fixed undefined behaviour due to union assignment
-
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index 7fa289e..ae920e4 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -1111,7 +1111,7 @@ AMF_AddProp(AMFObject *obj, const AMFObjectProperty *prop)
- if (!(obj->o_num & 0x0f))
- obj->o_props =
- realloc(obj->o_props, (obj->o_num + 16) * sizeof(AMFObjectProperty));
-- obj->o_props[obj->o_num++] = *prop;
-+ memcpy(&obj->o_props[obj->o_num++], prop, sizeof(AMFObjectProperty));
- }
-
- int
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 5311a8a..4b17a49 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2584,7 +2584,7 @@ RTMP_FindFirstMatchingProperty(AMFObject *obj, const AVal *name,
-
- if (AVMATCH(&prop->p_name, name))
- {
-- *p = *prop;
-+ memcpy(p, prop, sizeof(*prop));
- return TRUE;
- }
-
-@@ -2610,7 +2610,7 @@ RTMP_FindPrefixProperty(AMFObject *obj, const AVal *name,
- if (prop->p_name.av_len > name->av_len &&
- !memcmp(prop->p_name.av_val, name->av_val, name->av_len))
- {
-- *p = *prop;
-+ memcpy(p, prop, sizeof(*prop));
- return TRUE;
- }
-
---
-1.7.10.4
-
-
-From c90c05892cbaebfb1b2095759597d9fb38238c64 Mon Sep 17 00:00:00 2001
-From: KSV <faltuvistor@yahoo.co.in>
-Date: Mon, 7 Nov 2011 11:38:27 -0800
-Subject: [PATCH 19/64] Fix bytes-received report
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 4b17a49..a9c1bc1 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -1337,7 +1337,7 @@ ReadN(RTMP *r, char *buffer, int n)
- nBytes = nRead;
- r->m_nBytesIn += nRead;
- if (r->m_bSendCounter
-- && r->m_nBytesIn > r->m_nBytesInSent + r->m_nClientBW / 2)
-+ && r->m_nBytesIn > ( r->m_nBytesInSent + r->m_nClientBW / 10))
- if (!SendBytesReceived(r))
- return FALSE;
- }
---
-1.7.10.4
-
-
-From b3467069ad7c26d748ca13ce0ee88a41f85b22dd Mon Sep 17 00:00:00 2001
-From: Jeff Johnson <jeff@rogueamoeba.com>
-Date: Mon, 7 Nov 2011 11:43:26 -0800
-Subject: [PATCH 20/64] Fix getting swf hash with https URLs
-
-
-diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c
-index 3c56b69..5576730 100644
---- a/librtmp/hashswf.c
-+++ b/librtmp/hashswf.c
-@@ -163,7 +163,7 @@ HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
- #else
- TLS_client(RTMP_TLS_ctx, sb.sb_ssl);
- TLS_setfd(sb.sb_ssl, sb.sb_socket);
-- if ((i = TLS_connect(sb.sb_ssl)) < 0)
-+ if (TLS_connect(sb.sb_ssl) < 0)
- {
- RTMP_Log(RTMP_LOGERROR, "%s, TLS_Connect failed", __FUNCTION__);
- ret = HTTPRES_LOST_CONNECTION;
---
-1.7.10.4
-
-
-From 90799efbb67f415ff930d68905e8267d5aa5dc4e Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 8 Nov 2011 02:04:01 -0800
-Subject: [PATCH 21/64] Increase tcUrl buffer size
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index 01decf9..a8fa128 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -1152,9 +1152,9 @@ main(int argc, char **argv)
-
- if (tcUrl.av_len == 0)
- {
-- char str[512] = { 0 };
-+ char str[1024];
-
-- tcUrl.av_len = snprintf(str, 511, "%s://%.*s:%d/%.*s",
-+ tcUrl.av_len = snprintf(str, sizeof(str), "%s://%.*s:%d/%.*s",
- RTMPProtocolStringsLower[protocol], hostname.av_len,
- hostname.av_val, port, app.av_len, app.av_val);
- tcUrl.av_val = (char *) malloc(tcUrl.av_len + 1);
---
-1.7.10.4
-
-
-From 9df7959a71ec33cc9c83c9d3ef25c17b1c527f0e Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 8 Nov 2011 02:05:01 -0800
-Subject: [PATCH 22/64] Spell Referer according to RFC1945
-
-
-diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c
-index 5576730..0320480 100644
---- a/librtmp/hashswf.c
-+++ b/librtmp/hashswf.c
-@@ -141,7 +141,7 @@ HTTP_get(struct HTTP_ctx *http, const char *url, HTTP_read_callback *cb)
- return HTTPRES_LOST_CONNECTION;
- i =
- sprintf(sb.sb_buf,
-- "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\nReferrer: %.*s\r\n",
-+ "GET %s HTTP/1.0\r\nUser-Agent: %s\r\nHost: %s\r\nReferer: %.*s\r\n",
- path, AGENT, host, (int)(path - url + 1), url);
- if (http->date[0])
- i += sprintf(sb.sb_buf + i, "If-Modified-Since: %s\r\n", http->date);
---
-1.7.10.4
-
-
-From 1c77ff43439068981d2ad9872952922a1ee37f89 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 8 Nov 2011 02:13:14 -0800
-Subject: [PATCH 23/64] Calculate tcUrl length
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index a8fa128..892a8bc 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -1152,13 +1152,12 @@ main(int argc, char **argv)
-
- if (tcUrl.av_len == 0)
- {
-- char str[1024];
--
-- tcUrl.av_len = snprintf(str, sizeof(str), "%s://%.*s:%d/%.*s",
-+ tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) +
-+ hostname.av_len + app.av_len + sizeof("://:65535/");
-+ tcUrl.av_val = (char *) malloc(tcUrl.av_len);
-+ tcUrl.av_len = snprintf(tcUrl.av_val, tcUrl.av_len, "%s://%.*s:%d/%.*s",
- RTMPProtocolStringsLower[protocol], hostname.av_len,
- hostname.av_val, port, app.av_len, app.av_val);
-- tcUrl.av_val = (char *) malloc(tcUrl.av_len + 1);
-- strcpy(tcUrl.av_val, str);
- }
-
- int first = 1;
---
-1.7.10.4
-
-
-From 30fcf46fc82f96ca41b710fc38bbc15f2489795e Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 8 Nov 2011 02:14:21 -0800
-Subject: [PATCH 24/64] Check for malloc failure in prev commit
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index 892a8bc..c37def2 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -1155,6 +1155,8 @@ main(int argc, char **argv)
- tcUrl.av_len = strlen(RTMPProtocolStringsLower[protocol]) +
- hostname.av_len + app.av_len + sizeof("://:65535/");
- tcUrl.av_val = (char *) malloc(tcUrl.av_len);
-+ if (!tcUrl.av_val)
-+ return RD_FAILED;
- tcUrl.av_len = snprintf(tcUrl.av_val, tcUrl.av_len, "%s://%.*s:%d/%.*s",
- RTMPProtocolStringsLower[protocol], hostname.av_len,
- hostname.av_val, port, app.av_len, app.av_val);
---
-1.7.10.4
-
-
-From 83e701eef0d7947713280fe3e7561bed1e7195f5 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 14 Nov 2011 16:09:26 -0800
-Subject: [PATCH 25/64] Fix missing log message parameter
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index a9c1bc1..4da318b 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -974,7 +974,7 @@ SocksNegotiate(RTMP *r)
- }
- else
- {
-- RTMP_Log(RTMP_LOGERROR, "%s, SOCKS returned error code %d", packet[1]);
-+ RTMP_Log(RTMP_LOGERROR, "%s, SOCKS returned error code %d", __FUNCTION__, packet[1]);
- return FALSE;
- }
- }
---
-1.7.10.4
-
-
-From 949da84ab1f659597d6e7fa1ef0ab8fc1ca8e246 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 14 Nov 2011 16:11:13 -0800
-Subject: [PATCH 26/64] Tell gcc about log format strings
-
-
-diff --git a/librtmp/log.h b/librtmp/log.h
-index 97c9aac..2adb111 100644
---- a/librtmp/log.h
-+++ b/librtmp/log.h
-@@ -48,9 +48,15 @@ extern RTMP_LogLevel RTMP_debuglevel;
- typedef void (RTMP_LogCallback)(int level, const char *fmt, va_list);
- void RTMP_LogSetCallback(RTMP_LogCallback *cb);
- void RTMP_LogSetOutput(FILE *file);
-+#ifdef __GNUC__
-+void RTMP_LogPrintf(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-+void RTMP_LogStatus(const char *format, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
-+void RTMP_Log(int level, const char *format, ...) __attribute__ ((__format__ (__printf__, 2, 3)));
-+#else
- void RTMP_LogPrintf(const char *format, ...);
- void RTMP_LogStatus(const char *format, ...);
- void RTMP_Log(int level, const char *format, ...);
-+#endif
- void RTMP_LogHex(int level, const uint8_t *data, unsigned long len);
- void RTMP_LogHexString(int level, const uint8_t *data, unsigned long len);
- void RTMP_LogSetLevel(RTMP_LogLevel lvl);
---
-1.7.10.4
-
-
-From 45556fb3b372402d7bd5235832176f58dede90ae Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 14 Nov 2011 16:12:26 -0800
-Subject: [PATCH 27/64] Fix mismatched format string conversions
-
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index ae920e4..f9ecf21 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -586,7 +586,7 @@ AMF3Prop_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- case AMF3_ARRAY:
- case AMF3_BYTE_ARRAY:
- default:
-- RTMP_Log(RTMP_LOGDEBUG, "%s - AMF3 unknown/unsupported datatype 0x%02x, @0x%08X",
-+ RTMP_Log(RTMP_LOGDEBUG, "%s - AMF3 unknown/unsupported datatype 0x%02x, @%p",
- __FUNCTION__, (unsigned char)(*pBuffer), pBuffer);
- return -1;
- }
-@@ -772,7 +772,7 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- break;
- }
- default:
-- RTMP_Log(RTMP_LOGDEBUG, "%s - unknown datatype 0x%02x, @0x%08X", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s - unknown datatype 0x%02x, @%p", __FUNCTION__,
- prop->p_type, pBuffer - 1);
- return -1;
- }
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 4da318b..52d0254 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -185,7 +185,7 @@ void
- RTMPPacket_Dump(RTMPPacket *p)
- {
- RTMP_Log(RTMP_LOGDEBUG,
-- "RTMP PACKET: packet type: 0x%02x. channel: 0x%02x. info 1: %d info 2: %d. Body size: %lu. body: 0x%02x",
-+ "RTMP PACKET: packet type: 0x%02x. channel: 0x%02x. info 1: %d info 2: %d. Body size: %u. body: 0x%02x",
- p->m_packetType, p->m_nChannel, p->m_nTimeStamp, p->m_nInfoField2,
- p->m_nBodySize, p->m_body ? (unsigned char)p->m_body[0] : 0);
- }
-@@ -367,7 +367,7 @@ RTMP_SetupStream(RTMP *r,
- RTMP_Log(RTMP_LOGDEBUG, "StopTime : %d msec", dStop);
-
- RTMP_Log(RTMP_LOGDEBUG, "live : %s", bLiveStream ? "yes" : "no");
-- RTMP_Log(RTMP_LOGDEBUG, "timeout : %d sec", timeout);
-+ RTMP_Log(RTMP_LOGDEBUG, "timeout : %ld sec", timeout);
-
- #ifdef CRYPTO
- if (swfSHA256Hash != NULL && swfSize > 0)
-@@ -376,7 +376,7 @@ RTMP_SetupStream(RTMP *r,
- r->Link.SWFSize = swfSize;
- RTMP_Log(RTMP_LOGDEBUG, "SWFSHA256:");
- RTMP_LogHex(RTMP_LOGDEBUG, r->Link.SWFHash, sizeof(r->Link.SWFHash));
-- RTMP_Log(RTMP_LOGDEBUG, "SWFSize : %lu", r->Link.SWFSize);
-+ RTMP_Log(RTMP_LOGDEBUG, "SWFSize : %u", r->Link.SWFSize);
- }
- else
- {
-@@ -1161,14 +1161,14 @@ RTMP_ClientPacket(RTMP *r, RTMPPacket *packet)
- case RTMP_PACKET_TYPE_FLEX_STREAM_SEND:
- /* flex stream send */
- RTMP_Log(RTMP_LOGDEBUG,
-- "%s, flex stream send, size %lu bytes, not supported, ignoring",
-+ "%s, flex stream send, size %u bytes, not supported, ignoring",
- __FUNCTION__, packet->m_nBodySize);
- break;
-
- case RTMP_PACKET_TYPE_FLEX_SHARED_OBJECT:
- /* flex shared object */
- RTMP_Log(RTMP_LOGDEBUG,
-- "%s, flex shared object, size %lu bytes, not supported, ignoring",
-+ "%s, flex shared object, size %u bytes, not supported, ignoring",
- __FUNCTION__, packet->m_nBodySize);
- break;
-
-@@ -1176,7 +1176,7 @@ RTMP_ClientPacket(RTMP *r, RTMPPacket *packet)
- /* flex message */
- {
- RTMP_Log(RTMP_LOGDEBUG,
-- "%s, flex message, size %lu bytes, not fully supported",
-+ "%s, flex message, size %u bytes, not fully supported",
- __FUNCTION__, packet->m_nBodySize);
- /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */
-
-@@ -1198,7 +1198,7 @@ RTMP_ClientPacket(RTMP *r, RTMPPacket *packet)
- }
- case RTMP_PACKET_TYPE_INFO:
- /* metadata (notify) */
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received: notify %lu bytes", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received: notify %u bytes", __FUNCTION__,
- packet->m_nBodySize);
- if (HandleMetadata(r, packet->m_body, packet->m_nBodySize))
- bHasMediaPacket = 1;
-@@ -1211,7 +1211,7 @@ RTMP_ClientPacket(RTMP *r, RTMPPacket *packet)
-
- case RTMP_PACKET_TYPE_INVOKE:
- /* invoke */
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received: invoke %lu bytes", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received: invoke %u bytes", __FUNCTION__,
- packet->m_nBodySize);
- /*RTMP_LogHex(packet.m_body, packet.m_nBodySize); */
-
-@@ -2373,7 +2373,7 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- }
- }
- if (!methodInvoked.av_val) {
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received result id %d without matching request",
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received result id %f without matching request",
- __FUNCTION__, txn);
- goto leave;
- }
-@@ -3055,7 +3055,7 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet)
-
- if (ReadN(r, packet->m_body + packet->m_nBytesRead, nChunk) != nChunk)
- {
-- RTMP_Log(RTMP_LOGERROR, "%s, failed to read RTMP packet body. len: %lu",
-+ RTMP_Log(RTMP_LOGERROR, "%s, failed to read RTMP packet body. len: %u",
- __FUNCTION__, packet->m_nBodySize);
- return FALSE;
- }
-@@ -4176,7 +4176,7 @@ Read_1_Packet(RTMP *r, char *buf, unsigned int buflen)
- if (pos + 11 + dataSize > nPacketLen)
- {
- RTMP_Log(RTMP_LOGERROR,
-- "Wrong data size (%lu), stream corrupted, aborting!",
-+ "Wrong data size (%u), stream corrupted, aborting!",
- dataSize);
- ret = RTMP_READ_ERROR;
- break;
---
-1.7.10.4
-
-
-From 5d03a4f0d6216da92830306436eae7eb318d5115 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Mon, 14 Nov 2011 16:17:27 -0800
-Subject: [PATCH 28/64] Fix log messages
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index c37def2..34bfdba 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -686,7 +686,7 @@ void usage(char *prog)
- RTMP_LogPrintf
- ("--resume|-e Resume a partial RTMP download\n");
- RTMP_LogPrintf
-- ("--timeout|-m num Timeout connection num seconds (default: %lu)\n",
-+ ("--timeout|-m num Timeout connection num seconds (default: %u)\n",
- DEF_TIMEOUT);
- RTMP_LogPrintf
- ("--start|-A num Start at num seconds into stream (not valid when using --live)\n");
-@@ -699,7 +699,7 @@ void usage(char *prog)
- RTMP_LogPrintf
- ("--hashes|-# Display progress with hashes, not with the byte counter\n");
- RTMP_LogPrintf
-- ("--buffer|-b Buffer time in milliseconds (default: %lu)\n",
-+ ("--buffer|-b Buffer time in milliseconds (default: %u)\n",
- DEF_BUFTIME);
- RTMP_LogPrintf
- ("--skip|-k num Skip num keyframes when looking for last keyframe to resume from. Useful if resume fails (default: %d)\n\n",
-diff --git a/rtmpgw.c b/rtmpgw.c
-index 733e105..0cf56bb 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -563,7 +563,7 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- rtmp.Link.token = req.token;
- rtmp.m_read.timestamp = dSeek;
-
-- RTMP_LogPrintf("Connecting ... port: %d, app: %s\n", req.rtmpport, req.app);
-+ RTMP_LogPrintf("Connecting ... port: %d, app: %s\n", req.rtmpport, req.app.av_val);
- if (!RTMP_Connect(&rtmp, NULL))
- {
- RTMP_LogPrintf("%s, failed to connect!\n", __FUNCTION__);
-@@ -738,7 +738,7 @@ stopStreaming(STREAMING_SERVER * server)
-
- if (closesocket(server->socket))
- RTMP_Log(RTMP_LOGERROR, "%s: Failed to close listening socket, error %d",
-- GetSockError());
-+ __FUNCTION__, GetSockError());
-
- server->state = STREAMING_STOPPED;
- }
-@@ -1103,7 +1103,7 @@ main(int argc, char **argv)
- RTMP_LogPrintf
- ("--jtv|-j JSON Authentication token for Justin.tv legacy servers\n");
- RTMP_LogPrintf
-- ("--buffer|-b Buffer time in milliseconds (default: %lu)\n\n",
-+ ("--buffer|-b Buffer time in milliseconds (default: %u)\n\n",
- defaultRTMPRequest.bufferTime);
-
- RTMP_LogPrintf
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index 91fc4da..b662d54 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -765,7 +765,7 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
- {
- int ret = 0;
-
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received packet type %02X, size %lu bytes", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received packet type %02X, size %u bytes", __FUNCTION__,
- packet->m_packetType, packet->m_nBodySize);
-
- switch (packet->m_packetType)
-@@ -812,7 +812,7 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
-
- case 0x11: // flex message
- {
-- RTMP_Log(RTMP_LOGDEBUG, "%s, flex message, size %lu bytes, not fully supported",
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, flex message, size %u bytes, not fully supported",
- __FUNCTION__, packet->m_nBodySize);
- //RTMP_LogHex(packet.m_body, packet.m_nBodySize);
-
-@@ -840,7 +840,7 @@ ServePacket(STREAMING_SERVER *server, RTMP *r, RTMPPacket *packet)
-
- case 0x14:
- // invoke
-- RTMP_Log(RTMP_LOGDEBUG, "%s, received: invoke %lu bytes", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received: invoke %u bytes", __FUNCTION__,
- packet->m_nBodySize);
- //RTMP_LogHex(packet.m_body, packet.m_nBodySize);
-
-@@ -1053,7 +1053,7 @@ stopStreaming(STREAMING_SERVER * server)
-
- if (closesocket(server->socket))
- RTMP_Log(RTMP_LOGERROR, "%s: Failed to close listening socket, error %d",
-- GetSockError());
-+ __FUNCTION__, GetSockError());
-
- server->state = STREAMING_STOPPED;
- }
-diff --git a/rtmpsuck.c b/rtmpsuck.c
-index 661e64b..e886179 100644
---- a/rtmpsuck.c
-+++ b/rtmpsuck.c
-@@ -456,7 +456,7 @@ ServePacket(STREAMING_SERVER *server, int which, RTMPPacket *packet)
- {
- int ret = 0;
-
-- RTMP_Log(RTMP_LOGDEBUG, "%s, %s sent packet type %02X, size %lu bytes", __FUNCTION__,
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, %s sent packet type %02X, size %u bytes", __FUNCTION__,
- cst[which], packet->m_packetType, packet->m_nBodySize);
-
- switch (packet->m_packetType)
-@@ -649,7 +649,7 @@ WriteStream(char **buf, // target pointer, maybe preallocated
- if (pos + 11 + dataSize > nPacketLen)
- {
- RTMP_Log(RTMP_LOGERROR,
-- "Wrong data size (%lu), stream corrupted, aborting!",
-+ "Wrong data size (%u), stream corrupted, aborting!",
- dataSize);
- ret = -2;
- break;
-@@ -1117,7 +1117,7 @@ stopStreaming(STREAMING_SERVER * server)
-
- if (fd && closesocket(fd))
- RTMP_Log(RTMP_LOGERROR, "%s: Failed to close listening socket, error %d",
-- GetSockError());
-+ __FUNCTION__, GetSockError());
-
- server->state = STREAMING_STOPPED;
- }
---
-1.7.10.4
-
-
-From 4e06e218e230a86608637b613499984703a342cf Mon Sep 17 00:00:00 2001
-From: Antti Ajanki <antti.ajanki@iki.fi>
-Date: Thu, 22 Dec 2011 17:54:10 -0800
-Subject: [PATCH 29/64] Support decoding AMF_XML_DOC
-
-MF_XML_DOC data is an XML document which is encoded similarly to a
-long string.
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index f9ecf21..659421e 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -735,13 +735,15 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- break;
- }
- case AMF_LONG_STRING:
-+ case AMF_XML_DOC:
- {
- unsigned int nStringSize = AMF_DecodeInt32(pBuffer);
- if (nSize < (long)nStringSize + 4)
- return -1;
- AMF_DecodeLongString(pBuffer, &prop->p_vu.p_aval);
- nSize -= (4 + nStringSize);
-- prop->p_type = AMF_STRING;
-+ if (prop->p_type == AMF_LONG_STRING)
-+ prop->p_type = AMF_STRING;
- break;
- }
- case AMF_RECORDSET:
-@@ -750,12 +752,6 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- return -1;
- break;
- }
-- case AMF_XML_DOC:
-- {
-- RTMP_Log(RTMP_LOGERROR, "AMF_XML_DOC not supported!");
-- return -1;
-- break;
-- }
- case AMF_TYPED_OBJECT:
- {
- RTMP_Log(RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!");
---
-1.7.10.4
-
-
-From adb77ff4d72cea92b7c307ccb64e9aa930d866da Mon Sep 17 00:00:00 2001
-From: Joshua Allmann <joshua.allmann@gmail.com>
-Date: Fri, 24 Feb 2012 13:44:29 -0800
-Subject: [PATCH 30/64] Remove extra object end tag in Connect reply
-
-
-diff --git a/rtmpsrv.c b/rtmpsrv.c
-index b662d54..9aa62f3 100644
---- a/rtmpsrv.c
-+++ b/rtmpsrv.c
-@@ -223,9 +223,6 @@ SendConnectResult(RTMP *r, double txn)
- *enc++ = 0;
- *enc++ = 0;
- *enc++ = AMF_OBJECT_END;
-- *enc++ = 0;
-- *enc++ = 0;
-- *enc++ = AMF_OBJECT_END;
-
- packet.m_nBodySize = enc - packet.m_body;
-
---
-1.7.10.4
-
-
-From 2ad1d5d133a46ceeaaa05c9375e293f332871f3b Mon Sep 17 00:00:00 2001
-From: Josh Allmann <joshua.allmann@gmail.com>
-Date: Fri, 24 Feb 2012 13:46:59 -0800
-Subject: [PATCH 31/64] Fix upper bound check in AMF_GetProp
-
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index 659421e..ce84f81 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -1121,7 +1121,7 @@ AMF_GetProp(AMFObject *obj, const AVal *name, int nIndex)
- {
- if (nIndex >= 0)
- {
-- if (nIndex <= obj->o_num)
-+ if (nIndex < obj->o_num)
- return &obj->o_props[nIndex];
- }
- else
---
-1.7.10.4
-
-
-From eea470fa5f9a5481a36dedd257549595ef7480d6 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Thu, 8 Mar 2012 23:10:11 -0800
-Subject: [PATCH 32/64] Add support for building with gnutls with nettle as
- backend
-
-
-diff --git a/Makefile b/Makefile
-index 6ef5742..0cf41be 100644
---- a/Makefile
-+++ b/Makefile
-@@ -13,6 +13,7 @@ CRYPTO=OPENSSL
- #CRYPTO=GNUTLS
- LIBZ=-lz
- LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ)
-+LIB_GNUTLS_NETTLE=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
- LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
- LIB_POLARSSL=-lpolarssl $(LIBZ)
- CRYPTO_LIB=$(LIB_$(CRYPTO))
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index a0125f1..353c6c8 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -21,14 +21,17 @@ CRYPTO=OPENSSL
- DEF_POLARSSL=-DUSE_POLARSSL
- DEF_OPENSSL=-DUSE_OPENSSL
- DEF_GNUTLS=-DUSE_GNUTLS
-+DEF_GNUTLS_NETTLE=-DUSE_GNUTLS_NETTLE
- DEF_=-DNO_CRYPTO
- REQ_GNUTLS=gnutls
-+REQ_GNUTLS_NETTLE=gnutls
- REQ_OPENSSL=libssl,libcrypto
- LIBZ=-lz
- LIBS_posix=
- LIBS_darwin=
- LIBS_mingw=-lws2_32 -lwinmm -lgdi32
- LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ)
-+LIB_GNUTLS_NETTLE=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
- LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
- LIB_POLARSSL=-lpolarssl $(LIBZ)
- PRIVATE_LIBS=$(LIBS_$(SYS))
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index a9f3763..830000e 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -76,7 +76,8 @@ static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
- return 0;
- }
-
--#elif defined(USE_GNUTLS)
-+#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
-+#ifdef USE_GNUTLS
- #include <gcrypt.h>
- typedef gcry_mpi_t MP_t;
- #define MP_new(m) m = gcry_mpi_new(1)
-@@ -91,6 +92,23 @@ typedef gcry_mpi_t MP_t;
- #define MP_bytes(u) (gcry_mpi_get_nbits(u) + 7) / 8
- #define MP_setbin(u,buf,len) gcry_mpi_print(GCRYMPI_FMT_USG,buf,len,NULL,u)
- #define MP_getbin(u,buf,len) gcry_mpi_scan(&u,GCRYMPI_FMT_USG,buf,len,NULL)
-+#else
-+#include <gmp.h>
-+#include <nettle/bignum.h>
-+typedef mpz_ptr MP_t;
-+#define MP_new(m) m = malloc(sizeof(*m)); mpz_init2(m, 1)
-+#define MP_set_w(mpi, w) mpz_set_ui(mpi, w)
-+#define MP_cmp(u, v) mpz_cmp(u, v)
-+#define MP_set(u, v) mpz_set(u, v)
-+#define MP_sub_w(mpi, w) mpz_sub_ui(mpi, mpi, w)
-+#define MP_cmp_1(mpi) mpz_cmp_ui(mpi, 1)
-+#define MP_modexp(r, y, q, p) mpz_powm(r, y, q, p)
-+#define MP_free(mpi) mpz_clear(mpi); free(mpi)
-+#define MP_gethex(u, hex, res) u = malloc(sizeof(*u)); mpz_init2(u, 1); res = (mpz_set_str(u, hex, 16) == 0)
-+#define MP_bytes(u) (mpz_sizeinbase(u, 2) + 7) / 8
-+#define MP_setbin(u,buf,len) nettle_mpz_get_str_256(len,buf,u)
-+#define MP_getbin(u,buf,len) u = malloc(sizeof(*u)); mpz_init2(u, 1); nettle_mpz_set_str_256_u(u,len,buf)
-+#endif
-
- typedef struct MDH {
- MP_t p;
-diff --git a/librtmp/handshake.h b/librtmp/handshake.h
-index 98bf3c8..4c2ea7f 100644
---- a/librtmp/handshake.h
-+++ b/librtmp/handshake.h
-@@ -59,6 +59,26 @@ typedef gcry_cipher_hd_t RC4_handle;
- #define RC4_encrypt2(h,l,s,d) gcry_cipher_encrypt(h,(void *)d,l,(void *)s,l)
- #define RC4_free(h) gcry_cipher_close(h)
-
-+#elif defined(USE_GNUTLS_NETTLE)
-+#include <nettle/hmac.h>
-+#include <nettle/arcfour.h>
-+#ifndef SHA256_DIGEST_LENGTH
-+#define SHA256_DIGEST_LENGTH 32
-+#endif
-+#undef HMAC_CTX
-+#define HMAC_CTX struct hmac_sha256_ctx
-+#define HMAC_setup(ctx, key, len) hmac_sha256_set_key(&ctx, len, key)
-+#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)
-+
-+typedef struct arcfour_ctx* RC4_handle;
-+#define RC4_alloc(h) *h = malloc(sizeof(struct arcfour_ctx))
-+#define RC4_setkey(h,l,k) arcfour_set_key(h, l, k)
-+#define RC4_encrypt(h,l,d) arcfour_crypt(h,l,(uint8_t *)d,(uint8_t *)d)
-+#define RC4_encrypt2(h,l,s,d) arcfour_crypt(h,l,(uint8_t *)d,(uint8_t *)s)
-+#define RC4_free(h) free(h)
-+
- #else /* USE_OPENSSL */
- #include <openssl/sha.h>
- #include <openssl/hmac.h>
-diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c
-index 0320480..8cefd3b 100644
---- a/librtmp/hashswf.c
-+++ b/librtmp/hashswf.c
-@@ -52,6 +52,17 @@
- #define HMAC_crunch(ctx, buf, len) gcry_md_write(ctx, buf, len)
- #define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen)
- #define HMAC_close(ctx) gcry_md_close(ctx)
-+#elif defined(USE_GNUTLS_NETTLE)
-+#include <nettle/hmac.h>
-+#ifndef SHA256_DIGEST_LENGTH
-+#define SHA256_DIGEST_LENGTH 32
-+#endif
-+#undef HMAC_CTX
-+#define HMAC_CTX struct hmac_sha256_ctx
-+#define HMAC_setup(ctx, key, len) hmac_sha256_set_key(&ctx, len, key)
-+#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>
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 52d0254..5cd7b8d 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -34,7 +34,7 @@
- #ifdef CRYPTO
- #ifdef USE_POLARSSL
- #include <polarssl/havege.h>
--#elif defined(USE_GNUTLS)
-+#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
- #include <gnutls/gnutls.h>
- #else /* USE_OPENSSL */
- #include <openssl/ssl.h>
-@@ -204,7 +204,7 @@ RTMP_TLS_Init()
- /* 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);
--#elif defined(USE_GNUTLS) && !defined(NO_SSL)
-+#elif (defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)) && !defined(NO_SSL)
- /* Technically we need to initialize libgcrypt ourselves if
- * we're not going to call gnutls_global_init(). Ignoring this
- * for now.
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index c3fd4a6..478c59f 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -81,7 +81,7 @@ typedef struct tls_ctx {
- #define TLS_shutdown(s) ssl_close_notify(s)
- #define TLS_close(s) ssl_free(s); free(s)
-
--#elif defined(USE_GNUTLS)
-+#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
- #include <gnutls/gnutls.h>
- typedef struct tls_ctx {
- gnutls_certificate_credentials_t cred;
---
-1.7.10.4
-
-
-From 7340f6dbc6b3c8e552baab2e5a891c2de75cddcc Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Thu, 8 Mar 2012 23:19:45 -0800
-Subject: [PATCH 33/64] Cleanup prev commit, drop gcrypt support
-
-
-diff --git a/Makefile b/Makefile
-index 0cf41be..a1595a8 100644
---- a/Makefile
-+++ b/Makefile
-@@ -12,8 +12,7 @@ CRYPTO=OPENSSL
- #CRYPTO=POLARSSL
- #CRYPTO=GNUTLS
- LIBZ=-lz
--LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ)
--LIB_GNUTLS_NETTLE=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
-+LIB_GNUTLS=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
- LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
- LIB_POLARSSL=-lpolarssl $(LIBZ)
- CRYPTO_LIB=$(LIB_$(CRYPTO))
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index 353c6c8..74ee3b5 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -21,17 +21,14 @@ CRYPTO=OPENSSL
- DEF_POLARSSL=-DUSE_POLARSSL
- DEF_OPENSSL=-DUSE_OPENSSL
- DEF_GNUTLS=-DUSE_GNUTLS
--DEF_GNUTLS_NETTLE=-DUSE_GNUTLS_NETTLE
- DEF_=-DNO_CRYPTO
- REQ_GNUTLS=gnutls
--REQ_GNUTLS_NETTLE=gnutls
- REQ_OPENSSL=libssl,libcrypto
- LIBZ=-lz
- LIBS_posix=
- LIBS_darwin=
- LIBS_mingw=-lws2_32 -lwinmm -lgdi32
--LIB_GNUTLS=-lgnutls -lgcrypt $(LIBZ)
--LIB_GNUTLS_NETTLE=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
-+LIB_GNUTLS=-lgnutls -lhogweed -lnettle -lgmp $(LIBZ)
- LIB_OPENSSL=-lssl -lcrypto $(LIBZ)
- LIB_POLARSSL=-lpolarssl $(LIBZ)
- PRIVATE_LIBS=$(LIBS_$(SYS))
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index 830000e..9959532 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -76,23 +76,7 @@ static int MDH_compute_key(uint8_t *secret, size_t len, MP_t pub, MDH *dh)
- return 0;
- }
-
--#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
--#ifdef USE_GNUTLS
--#include <gcrypt.h>
--typedef gcry_mpi_t MP_t;
--#define MP_new(m) m = gcry_mpi_new(1)
--#define MP_set_w(mpi, w) gcry_mpi_set_ui(mpi, w)
--#define MP_cmp(u, v) gcry_mpi_cmp(u, v)
--#define MP_set(u, v) gcry_mpi_set(u, v)
--#define MP_sub_w(mpi, w) gcry_mpi_sub_ui(mpi, mpi, w)
--#define MP_cmp_1(mpi) gcry_mpi_cmp_ui(mpi, 1)
--#define MP_modexp(r, y, q, p) gcry_mpi_powm(r, y, q, p)
--#define MP_free(mpi) gcry_mpi_release(mpi)
--#define MP_gethex(u, hex, res) res = (gcry_mpi_scan(&u, GCRYMPI_FMT_HEX, hex, 0, 0) == 0)
--#define MP_bytes(u) (gcry_mpi_get_nbits(u) + 7) / 8
--#define MP_setbin(u,buf,len) gcry_mpi_print(GCRYMPI_FMT_USG,buf,len,NULL,u)
--#define MP_getbin(u,buf,len) gcry_mpi_scan(&u,GCRYMPI_FMT_USG,buf,len,NULL)
--#else
-+#elif defined(USE_GNUTLS)
- #include <gmp.h>
- #include <nettle/bignum.h>
- typedef mpz_ptr MP_t;
-@@ -108,7 +92,6 @@ typedef mpz_ptr MP_t;
- #define MP_bytes(u) (mpz_sizeinbase(u, 2) + 7) / 8
- #define MP_setbin(u,buf,len) nettle_mpz_get_str_256(len,buf,u)
- #define MP_getbin(u,buf,len) u = malloc(sizeof(*u)); mpz_init2(u, 1); nettle_mpz_set_str_256_u(u,len,buf)
--#endif
-
- typedef struct MDH {
- MP_t p;
-diff --git a/librtmp/handshake.h b/librtmp/handshake.h
-index 4c2ea7f..0438486 100644
---- a/librtmp/handshake.h
-+++ b/librtmp/handshake.h
-@@ -43,27 +43,10 @@ typedef arc4_context * RC4_handle;
- #define RC4_free(h) free(h)
-
- #elif defined(USE_GNUTLS)
--#include <gcrypt.h>
--#ifndef SHA256_DIGEST_LENGTH
--#define SHA256_DIGEST_LENGTH 32
--#endif
--#define HMAC_CTX gcry_md_hd_t
--#define HMAC_setup(ctx, key, len) gcry_md_open(&ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); gcry_md_setkey(ctx, key, len)
--#define HMAC_crunch(ctx, buf, len) gcry_md_write(ctx, buf, len)
--#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen); gcry_md_close(ctx)
--
--typedef gcry_cipher_hd_t RC4_handle;
--#define RC4_alloc(h) gcry_cipher_open(h, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)
--#define RC4_setkey(h,l,k) gcry_cipher_setkey(h,k,l)
--#define RC4_encrypt(h,l,d) gcry_cipher_encrypt(h,(void *)d,l,NULL,0)
--#define RC4_encrypt2(h,l,s,d) gcry_cipher_encrypt(h,(void *)d,l,(void *)s,l)
--#define RC4_free(h) gcry_cipher_close(h)
--
--#elif defined(USE_GNUTLS_NETTLE)
- #include <nettle/hmac.h>
- #include <nettle/arcfour.h>
- #ifndef SHA256_DIGEST_LENGTH
--#define SHA256_DIGEST_LENGTH 32
-+#define SHA256_DIGEST_LENGTH 32
- #endif
- #undef HMAC_CTX
- #define HMAC_CTX struct hmac_sha256_ctx
-diff --git a/librtmp/hashswf.c b/librtmp/hashswf.c
-index 8cefd3b..9f4e2c0 100644
---- a/librtmp/hashswf.c
-+++ b/librtmp/hashswf.c
-@@ -42,17 +42,6 @@
- #define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig)
- #define HMAC_close(ctx)
- #elif defined(USE_GNUTLS)
--#include <gnutls/gnutls.h>
--#include <gcrypt.h>
--#ifndef SHA256_DIGEST_LENGTH
--#define SHA256_DIGEST_LENGTH 32
--#endif
--#define HMAC_CTX gcry_md_hd_t
--#define HMAC_setup(ctx, key, len) gcry_md_open(&ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); gcry_md_setkey(ctx, key, len)
--#define HMAC_crunch(ctx, buf, len) gcry_md_write(ctx, buf, len)
--#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; memcpy(dig, gcry_md_read(ctx, 0), dlen)
--#define HMAC_close(ctx) gcry_md_close(ctx)
--#elif defined(USE_GNUTLS_NETTLE)
- #include <nettle/hmac.h>
- #ifndef SHA256_DIGEST_LENGTH
- #define SHA256_DIGEST_LENGTH 32
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 5cd7b8d..52d0254 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -34,7 +34,7 @@
- #ifdef CRYPTO
- #ifdef USE_POLARSSL
- #include <polarssl/havege.h>
--#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
-+#elif defined(USE_GNUTLS)
- #include <gnutls/gnutls.h>
- #else /* USE_OPENSSL */
- #include <openssl/ssl.h>
-@@ -204,7 +204,7 @@ RTMP_TLS_Init()
- /* 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);
--#elif (defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)) && !defined(NO_SSL)
-+#elif defined(USE_GNUTLS) && !defined(NO_SSL)
- /* Technically we need to initialize libgcrypt ourselves if
- * we're not going to call gnutls_global_init(). Ignoring this
- * for now.
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index 478c59f..c3fd4a6 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -81,7 +81,7 @@ typedef struct tls_ctx {
- #define TLS_shutdown(s) ssl_close_notify(s)
- #define TLS_close(s) ssl_free(s); free(s)
-
--#elif defined(USE_GNUTLS) || defined(USE_GNUTLS_NETTLE)
-+#elif defined(USE_GNUTLS)
- #include <gnutls/gnutls.h>
- typedef struct tls_ctx {
- gnutls_certificate_credentials_t cred;
---
-1.7.10.4
-
-
-From 603ff20e9e717a70b5b0c011f3413cf376d0c2f6 Mon Sep 17 00:00:00 2001
-From: Ulrik Dickow <u.dickow@gmail.com>
-Date: Thu, 26 Jul 2012 04:57:23 -0700
-Subject: [PATCH 34/64] Add .gitignore to ignore generated files
-
-
-diff --git a/.gitignore b/.gitignore
-new file mode 100644
-index 0000000..c7ec44f
---- /dev/null
-+++ b/.gitignore
-@@ -0,0 +1,9 @@
-+*.[oa]
-+*.exe
-+*.so
-+*.so.[0-9]
-+*.dylib
-+rtmpdump
-+rtmpgw
-+rtmpsrv
-+rtmpsuck
---
-1.7.10.4
-
-
-From e0056c51cc1710c9a44d2a2c4e2f344fa9cabcf4 Mon Sep 17 00:00:00 2001
-From: Ulrik Dickow <u.dickow@gmail.com>
-Date: Tue, 24 Jul 2012 17:17:26 +0200
-Subject: [PATCH 35/64] Add option --realtime (-R) to rtmpdump to disable the
- BUFX hack
-
-
-diff --git a/rtmpdump.1 b/rtmpdump.1
-index 0d9de8d..7bb5328 100644
---- a/rtmpdump.1
-+++ b/rtmpdump.1
-@@ -1,4 +1,4 @@
--.TH RTMPDUMP 1 "2011-07-20" "RTMPDump v2.4"
-+.TH RTMPDUMP 1 "2012-07-24" "RTMPDump v2.4"
- .\" Copyright 2011 Howard Chu.
- .\" Copying permitted according to the GNU General Public License V2.
- .SH NAME
-@@ -177,6 +177,12 @@ live streams is possible.
- Name of live stream to subscribe to. Defaults to
- .IR playpath .
- .TP
-+.B \-\-realtime \-R
-+Download approximately in realtime, without attempting to speed up via
-+Pause/Unpause commands ("the BUFX hack").
-+Useful for servers that jump backwards in time at the Unpause command.
-+Resuming and seeking in realtime streams is still possible.
-+.TP
- .B \-\-resume \-e
- Resume an incomplete RTMP download.
- .TP
-diff --git a/rtmpdump.1.html b/rtmpdump.1.html
-index 826f722..4c39b35 100644
---- a/rtmpdump.1.html
-+++ b/rtmpdump.1.html
-@@ -6,7 +6,7 @@
- <tr><td>RTMPDUMP(1)<td align="center"><td align="right">RTMPDUMP(1)
- </thead>
- <tfoot>
--<tr><td>RTMPDump v2.4<td align="center">2011-07-20<td align="right">RTMPDUMP(1)
-+<tr><td>RTMPDump v2.4<td align="center">2012-07-24<td align="right">RTMPDUMP(1)
- </tfoot>
- <tbody><tr><td colspan="3"><br><br><ul>
- <!-- Copyright 2011 Howard Chu.
-@@ -34,6 +34,7 @@ rtmpdump &minus; RTMP streaming media client
- [<b>&minus;y</b><i>&nbsp;playpath</i>]
- [<b>&minus;Y</b>]
- [<b>&minus;v</b>]
-+[<b>&minus;R</b>]
- [<b>&minus;d</b><i>&nbsp;subscription</i>]
- [<b>&minus;e</b>]
- [<b>&minus;k</b><i>&nbsp;skip</i>]
-@@ -218,6 +219,15 @@ Name of live stream to subscribe to. Defaults to
- </dl>
- <p>
- <dl compact><dt>
-+<b>&minus;&minus;realtime &minus;R</b>
-+<dd>
-+Download approximately in realtime, without attempting to speed up via
-+Pause/Unpause commands (&quot;the BUFX hack&quot;).
-+Useful for servers that jump backwards in time at the Unpause command.
-+Resuming and seeking in realtime streams is still possible.
-+</dl>
-+<p>
-+<dl compact><dt>
- <b>&minus;&minus;resume &minus;e</b>
- <dd>
- Resume an incomplete RTMP download.
-diff --git a/rtmpdump.c b/rtmpdump.c
-index 34bfdba..e52f7d4 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -441,7 +441,7 @@ GetLastKeyframe(FILE * file, // output file [in]
-
- int
- Download(RTMP * rtmp, // connected RTMP object
-- FILE * file, uint32_t dSeek, uint32_t dStopOffset, double duration, int bResume, char *metaHeader, uint32_t nMetaHeaderSize, char *initialFrame, int initialFrameType, uint32_t nInitialFrameSize, int nSkipKeyFrames, int bStdoutMode, int bLiveStream, int bHashes, int bOverrideBufferTime, uint32_t bufferTime, double *percent) // percentage downloaded [out]
-+ FILE * file, uint32_t dSeek, uint32_t dStopOffset, double duration, int bResume, char *metaHeader, uint32_t nMetaHeaderSize, char *initialFrame, int initialFrameType, uint32_t nInitialFrameSize, int nSkipKeyFrames, int bStdoutMode, int bLiveStream, int bRealtimeStream, int bHashes, int bOverrideBufferTime, uint32_t bufferTime, double *percent) // percentage downloaded [out]
- {
- int32_t now, lastUpdate;
- int bufferSize = 64 * 1024;
-@@ -492,6 +492,8 @@ Download(RTMP * rtmp, // connected RTMP object
- bResume ? "Resuming" : "Starting",
- (double) size / 1024.0);
- }
-+ if (bRealtimeStream)
-+ RTMP_LogPrintf(" in approximately realtime (disabled BUFX speedup hack)\n");
- }
-
- if (dStopOffset > 0)
-@@ -682,6 +684,8 @@ void usage(char *prog)
- RTMP_LogPrintf
- ("--subscribe|-d string Stream name to subscribe to (otherwise defaults to playpath if live is specifed)\n");
- RTMP_LogPrintf
-+ ("--realtime|-R Don't attempt to speed up download via the Pause/Unpause BUFX hack\n");
-+ RTMP_LogPrintf
- ("--flv|-o string FLV output file name, if the file name is - print stream to stdout\n");
- RTMP_LogPrintf
- ("--resume|-e Resume a partial RTMP download\n");
-@@ -748,6 +752,7 @@ main(int argc, char **argv)
- int protocol = RTMP_PROTOCOL_UNDEFINED;
- int retries = 0;
- int bLiveStream = FALSE; // is it a live stream? then we can't seek/resume
-+ int bRealtimeStream = FALSE; // If true, disable the BUFX hack (be patient)
- int bHashes = FALSE; // display byte counters not hashes by default
-
- long int timeout = DEF_TIMEOUT; // timeout connection after 120 seconds
-@@ -832,6 +837,7 @@ main(int argc, char **argv)
- #endif
- {"flashVer", 1, NULL, 'f'},
- {"live", 0, NULL, 'v'},
-+ {"realtime", 0, NULL, 'R'},
- {"flv", 1, NULL, 'o'},
- {"resume", 0, NULL, 'e'},
- {"timeout", 1, NULL, 'm'},
-@@ -851,7 +857,7 @@ main(int argc, char **argv)
-
- while ((opt =
- getopt_long(argc, argv,
-- "hVveqzr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
-+ "hVveqzRr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
- longopts, NULL)) != -1)
- {
- switch (opt)
-@@ -936,6 +942,9 @@ main(int argc, char **argv)
- case 'v':
- bLiveStream = TRUE; // no seeking or resuming possible!
- break;
-+ case 'R':
-+ bRealtimeStream = TRUE; // seeking and resuming is still possible
-+ break;
- case 'd':
- STR2AVAL(subscribepath, optarg);
- break;
-@@ -1181,7 +1190,7 @@ main(int argc, char **argv)
- &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout);
-
- /* Try to keep the stream moving if it pauses on us */
-- if (!bLiveStream && !(protocol & RTMP_FEATURE_HTTP))
-+ if (!bLiveStream && !bRealtimeStream && !(protocol & RTMP_FEATURE_HTTP))
- rtmp.Link.lFlags |= RTMP_LF_BUFX;
-
- off_t size = 0;
-@@ -1348,8 +1357,8 @@ main(int argc, char **argv)
-
- nStatus = Download(&rtmp, file, dSeek, dStopOffset, duration, bResume,
- metaHeader, nMetaHeaderSize, initialFrame,
-- initialFrameType, nInitialFrameSize,
-- nSkipKeyFrames, bStdoutMode, bLiveStream, bHashes,
-+ initialFrameType, nInitialFrameSize, nSkipKeyFrames,
-+ bStdoutMode, bLiveStream, bRealtimeStream, bHashes,
- bOverrideBufferTime, bufferTime, &percent);
- free(initialFrame);
- initialFrame = NULL;
---
-1.7.10.4
-
-
-From 87d47b876f818fe5c949e08c699238bc22a3c7b1 Mon Sep 17 00:00:00 2001
-From: Bastien Nocera <hadess@hadess.net>
-Date: Tue, 30 Oct 2012 08:16:36 -0700
-Subject: [PATCH 36/64] Make rtmpdump handle full RTMP URLs with "-i"
-
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index e52f7d4..2b30eb2 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -640,6 +640,8 @@ void usage(char *prog)
- ("\n%s: This program dumps the media content streamed over RTMP.\n\n", prog);
- RTMP_LogPrintf("--help|-h Prints this help screen.\n");
- RTMP_LogPrintf
-+ ("--url|-i url URL with options included (e.g. rtmp://host[:port]/path swfUrl=url tcUrl=url)\n");
-+ RTMP_LogPrintf
- ("--rtmp|-r url URL (e.g. rtmp://host[:port]/path)\n");
- RTMP_LogPrintf
- ("--host|-n hostname Overrides the hostname in the rtmp url\n");
-@@ -760,6 +762,7 @@ main(int argc, char **argv)
- uint32_t dStopOffset = 0;
- RTMP rtmp = { 0 };
-
-+ AVal fullUrl = { 0, 0 };
- AVal swfUrl = { 0, 0 };
- AVal tcUrl = { 0, 0 };
- AVal pageUrl = { 0, 0 };
-@@ -822,6 +825,7 @@ main(int argc, char **argv)
- {"protocol", 1, NULL, 'l'},
- {"playpath", 1, NULL, 'y'},
- {"playlist", 0, NULL, 'Y'},
-+ {"url", 1, NULL, 'i'},
- {"rtmp", 1, NULL, 'r'},
- {"swfUrl", 1, NULL, 's'},
- {"tcUrl", 1, NULL, 't'},
-@@ -857,7 +861,7 @@ main(int argc, char **argv)
-
- while ((opt =
- getopt_long(argc, argv,
-- "hVveqzRr:s:t:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
-+ "hVveqzRr:s:t:i:p:a:b:f:o:u:C:n:c:l:y:Ym:k:d:A:B:T:w:x:W:X:S:#j:",
- longopts, NULL)) != -1)
- {
- switch (opt)
-@@ -1000,6 +1004,9 @@ main(int argc, char **argv)
- }
- break;
- }
-+ case 'i':
-+ STR2AVAL(fullUrl, optarg);
-+ break;
- case 's':
- STR2AVAL(swfUrl, optarg);
- break;
-@@ -1078,32 +1085,32 @@ main(int argc, char **argv)
- }
- }
-
-- if (!hostname.av_len)
-+ if (!hostname.av_len && !fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGERROR,
- "You must specify a hostname (--host) or url (-r \"rtmp://host[:port]/playpath\") containing a hostname");
- return RD_FAILED;
- }
-- if (playpath.av_len == 0)
-+ if (playpath.av_len == 0 && !fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGERROR,
- "You must specify a playpath (--playpath) or url (-r \"rtmp://host[:port]/playpath\") containing a playpath");
- return RD_FAILED;
- }
-
-- if (protocol == RTMP_PROTOCOL_UNDEFINED)
-+ if (protocol == RTMP_PROTOCOL_UNDEFINED && !fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGWARNING,
- "You haven't specified a protocol (--protocol) or rtmp url (-r), using default protocol RTMP");
- protocol = RTMP_PROTOCOL_RTMP;
- }
-- if (port == -1)
-+ if (port == -1 && !fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGWARNING,
- "You haven't specified a port (--port) or rtmp url (-r), using default port 1935");
- port = 0;
- }
-- if (port == 0)
-+ if (port == 0 && !fullUrl.av_len)
- {
- if (protocol & RTMP_FEATURE_SSL)
- port = 443;
-@@ -1185,9 +1192,20 @@ main(int argc, char **argv)
- }
- }
-
-- RTMP_SetupStream(&rtmp, protocol, &hostname, port, &sockshost, &playpath,
-- &tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize,
-- &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout);
-+ if (!fullUrl.av_len)
-+ {
-+ RTMP_SetupStream(&rtmp, protocol, &hostname, port, &sockshost, &playpath,
-+ &tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize,
-+ &flashVer, &subscribepath, &usherToken, dSeek, dStopOffset, bLiveStream, timeout);
-+ }
-+ else
-+ {
-+ if (RTMP_SetupURL(&rtmp, fullUrl.av_val) == FALSE)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "Couldn't parse URL: %s", fullUrl.av_val);
-+ return RD_FAILED;
-+ }
-+ }
-
- /* Try to keep the stream moving if it pauses on us */
- if (!bLiveStream && !bRealtimeStream && !(protocol & RTMP_FEATURE_HTTP))
---
-1.7.10.4
-
-
-From 3fcbcb9a0bae6de03401f32939d3d243cdd7b865 Mon Sep 17 00:00:00 2001
-From: Bastien Nocera <hadess@hadess.net>
-Date: Thu, 19 Jul 2012 17:22:03 +0100
-Subject: [PATCH 37/64] Make rtmpgw handle full RTMP URLs with "-i"
-
-or --url. Just as rtmpdump and librtmp already can.
-
-diff --git a/rtmpgw.c b/rtmpgw.c
-index 0cf56bb..ab255d4 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -85,6 +85,7 @@ typedef struct
- uint32_t bufferTime;
-
- char *rtmpurl;
-+ AVal fullUrl;
- AVal playpath;
- AVal swfUrl;
- AVal tcUrl;
-@@ -469,14 +470,14 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- }
-
- // do necessary checks right here to make sure the combined request of default values and GET parameters is correct
-- if (!req.hostname.av_len)
-+ if (!req.hostname.av_len && !req.fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGERROR,
- "You must specify a hostname (--host) or url (-r \"rtmp://host[:port]/playpath\") containing a hostname");
- status = "400 Missing Hostname";
- goto filenotfound;
- }
-- if (req.playpath.av_len == 0)
-+ if (req.playpath.av_len == 0 && !req.fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGERROR,
- "You must specify a playpath (--playpath) or url (-r \"rtmp://host[:port]/playpath\") containing a playpath");
-@@ -484,19 +485,19 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- goto filenotfound;;
- }
-
-- if (req.protocol == RTMP_PROTOCOL_UNDEFINED)
-+ if (req.protocol == RTMP_PROTOCOL_UNDEFINED && !req.fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGWARNING,
- "You haven't specified a protocol (--protocol) or rtmp url (-r), using default protocol RTMP");
- req.protocol = RTMP_PROTOCOL_RTMP;
- }
-- if (req.rtmpport == -1)
-+ if (req.rtmpport == -1 && !req.fullUrl.av_len)
- {
- RTMP_Log(RTMP_LOGWARNING,
- "You haven't specified a port (--port) or rtmp url (-r), using default port");
- req.rtmpport = 0;
- }
-- if (req.rtmpport == 0)
-+ if (req.rtmpport == 0 && !req.fullUrl.av_len)
- {
- if (req.protocol & RTMP_FEATURE_SSL)
- req.rtmpport = 443;
-@@ -552,9 +553,20 @@ void processTCPrequest(STREAMING_SERVER * server, // server socket and state (ou
- RTMP_Log(RTMP_LOGDEBUG, "Setting buffer time to: %dms", req.bufferTime);
- RTMP_Init(&rtmp);
- RTMP_SetBufferMS(&rtmp, req.bufferTime);
-- RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost,
-- &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, dSeek, req.dStopOffset,
-- req.bLiveStream, req.timeout);
-+ if (!req.fullUrl.av_len)
-+ {
-+ RTMP_SetupStream(&rtmp, req.protocol, &req.hostname, req.rtmpport, &req.sockshost,
-+ &req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, &req.usherToken, dSeek, req.dStopOffset,
-+ req.bLiveStream, req.timeout);
-+ }
-+ else
-+ {
-+ if (RTMP_SetupURL(&rtmp, req.fullUrl.av_val) == FALSE)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "Couldn't parse URL: %s", req.fullUrl.av_val);
-+ return;
-+ }
-+ }
- /* backward compatibility, we always sent this as true before */
- if (req.auth.av_len)
- rtmp.Link.lFlags |= RTMP_LF_AUTH;
-@@ -908,6 +920,9 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
- }
- break;
- }
-+ case 'i':
-+ STR2AVAL(req->fullUrl, optarg);
-+ break;
- case 's':
- STR2AVAL(req->swfUrl, arg);
- break;
-@@ -993,6 +1008,7 @@ main(int argc, char **argv)
- int opt;
- struct option longopts[] = {
- {"help", 0, NULL, 'h'},
-+ {"url", 1, NULL, 'i'},
- {"host", 1, NULL, 'n'},
- {"port", 1, NULL, 'c'},
- {"socks", 1, NULL, 'S'},
-@@ -1040,7 +1056,7 @@ main(int argc, char **argv)
-
- while ((opt =
- getopt_long(argc, argv,
-- "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:", longopts,
-+ "hvqVzr:s:t:i:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:W:X:S:j:", longopts,
- NULL)) != -1)
- {
- switch (opt)
-@@ -1050,6 +1066,8 @@ main(int argc, char **argv)
- ("\nThis program serves media content streamed from RTMP onto HTTP.\n\n");
- RTMP_LogPrintf("--help|-h Prints this help screen.\n");
- RTMP_LogPrintf
-+ ("--url|-i url URL with options included (e.g. rtmp://host[:port]/path swfUrl=url tcUrl=url)\n");
-+ RTMP_LogPrintf
- ("--rtmp|-r url URL (e.g. rtmp://host[:port]/path)\n");
- RTMP_LogPrintf
- ("--host|-n hostname Overrides the hostname in the rtmp url\n");
---
-1.7.10.4
-
-
-From 75a6167863bc415845b9130d6f8f437cbdc185f7 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 08:20:14 -0700
-Subject: [PATCH 38/64] Fix bogus optarg refs in prev commit
-
-
-diff --git a/rtmpgw.c b/rtmpgw.c
-index ab255d4..3e47602 100644
---- a/rtmpgw.c
-+++ b/rtmpgw.c
-@@ -921,7 +921,7 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
- break;
- }
- case 'i':
-- STR2AVAL(req->fullUrl, optarg);
-+ STR2AVAL(req->fullUrl, arg);
- break;
- case 's':
- STR2AVAL(req->swfUrl, arg);
-@@ -942,7 +942,7 @@ ParseOption(char opt, char *arg, RTMP_REQUEST * req)
- STR2AVAL(req->auth, arg);
- break;
- case 'C':
-- parseAMF(&req->extras, optarg, &req->edepth);
-+ parseAMF(&req->extras, arg, &req->edepth);
- break;
- case 'm':
- req->timeout = atoi(arg);
---
-1.7.10.4
-
-
-From dc1ddd3b3f567c036f6909af7f1bfdc135331439 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 08:28:15 -0700
-Subject: [PATCH 39/64] Fix rare infinite loop on EOF
-
-reported by Matt Robison <rtmpdump@nerdoftheherd.com>
-
-diff --git a/rtmpdump.c b/rtmpdump.c
-index 2b30eb2..13741a7 100644
---- a/rtmpdump.c
-+++ b/rtmpdump.c
-@@ -580,12 +580,14 @@ Download(RTMP * rtmp, // connected RTMP object
- }
- }
- }
--#ifdef _DEBUG
- else
- {
-+#ifdef _DEBUG
- RTMP_Log(RTMP_LOGDEBUG, "zero read!");
-- }
- #endif
-+ if (rtmp->m_read.status == RTMP_READ_EOF)
-+ break;
-+ }
-
- }
- while (!RTMP_ctrlC && nRead > -1 && RTMP_IsConnected(rtmp) && !RTMP_IsTimedout(rtmp));
---
-1.7.10.4
-
-
-From a312ac7770207bd7d07725c1aef43725206e803a Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 08:41:49 -0700
-Subject: [PATCH 40/64] Fix compat with PolarSSL >= 1.1.0
-
-
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index 9959532..fa264f8 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -29,6 +29,9 @@
-
- #ifdef USE_POLARSSL
- #include <polarssl/dhm.h>
-+#if POLARSSL_VERSION_NUMBER < 0x01010100
-+#define havege_random havege_rand
-+#endif
- typedef mpi * MP_t;
- #define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
- #define MP_set_w(mpi, w) mpi_lset(mpi, w)
-@@ -61,7 +64,7 @@ static int MDH_generate_key(MDH *dh)
- MP_set(&dh->ctx.P, dh->p);
- MP_set(&dh->ctx.G, dh->g);
- dh->ctx.len = 128;
-- dhm_make_public(&dh->ctx, 1024, out, 1, havege_rand, &RTMP_TLS_ctx->hs);
-+ dhm_make_public(&dh->ctx, 1024, out, 1, havege_random, &RTMP_TLS_ctx->hs);
- MP_new(dh->pub_key);
- MP_new(dh->priv_key);
- MP_set(dh->pub_key, &dh->ctx.GX);
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 52d0254..76a6b4f 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -33,6 +33,7 @@
-
- #ifdef CRYPTO
- #ifdef USE_POLARSSL
-+#include <polarssl/version.h>
- #include <polarssl/havege.h>
- #elif defined(USE_GNUTLS)
- #include <gnutls/gnutls.h>
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index c3fd4a6..1bf0735 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -61,9 +61,13 @@
- #include "rtmp.h"
-
- #ifdef USE_POLARSSL
-+#include <polarssl/version.h>
- #include <polarssl/net.h>
- #include <polarssl/ssl.h>
- #include <polarssl/havege.h>
-+#if POLARSSL_VERSION_NUMBER < 0x01010100
-+#define havege_random havege_rand
-+#endif
- typedef struct tls_ctx {
- havege_state hs;
- ssl_session ssn;
-@@ -71,7 +75,7 @@ typedef struct 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_rand, &ctx->hs);\
-+ 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)
---
-1.7.10.4
-
-
-From 1d07cfa60402ace8472f4661112595f1fe661913 Mon Sep 17 00:00:00 2001
-From: Matthew Garrett <mjg59@srcf.ucam.org>
-Date: Sun, 8 Jul 2012 16:26:14 -0400
-Subject: [PATCH 41/64] Fix socks support for SetupURL
-
-SetupURL assigns sockshost but never parses the data. This patch factors
-the code out from SetupStream into a common function and adds it to
-SetupURL.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 76a6b4f..682e3b8 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -321,6 +321,31 @@ static const char DEFAULT_FLASH_VER[] = DEF_VERSTR;
- const AVal RTMP_DefaultFlashVer =
- { (char *)DEFAULT_FLASH_VER, sizeof(DEFAULT_FLASH_VER) - 1 };
-
-+static void
-+SocksSetup(RTMP *r, AVal *sockshost)
-+{
-+ if (sockshost->av_len)
-+ {
-+ const char *socksport = strchr(sockshost->av_val, ':');
-+ char *hostname = strdup(sockshost->av_val);
-+
-+ if (socksport)
-+ hostname[socksport - sockshost->av_val] = '\0';
-+ r->Link.sockshost.av_val = hostname;
-+ r->Link.sockshost.av_len = strlen(hostname);
-+
-+ r->Link.socksport = socksport ? atoi(socksport + 1) : 1080;
-+ RTMP_Log(RTMP_LOGDEBUG, "Connecting via SOCKS proxy: %s:%d", r->Link.sockshost.av_val,
-+ r->Link.socksport);
-+ }
-+ else
-+ {
-+ r->Link.sockshost.av_val = NULL;
-+ r->Link.sockshost.av_len = 0;
-+ r->Link.socksport = 0;
-+ }
-+}
-+
- void
- RTMP_SetupStream(RTMP *r,
- int protocol,
-@@ -385,26 +410,7 @@ RTMP_SetupStream(RTMP *r,
- }
- #endif
-
-- if (sockshost->av_len)
-- {
-- const char *socksport = strchr(sockshost->av_val, ':');
-- char *hostname = strdup(sockshost->av_val);
--
-- if (socksport)
-- hostname[socksport - sockshost->av_val] = '\0';
-- r->Link.sockshost.av_val = hostname;
-- r->Link.sockshost.av_len = strlen(hostname);
--
-- r->Link.socksport = socksport ? atoi(socksport + 1) : 1080;
-- RTMP_Log(RTMP_LOGDEBUG, "Connecting via SOCKS proxy: %s:%d", r->Link.sockshost.av_val,
-- r->Link.socksport);
-- }
-- else
-- {
-- r->Link.sockshost.av_val = NULL;
-- r->Link.sockshost.av_len = 0;
-- r->Link.socksport = 0;
-- }
-+ SocksSetup(r, sockshost);
-
- if (tcUrl && tcUrl->av_len)
- r->Link.tcUrl = *tcUrl;
-@@ -757,6 +763,8 @@ int RTMP_SetupURL(RTMP *r, char *url)
- (unsigned char *)r->Link.SWFHash, r->Link.swfAge);
- #endif
-
-+ SocksSetup(r, &r->Link.sockshost);
-+
- if (r->Link.port == 0)
- {
- if (r->Link.protocol & RTMP_FEATURE_SSL)
---
-1.7.10.4
-
-
-From b77a7dc719f8b04274db91f6344f4358a78d9c5f Mon Sep 17 00:00:00 2001
-From: goggle1 <goggle1@163.com>
-Date: Tue, 30 Oct 2012 08:47:19 -0700
-Subject: [PATCH 42/64] Handle AMF_ECMA_ARRAY and AMF_STRICT_ARRAY objects
-
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index ce84f81..1406be4 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -396,6 +396,14 @@ AMFProp_Encode(AMFObjectProperty *prop, char *pBuffer, char *pBufEnd)
- pBuffer = AMF_Encode(&prop->p_vu.p_object, pBuffer, pBufEnd);
- break;
-
-+ case AMF_ECMA_ARRAY:
-+ pBuffer = AMF_EncodeEcmaArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
-+ break;
-+
-+ case AMF_STRICT_ARRAY:
-+ pBuffer = AMF_EncodeArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
-+ break;
-+
- default:
- RTMP_Log(RTMP_LOGERROR, "%s, invalid type. %d", __FUNCTION__, prop->p_type);
- pBuffer = NULL;
-@@ -700,7 +708,7 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- if (nRes == -1)
- return -1;
- nSize -= nRes;
-- prop->p_type = AMF_OBJECT;
-+ //prop->p_type = AMF_OBJECT;
- break;
- }
- case AMF_OBJECT_END:
-@@ -718,7 +726,7 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- if (nRes == -1)
- return -1;
- nSize -= nRes;
-- prop->p_type = AMF_OBJECT;
-+ //prop->p_type = AMF_OBJECT;
- break;
- }
- case AMF_DATE:
-@@ -815,6 +823,18 @@ AMFProp_Dump(AMFObjectProperty *prop)
- AMF_Dump(&prop->p_vu.p_object);
- return;
- }
-+ else if (prop->p_type == AMF_ECMA_ARRAY)
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "Property: <%sECMA_ARRAY>", strRes);
-+ AMF_Dump(&prop->p_vu.p_object);
-+ return;
-+ }
-+ else if (prop->p_type == AMF_STRICT_ARRAY)
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "Property: <%sSTRICT_ARRAY>", strRes);
-+ AMF_Dump(&prop->p_vu.p_object);
-+ return;
-+ }
-
- switch (prop->p_type)
- {
-@@ -888,6 +908,76 @@ AMF_Encode(AMFObject *obj, char *pBuffer, char *pBufEnd)
- return pBuffer;
- }
-
-+char *
-+AMF_EncodeEcmaArray(AMFObject *obj, char *pBuffer, char *pBufEnd)
-+{
-+ int i;
-+
-+ if (pBuffer+4 >= pBufEnd)
-+ return NULL;
-+
-+ *pBuffer++ = AMF_ECMA_ARRAY;
-+
-+ pBuffer = AMF_EncodeInt32(pBuffer, pBufEnd, obj->o_num);
-+
-+ for (i = 0; i < obj->o_num; i++)
-+ {
-+ char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
-+ if (res == NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "AMF_Encode - failed to encode property in index %d",
-+ i);
-+ break;
-+ }
-+ else
-+ {
-+ pBuffer = res;
-+ }
-+ }
-+
-+ if (pBuffer + 3 >= pBufEnd)
-+ return NULL; /* no room for the end marker */
-+
-+ pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
-+
-+ return pBuffer;
-+}
-+
-+char *
-+AMF_EncodeArray(AMFObject *obj, char *pBuffer, char *pBufEnd)
-+{
-+ int i;
-+
-+ if (pBuffer+4 >= pBufEnd)
-+ return NULL;
-+
-+ *pBuffer++ = AMF_STRICT_ARRAY;
-+
-+ pBuffer = AMF_EncodeInt32(pBuffer, pBufEnd, obj->o_num);
-+
-+ for (i = 0; i < obj->o_num; i++)
-+ {
-+ char *res = AMFProp_Encode(&obj->o_props[i], pBuffer, pBufEnd);
-+ if (res == NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "AMF_Encode - failed to encode property in index %d",
-+ i);
-+ break;
-+ }
-+ else
-+ {
-+ pBuffer = res;
-+ }
-+ }
-+
-+ //if (pBuffer + 3 >= pBufEnd)
-+ // return NULL; /* no room for the end marker */
-+
-+ //pBuffer = AMF_EncodeInt24(pBuffer, pBufEnd, AMF_OBJECT_END);
-+
-+ return pBuffer;
-+}
-+
- int
- AMF_DecodeArray(AMFObject *obj, const char *pBuffer, int nSize,
- int nArrayLen, int bDecodeName)
-diff --git a/librtmp/amf.h b/librtmp/amf.h
-index b945beb..5a47d77 100644
---- a/librtmp/amf.h
-+++ b/librtmp/amf.h
-@@ -104,6 +104,9 @@ extern "C"
- double AMF_DecodeNumber(const char *data);
-
- char *AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd);
-+ char *AMF_EncodeEcmaArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
-+ char *AMF_EncodeArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
-+
- int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize,
- int bDecodeName);
- int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize,
---
-1.7.10.4
-
-
-From 294135e6eafeb1ac338ac4bb11ebd5ef62c748b9 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 08:50:34 -0700
-Subject: [PATCH 43/64] Cleanup prev commit
-
-
-diff --git a/librtmp/amf.c b/librtmp/amf.c
-index 1406be4..563486c 100644
---- a/librtmp/amf.c
-+++ b/librtmp/amf.c
-@@ -396,14 +396,14 @@ AMFProp_Encode(AMFObjectProperty *prop, char *pBuffer, char *pBufEnd)
- pBuffer = AMF_Encode(&prop->p_vu.p_object, pBuffer, pBufEnd);
- break;
-
-- case AMF_ECMA_ARRAY:
-+ case AMF_ECMA_ARRAY:
- pBuffer = AMF_EncodeEcmaArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
- break;
--
-- case AMF_STRICT_ARRAY:
-+
-+ case AMF_STRICT_ARRAY:
- pBuffer = AMF_EncodeArray(&prop->p_vu.p_object, pBuffer, pBufEnd);
- break;
--
-+
- default:
- RTMP_Log(RTMP_LOGERROR, "%s, invalid type. %d", __FUNCTION__, prop->p_type);
- pBuffer = NULL;
-@@ -708,7 +708,6 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- if (nRes == -1)
- return -1;
- nSize -= nRes;
-- //prop->p_type = AMF_OBJECT;
- break;
- }
- case AMF_OBJECT_END:
-@@ -726,7 +725,6 @@ AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize,
- if (nRes == -1)
- return -1;
- nSize -= nRes;
-- //prop->p_type = AMF_OBJECT;
- break;
- }
- case AMF_DATE:
-diff --git a/librtmp/amf.h b/librtmp/amf.h
-index 5a47d77..5de414b 100644
---- a/librtmp/amf.h
-+++ b/librtmp/amf.h
-@@ -106,7 +106,7 @@ extern "C"
- char *AMF_Encode(AMFObject * obj, char *pBuffer, char *pBufEnd);
- char *AMF_EncodeEcmaArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
- char *AMF_EncodeArray(AMFObject *obj, char *pBuffer, char *pBufEnd);
--
-+
- int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize,
- int bDecodeName);
- int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize,
---
-1.7.10.4
-
-
-From d70c3f677d3d80763adf54c4e1329c57ed8af3ba Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sun, 20 May 2012 23:36:57 +0300
-Subject: [PATCH 44/64] 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:
---
-1.7.10.4
-
-
-From f14b6ac18d779cfb1431c59344bd59a0b0445e08 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sun, 20 May 2012 23:36:58 +0300
-Subject: [PATCH 45/64] 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__,
---
-1.7.10.4
-
-
-From 6df3b1f2015f928d74a675bda542c354b893c2c2 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Tue, 30 Oct 2012 08:57:43 -0700
-Subject: [PATCH 46/64] 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)
---
-1.7.10.4
-
-
-From 002ef6f6be2bbdf852ff64ab6981d709435a9045 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Sun, 20 May 2012 23:37:35 +0300
-Subject: [PATCH 47/64] 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
---
-1.7.10.4
-
-
-From 8e527f61afbcb72eb7d8ae1f507765cdc2df2785 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 21 May 2012 18:17:29 +0300
-Subject: [PATCH 48/64] Add null termination to buffers before using strstr
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index cba8b6c..83f3247 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -3673,7 +3673,7 @@ RTMPSockBuf_Fill(RTMPSockBuf *sb)
-
- while (1)
- {
-- nBytes = sizeof(sb->sb_buf) - sb->sb_size - (sb->sb_start - sb->sb_buf);
-+ nBytes = sizeof(sb->sb_buf) - 1 - sb->sb_size - (sb->sb_start - sb->sb_buf);
- #if defined(CRYPTO) && !defined(NO_SSL)
- if (sb->sb_ssl)
- {
-@@ -3852,6 +3852,7 @@ HTTP_read(RTMP *r, int fill)
- return -2;
- if (strncmp(r->m_sb.sb_start, "HTTP/1.1 200 ", 13))
- return -1;
-+ r->m_sb.sb_start[r->m_sb.sb_size] = '\0';
- ptr = r->m_sb.sb_start + sizeof("HTTP/1.1 200");
- while ((ptr = strstr(ptr, "Content-"))) {
- if (!strncasecmp(ptr+8, "length:", 7)) break;
---
-1.7.10.4
-
-
-From 895392a7161ceb37ac32b3fb4a910b350361b13f Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 21 May 2012 18:17:30 +0300
-Subject: [PATCH 49/64] Buffer more data before returning successfully from
- HTTP_read, if needed
-
-This fixes issues if the http header and the payload data
-are sent in separate packets (as they normally are), and the
-buffer contains the full header but none of the payload.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 83f3247..0d28666 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -3846,6 +3846,7 @@ HTTP_read(RTMP *r, int fill)
- char *ptr;
- int hlen;
-
-+restart:
- if (fill)
- RTMPSockBuf_Fill(&r->m_sb);
- if (r->m_sb.sb_size < 144)
-@@ -3865,6 +3866,12 @@ HTTP_read(RTMP *r, int fill)
- if (!ptr)
- return -1;
- ptr += 4;
-+ if (ptr + (r->m_clientID.av_val ? 1 : hlen) > r->m_sb.sb_start + r->m_sb.sb_size)
-+ {
-+ if (fill)
-+ goto restart;
-+ return -2;
-+ }
- r->m_sb.sb_size -= ptr - r->m_sb.sb_start;
- r->m_sb.sb_start = ptr;
- r->m_unackd--;
---
-1.7.10.4
-
-
-From 4ded9e053744e54286ab9af4e9657f5926a79a2c Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 21 May 2012 18:17:31 +0300
-Subject: [PATCH 50/64] Don't require 144 bytes to be buffered before
- proceeding with HTTP_read
-
-This makes the code more flexible, if servers were to use
-smaller headers.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 0d28666..21e2c18 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -3849,11 +3849,20 @@ HTTP_read(RTMP *r, int fill)
- restart:
- if (fill)
- RTMPSockBuf_Fill(&r->m_sb);
-- if (r->m_sb.sb_size < 144)
-+ if (r->m_sb.sb_size < 13) {
-+ if (fill)
-+ goto restart;
- return -2;
-+ }
- if (strncmp(r->m_sb.sb_start, "HTTP/1.1 200 ", 13))
- return -1;
- r->m_sb.sb_start[r->m_sb.sb_size] = '\0';
-+ if (!strstr(r->m_sb.sb_start, "\r\n\r\n")) {
-+ if (fill)
-+ goto restart;
-+ return -2;
-+ }
-+
- ptr = r->m_sb.sb_start + sizeof("HTTP/1.1 200");
- while ((ptr = strstr(ptr, "Content-"))) {
- if (!strncasecmp(ptr+8, "length:", 7)) break;
---
-1.7.10.4
-
-
-From 91921dda7002ea8ffed9dfb74ad2913dfdd0b1ed Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 21 May 2012 18:17:32 +0300
-Subject: [PATCH 51/64] Refill if HTTP_read indicated it needs more data
-
-HTTP_read wants to skip past the first payload byte, so
-it actually needs to have at least 144 + 1 bytes buffered.
-
-This also avoids relying on the magic 144 byte constant altogether,
-which could easily break if servers include less reply headers.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 21e2c18..6183d20 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -1403,9 +1403,11 @@ ReadN(RTMP *r, char *buffer, int n)
- int nBytes = 0, nRead;
- if (r->Link.protocol & RTMP_FEATURE_HTTP)
- {
-+ int refill = 0;
- while (!r->m_resplen)
- {
-- if (r->m_sb.sb_size < 144)
-+ int ret;
-+ if (r->m_sb.sb_size < 13 || refill)
- {
- if (!r->m_unackd)
- HTTP_Post(r, RTMPT_IDLE, "", 1);
-@@ -1416,12 +1418,20 @@ ReadN(RTMP *r, char *buffer, int n)
- return 0;
- }
- }
-- if (HTTP_read(r, 0) == -1)
-+ if ((ret = HTTP_read(r, 0)) == -1)
- {
- RTMP_Log(RTMP_LOGDEBUG, "%s, No valid HTTP response found", __FUNCTION__);
- RTMP_Close(r);
- return 0;
- }
-+ else if (ret == -2)
-+ {
-+ refill = 1;
-+ }
-+ else
-+ {
-+ refill = 0;
-+ }
- }
- if (r->m_resplen && !r->m_sb.sb_size)
- RTMPSockBuf_Fill(&r->m_sb);
---
-1.7.10.4
-
-
-From 4a08069f086b68e99f33e931583148f4090960a3 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Mon, 21 May 2012 23:52:11 +0300
-Subject: [PATCH 52/64] Use CRLF newlines consistently for all HTTP POST
- headers
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 6183d20..ab52c49 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -3835,8 +3835,8 @@ HTTP_Post(RTMP *r, RTMPTCmd cmd, const char *buf, int len)
- int hlen = snprintf(hbuf, sizeof(hbuf), "POST /%s%s/%d HTTP/1.1\r\n"
- "Host: %.*s:%d\r\n"
- "Accept: */*\r\n"
-- "User-Agent: Shockwave Flash\n"
-- "Connection: Keep-Alive\n"
-+ "User-Agent: Shockwave Flash\r\n"
-+ "Connection: Keep-Alive\r\n"
- "Cache-Control: no-cache\r\n"
- "Content-type: application/x-fcs\r\n"
- "Content-length: %d\r\n\r\n", RTMPT_cmds[cmd],
---
-1.7.10.4
-
-
-From 0fb1d9936fb25f0755bb8b4afc95db048efe4526 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Wed, 30 May 2012 22:06:57 +0300
-Subject: [PATCH 53/64] Free skipped packets in RTMP_GetNextMediaPacket
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index ab52c49..d35b58a 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -1206,6 +1206,7 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
- packet->m_nTimeStamp, packet->m_hasAbsTimestamp,
- r->m_mediaStamp);
- #endif
-+ RTMPPacket_Free(packet);
- continue;
- }
- r->m_pausing = 0;
---
-1.7.10.4
-
-
-From a9282329c3be3bb95f31137867fad9920b682d6d Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Wed, 30 May 2012 22:07:23 +0300
-Subject: [PATCH 54/64] Allocate the channel arrays dynamically
-
-This avoids having to allocate space for all theoretical channels
-if most of them aren't used. This drops the size of the full
-RTMP struct from over 1200 KB to 16 KB (on 64 bit), and as long as
-only channels with a low number are used, the amount of total
-allocated memory stays far below what it was before.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index d35b58a..6f6e97b 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -1216,7 +1216,8 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
- if (bHasMediaPacket)
- r->m_bPlaying = TRUE;
- else if (r->m_sb.sb_timedout && !r->m_pausing)
-- r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
-+ r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
-+ r->m_channelTimestamp[r->m_mediaChannel] : 0;
-
- return bHasMediaPacket;
- }
-@@ -1998,7 +1999,8 @@ RTMP_SendPause(RTMP *r, int DoPause, int iTime)
- int RTMP_Pause(RTMP *r, int DoPause)
- {
- if (DoPause)
-- r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
-+ r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
-+ r->m_channelTimestamp[r->m_mediaChannel] : 0;
- return RTMP_SendPause(r, DoPause, r->m_pauseStamp);
- }
-
-@@ -2953,7 +2955,8 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet)
- break;
- if (!r->m_pausing)
- {
-- r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
-+ r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
-+ r->m_channelTimestamp[r->m_mediaChannel] : 0;
- RTMP_SendPause(r, TRUE, r->m_pauseStamp);
- r->m_pausing = 1;
- }
-@@ -3098,6 +3101,26 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet)
-
- nSize = packetSize[packet->m_headerType];
-
-+ if (packet->m_nChannel >= r->m_channelsAllocatedIn)
-+ {
-+ int n = packet->m_nChannel + 10;
-+ int *timestamp = realloc(r->m_channelTimestamp, sizeof(int) * n);
-+ RTMPPacket **packets = realloc(r->m_vecChannelsIn, sizeof(RTMPPacket*) * n);
-+ if (!timestamp)
-+ free(r->m_channelTimestamp);
-+ if (!packets)
-+ free(r->m_vecChannelsIn);
-+ r->m_channelTimestamp = timestamp;
-+ r->m_vecChannelsIn = packets;
-+ if (!timestamp || !packets) {
-+ r->m_channelsAllocatedIn = 0;
-+ return FALSE;
-+ }
-+ memset(r->m_channelTimestamp + r->m_channelsAllocatedIn, 0, sizeof(int) * (n - r->m_channelsAllocatedIn));
-+ memset(r->m_vecChannelsIn + r->m_channelsAllocatedIn, 0, sizeof(RTMPPacket*) * (n - r->m_channelsAllocatedIn));
-+ r->m_channelsAllocatedIn = n;
-+ }
-+
- if (nSize == RTMP_LARGE_HEADER_SIZE) /* if we get a full header the timestamp is absolute */
- packet->m_hasAbsTimestamp = TRUE;
-
-@@ -3373,7 +3396,7 @@ RTMP_SendChunk(RTMP *r, RTMPChunk *chunk)
- int
- RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
- {
-- const RTMPPacket *prevPacket = r->m_vecChannelsOut[packet->m_nChannel];
-+ const RTMPPacket *prevPacket;
- uint32_t last = 0;
- int nSize;
- int hSize, cSize;
-@@ -3383,6 +3406,22 @@ RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
- int nChunkSize;
- int tlen;
-
-+ if (packet->m_nChannel >= r->m_channelsAllocatedOut)
-+ {
-+ int n = packet->m_nChannel + 10;
-+ RTMPPacket **packets = realloc(r->m_vecChannelsOut, sizeof(RTMPPacket*) * n);
-+ if (!packets) {
-+ free(r->m_vecChannelsOut);
-+ r->m_vecChannelsOut = NULL;
-+ r->m_channelsAllocatedOut = 0;
-+ return FALSE;
-+ }
-+ r->m_vecChannelsOut = packets;
-+ memset(r->m_vecChannelsOut + r->m_channelsAllocatedOut, 0, sizeof(RTMPPacket*) * (n - r->m_channelsAllocatedOut));
-+ r->m_channelsAllocatedOut = n;
-+ }
-+
-+ prevPacket = r->m_vecChannelsOut[packet->m_nChannel];
- if (prevPacket && packet->m_headerType != RTMP_PACKET_SIZE_LARGE)
- {
- /* compress a bit by using the prev packet's attributes */
-@@ -3619,7 +3658,7 @@ RTMP_Close(RTMP *r)
- r->m_write.m_nBytesRead = 0;
- RTMPPacket_Free(&r->m_write);
-
-- for (i = 0; i < RTMP_CHANNELS; i++)
-+ for (i = 0; i < r->m_channelsAllocatedIn; i++)
- {
- if (r->m_vecChannelsIn[i])
- {
-@@ -3627,12 +3666,23 @@ RTMP_Close(RTMP *r)
- free(r->m_vecChannelsIn[i]);
- r->m_vecChannelsIn[i] = NULL;
- }
-+ }
-+ free(r->m_vecChannelsIn);
-+ r->m_vecChannelsIn = NULL;
-+ free(r->m_channelTimestamp);
-+ r->m_channelTimestamp = NULL;
-+ r->m_channelsAllocatedIn = 0;
-+ for (i = 0; i < r->m_channelsAllocatedOut; i++)
-+ {
- if (r->m_vecChannelsOut[i])
- {
- free(r->m_vecChannelsOut[i]);
- r->m_vecChannelsOut[i] = NULL;
- }
- }
-+ free(r->m_vecChannelsOut);
-+ r->m_vecChannelsOut = NULL;
-+ r->m_channelsAllocatedOut = 0;
- AV_clear(r->m_methodCalls, r->m_numCalls);
- r->m_methodCalls = NULL;
- r->m_numCalls = 0;
-diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
-index 76e01fd..8cb6e45 100644
---- a/librtmp/rtmp.h
-+++ b/librtmp/rtmp.h
-@@ -253,9 +253,11 @@ extern "C"
- int m_numCalls;
- RTMP_METHOD *m_methodCalls; /* remote method calls queue */
-
-- RTMPPacket *m_vecChannelsIn[RTMP_CHANNELS];
-- RTMPPacket *m_vecChannelsOut[RTMP_CHANNELS];
-- int m_channelTimestamp[RTMP_CHANNELS]; /* abs timestamp of last packet */
-+ int m_channelsAllocatedIn;
-+ int m_channelsAllocatedOut;
-+ RTMPPacket **m_vecChannelsIn;
-+ RTMPPacket **m_vecChannelsOut;
-+ int *m_channelTimestamp; /* abs timestamp of last packet */
-
- double m_fAudioCodecs; /* audioCodecs for the connect packet */
- double m_fVideoCodecs; /* videoCodecs for the connect packet */
---
-1.7.10.4
-
-
-From 630c8db7d1ee2889d0c26a77d95050c01caf5d5a Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Tue, 30 Oct 2012 09:09:25 -0700
-Subject: [PATCH 55/64] Add adobe authentication support
-
-From: Sergiy <piratfm@gmail.com>
-
-To use this, add flashver=FMLE/3.0\20(compatible;\20FMSc/1.0)
-and pubUser=<username> pubUser=<password> to the RTMP url.
-
-This should both work for generic adobe authentication, and for
-publishing to akamai.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 6f6e97b..391a3b4 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -27,6 +27,7 @@
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
-+#include <time.h>
-
- #include "rtmp_sys.h"
- #include "log.h"
-@@ -35,6 +36,9 @@
- #ifdef USE_POLARSSL
- #include <polarssl/version.h>
- #include <polarssl/havege.h>
-+#include <polarssl/md5.h>
-+#include <polarssl/base64.h>
-+#define MD5_DIGEST_LENGTH 16
-
- static const char *my_dhm_P =
- "E4004C1F94182000103D883A448B3F80" \
-@@ -50,9 +54,15 @@ static const char *my_dhm_G = "4";
-
- #elif defined(USE_GNUTLS)
- #include <gnutls/gnutls.h>
-+#define MD5_DIGEST_LENGTH 16
-+#include <nettle/base64.h>
-+#include <nettle/md5.h>
- #else /* USE_OPENSSL */
- #include <openssl/ssl.h>
- #include <openssl/rc4.h>
-+#include <openssl/md5.h>
-+#include <openssl/bio.h>
-+#include <openssl/buffer.h>
- #endif
- TLS_CTX RTMP_TLS_ctx;
- #endif
-@@ -595,6 +605,10 @@ static struct urlopt {
- "Buffer time in milliseconds" },
- { AVC("timeout"), OFF(Link.timeout), OPT_INT, 0,
- "Session timeout in seconds" },
-+ { AVC("pubUser"), OFF(Link.pubUser), OPT_STR, 0,
-+ "Publisher username" },
-+ { AVC("pubPasswd"), OFF(Link.pubPasswd), OPT_STR, 0,
-+ "Publisher password" },
- { {NULL,0}, 0, 0}
- };
-
-@@ -2433,6 +2447,239 @@ AV_clear(RTMP_METHOD *vals, int num)
- free(vals);
- }
-
-+
-+#ifdef CRYPTO
-+static int
-+b64enc(const unsigned char *input, int length, char *output, int maxsize)
-+{
-+#ifdef USE_POLARSSL
-+ int buf_size = maxsize;
-+ if(base64_encode((unsigned char *) output, &buf_size, input, length) == 0)
-+ {
-+ output[buf_size] = '\0';
-+ return 1;
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, error", __FUNCTION__);
-+ return 0;
-+ }
-+#elif defined(USE_GNUTLS)
-+ if (BASE64_ENCODE_RAW_LENGTH(length) <= maxsize)
-+ base64_encode_raw((uint8_t*) output, length, input);
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, error", __FUNCTION__);
-+ return 0;
-+ }
-+#else /* USE_OPENSSL */
-+ BIO *bmem, *b64;
-+ BUF_MEM *bptr;
-+
-+ b64 = BIO_new(BIO_f_base64());
-+ bmem = BIO_new(BIO_s_mem());
-+ b64 = BIO_push(b64, bmem);
-+ BIO_write(b64, input, length);
-+ if (BIO_flush(b64) == 1)
-+ {
-+ BIO_get_mem_ptr(b64, &bptr);
-+ memcpy(output, bptr->data, bptr->length-1);
-+ output[bptr->length-1] = '\0';
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, error", __FUNCTION__);
-+ return 0;
-+ }
-+ BIO_free_all(b64);
-+#endif
-+ return 1;
-+}
-+
-+#ifdef USE_POLARSSL
-+#define md5sum(x,y,z) md5(x,y,z);
-+#elif defined(USE_GNUTLS)
-+static void md5sum(const unsigned char *data, int len, unsigned char *out)
-+{
-+ struct md5_ctx ctx;
-+ md5_init(&ctx);
-+ md5_update(&ctx, len, data);
-+ md5_digest(&ctx, MD5_DIGEST_LENGTH, out);
-+}
-+#else
-+#define md5sum(x,y,z) MD5(x,y,z);
-+#endif
-+
-+static const AVal av_authmod_adobe = AVC("authmod=adobe");
-+
-+static int
-+PublisherAuth(RTMP *r, AVal *description)
-+{
-+ char *token_in = NULL;
-+ char *ptr;
-+ unsigned char md5sum_val[MD5_DIGEST_LENGTH+1];
-+ int challenge2_data;
-+#define RESPONSE_LEN 32
-+#define CHALLENGE2_LEN 16
-+#define SALTED2_LEN (32+8+8+8)
-+ char response[RESPONSE_LEN];
-+ char challenge2[CHALLENGE2_LEN];
-+ char salted2[SALTED2_LEN];
-+ AVal pubToken;
-+
-+ if (strstr(description->av_val, av_authmod_adobe.av_val) != NULL)
-+ {
-+ if(strstr(description->av_val, "code=403 need auth") != NULL)
-+ {
-+ if (strstr(r->Link.app.av_val, av_authmod_adobe.av_val) != NULL) {
-+ RTMP_Log(RTMP_LOGERROR, "%s, wrong pubUser & pubPasswd for publisher auth", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ } else if(r->Link.pubUser.av_len && r->Link.pubPasswd.av_len) {
-+ pubToken.av_val = malloc(r->Link.pubUser.av_len + av_authmod_adobe.av_len + 8);
-+ pubToken.av_len = sprintf(pubToken.av_val, "?%s&user=%s",
-+ av_authmod_adobe.av_val,
-+ r->Link.pubUser.av_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken1: %s", __FUNCTION__, pubToken.av_val);
-+ r->Link.pFlags |= RTMP_PUB_NAME;
-+ } else {
-+ RTMP_Log(RTMP_LOGERROR, "%s, need to set pubUser & pubPasswd for publisher auth", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ }
-+ else if((token_in = strstr(description->av_val, "?reason=needauth")) != NULL)
-+ {
-+ char *par, *val = NULL, *orig_ptr;
-+ char *user = NULL;
-+ char *salt = NULL;
-+ char *opaque = NULL;
-+ char *challenge = NULL;
-+ char *salted1;
-+
-+ ptr = orig_ptr = strdup(token_in);
-+ while (ptr)
-+ {
-+ par = ptr;
-+ ptr = strchr(par, '&');
-+ if(ptr)
-+ *ptr++ = '\0';
-+
-+ val = strchr(par, '=');
-+ if(val)
-+ *val++ = '\0';
-+
-+ if (strcmp(par, "user") == 0){
-+ user = val;
-+ } else if (strcmp(par, "salt") == 0){
-+ salt = val;
-+ } else if (strcmp(par, "opaque") == 0){
-+ opaque = val;
-+ } else if (strcmp(par, "challenge") == 0){
-+ challenge = val;
-+ }
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, par:\"%s\" = val:\"%s\"", __FUNCTION__, par, val);
-+ }
-+
-+ /* hash1 = base64enc(md5(user + _aodbeAuthSalt + password)) */
-+ salted1 = malloc(strlen(user)+strlen(salt)+r->Link.pubPasswd.av_len+1);
-+ strcpy(salted1, user);
-+ strcat(salted1, salt);
-+ strcat(salted1, r->Link.pubPasswd.av_val);
-+ md5sum((unsigned char*) salted1, strlen(salted1), md5sum_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, salted1);
-+ free(salted1);
-+
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+
-+ b64enc(md5sum_val, MD5_DIGEST_LENGTH, salted2, SALTED2_LEN);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_1) = %s", __FUNCTION__, salted2);
-+
-+ srand( time(NULL) );
-+ challenge2_data = rand();
-+
-+ b64enc((unsigned char *) &challenge2_data, sizeof(int), challenge2, CHALLENGE2_LEN);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, b64(%d) = %s", __FUNCTION__, challenge2_data, challenge2);
-+
-+ /* response = base64enc(md5(hash1 + opaque + challenge2)) */
-+ if (opaque)
-+ strcat(salted2, opaque);
-+ if (challenge)
-+ strcat(salted2, challenge);
-+ strcat(salted2, challenge2);
-+
-+ md5sum((unsigned char*) salted2, strlen(salted2), md5sum_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, salted2);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+
-+ b64enc(md5sum_val, MD5_DIGEST_LENGTH, response, RESPONSE_LEN);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_2) = %s", __FUNCTION__, response);
-+
-+ /* have all hashes, create auth token for the end of app */
-+ pubToken.av_val = malloc(32 + strlen(challenge2) + strlen(response) + (opaque ? strlen(opaque) : 0));
-+ pubToken.av_len = sprintf(pubToken.av_val,
-+ "&challenge=%s&response=%s&opaque=%s",
-+ challenge2,
-+ response,
-+ opaque ? opaque : "");
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken2: %s", __FUNCTION__, pubToken.av_val);
-+ free(orig_ptr);
-+ r->Link.pFlags |= RTMP_PUB_RESP|RTMP_PUB_CLATE;
-+ }
-+ else if(strstr(description->av_val, "?reason=authfailed") != NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed: wrong password", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ else if(strstr(description->av_val, "?reason=nosuchuser") != NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed: no such user", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed: unknown auth mode: %s",
-+ __FUNCTION__, description->av_val);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+
-+ ptr = malloc(r->Link.app.av_len + pubToken.av_len);
-+ strncpy(ptr, r->Link.app.av_val, r->Link.app.av_len);
-+ strncpy(ptr + r->Link.app.av_len, pubToken.av_val, pubToken.av_len);
-+ r->Link.app.av_len += pubToken.av_len;
-+ if(r->Link.pFlags & RTMP_PUB_ALLOC)
-+ free(r->Link.app.av_val);
-+ r->Link.app.av_val = ptr;
-+
-+ ptr = malloc(r->Link.tcUrl.av_len + pubToken.av_len);
-+ strncpy(ptr, r->Link.tcUrl.av_val, r->Link.tcUrl.av_len);
-+ strncpy(ptr + r->Link.tcUrl.av_len, pubToken.av_val, pubToken.av_len);
-+ r->Link.tcUrl.av_len += pubToken.av_len;
-+ if(r->Link.pFlags & RTMP_PUB_ALLOC)
-+ free(r->Link.tcUrl.av_val);
-+ r->Link.tcUrl.av_val = ptr;
-+
-+ free(pubToken.av_val);
-+ r->Link.pFlags |= RTMP_PUB_ALLOC;
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, new app: %.*s tcUrl: %.*s playpath: %s", __FUNCTION__,
-+ r->Link.app.av_len, r->Link.app.av_val,
-+ r->Link.tcUrl.av_len, r->Link.tcUrl.av_val,
-+ r->Link.playpath.av_val);
-+ }
-+ else
-+ {
-+ return 0;
-+ }
-+ return 1;
-+}
-+#endif
-+
-+
- SAVC(onBWDone);
- SAVC(onFCSubscribe);
- SAVC(onFCUnsubscribe);
-@@ -2442,6 +2689,7 @@ SAVC(_error);
- SAVC(close);
- SAVC(code);
- SAVC(level);
-+SAVC(description);
- SAVC(onStatus);
- SAVC(playlist_ready);
- static const AVal av_NetStream_Failed = AVC("NetStream.Failed");
-@@ -2460,6 +2708,8 @@ AVC("NetStream.Play.PublishNotify");
- static const AVal av_NetStream_Play_UnpublishNotify =
- AVC("NetStream.Play.UnpublishNotify");
- static const AVal av_NetStream_Publish_Start = AVC("NetStream.Publish.Start");
-+static const AVal av_NetConnection_Connect_Rejected =
-+AVC("NetConnection.Connect.Rejected");
-
- /* Returns 0 for OK/Failed/error, 1 for 'Stop or Complete' */
- static int
-@@ -2601,12 +2851,73 @@ HandleInvoke(RTMP *r, const char *body, unsigned int nBodySize)
- }
- else if (AVMATCH(&method, &av__error))
- {
-+#ifdef CRYPTO
-+ AVal methodInvoked = {0};
-+ int i;
-+
-+ if (r->Link.protocol & RTMP_FEATURE_WRITE)
-+ {
-+ for (i=0; i<r->m_numCalls; i++)
-+ {
-+ if (r->m_methodCalls[i].num == txn)
-+ {
-+ methodInvoked = r->m_methodCalls[i].name;
-+ AV_erase(r->m_methodCalls, &r->m_numCalls, i, FALSE);
-+ break;
-+ }
-+ }
-+ if (!methodInvoked.av_val)
-+ {
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received result id %f without matching request",
-+ __FUNCTION__, txn);
-+ goto leave;
-+ }
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, received error for method call <%s>", __FUNCTION__,
-+ methodInvoked.av_val);
-+
-+ if (AVMATCH(&methodInvoked, &av_connect))
-+ {
-+ AMFObject obj2;
-+ AVal code, level, description;
-+ AMFProp_GetObject(AMF_GetProp(&obj, NULL, 3), &obj2);
-+ AMFProp_GetString(AMF_GetProp(&obj2, &av_code, -1), &code);
-+ AMFProp_GetString(AMF_GetProp(&obj2, &av_level, -1), &level);
-+ AMFProp_GetString(AMF_GetProp(&obj2, &av_description, -1), &description);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, error description: %s", __FUNCTION__, description.av_val);
-+ /* if PublisherAuth returns 1, then reconnect */
-+ PublisherAuth(r, &description);
-+ }
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
-+ }
-+ free(methodInvoked.av_val);
-+#else
- RTMP_Log(RTMP_LOGERROR, "rtmp server sent error");
-+#endif
- }
- else if (AVMATCH(&method, &av_close))
- {
- RTMP_Log(RTMP_LOGERROR, "rtmp server requested close");
- RTMP_Close(r);
-+#ifdef CRYPTO
-+ if ((r->Link.protocol & RTMP_FEATURE_WRITE) &&
-+ !(r->Link.pFlags & RTMP_PUB_CLEAN) &&
-+ ( !(r->Link.pFlags & RTMP_PUB_NAME) ||
-+ !(r->Link.pFlags & RTMP_PUB_RESP) ||
-+ (r->Link.pFlags & RTMP_PUB_CLATE) ) )
-+ {
-+ /* clean later */
-+ if(r->Link.pFlags & RTMP_PUB_CLATE)
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ RTMP_Log(RTMP_LOGERROR, "authenticating publisher");
-+
-+ if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0))
-+ goto leave;
-+ }
-+#endif
- }
- else if (AVMATCH(&method, &av_onStatus))
- {
-@@ -3695,9 +4006,6 @@ RTMP_Close(RTMP *r)
- r->m_resplen = 0;
- r->m_unackd = 0;
-
-- free(r->Link.playpath0.av_val);
-- r->Link.playpath0.av_val = NULL;
--
- if (r->Link.lFlags & RTMP_LF_FTCU)
- {
- free(r->Link.tcUrl.av_val);
-@@ -3706,6 +4014,20 @@ RTMP_Close(RTMP *r)
- }
-
- #ifdef CRYPTO
-+ if (!(r->Link.protocol & RTMP_FEATURE_WRITE) || (r->Link.pFlags & RTMP_PUB_CLEAN))
-+ {
-+ free(r->Link.playpath0.av_val);
-+ r->Link.playpath0.av_val = NULL;
-+ }
-+ if ((r->Link.protocol & RTMP_FEATURE_WRITE) &&
-+ (r->Link.pFlags & RTMP_PUB_CLEAN) &&
-+ (r->Link.pFlags & RTMP_PUB_ALLOC))
-+ {
-+ free(r->Link.app.av_val);
-+ r->Link.app.av_val = NULL;
-+ free(r->Link.tcUrl.av_val);
-+ r->Link.tcUrl.av_val = NULL;
-+ }
- if (r->Link.dh)
- {
- MDH_free(r->Link.dh);
-@@ -3721,6 +4043,9 @@ RTMP_Close(RTMP *r)
- RC4_free(r->Link.rc4keyOut);
- r->Link.rc4keyOut = NULL;
- }
-+#else
-+ free(r->Link.playpath0.av_val);
-+ r->Link.playpath0.av_val = NULL;
- #endif
- }
-
-diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
-index 8cb6e45..d723070 100644
---- a/librtmp/rtmp.h
-+++ b/librtmp/rtmp.h
-@@ -157,6 +157,8 @@ extern "C"
- AVal subscribepath;
- AVal usherToken;
- AVal token;
-+ AVal pubUser;
-+ AVal pubPasswd;
- AMFObject extras;
- int edepth;
-
-@@ -176,6 +178,13 @@ extern "C"
- int protocol;
- int timeout; /* connection timeout in seconds */
-
-+#define RTMP_PUB_NAME 0x0001 /* send login to server */
-+#define RTMP_PUB_RESP 0x0002 /* send salted password hash */
-+#define RTMP_PUB_ALLOC 0x0004 /* allocated data for new tcUrl & app */
-+#define RTMP_PUB_CLEAN 0x0008 /* need to free allocated data for newer tcUrl & app at exit */
-+#define RTMP_PUB_CLATE 0x0010 /* late clean tcUrl & app at exit */
-+ int pFlags;
-+
- unsigned short socksport;
- unsigned short port;
-
---
-1.7.10.4
-
-
-From 9ecf540e4d5bdc85c17668fa7ead93cc375111ca Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B6rn=20Axelsson?= <bjorn.axelsson@intinor.se>
-Date: Tue, 20 Mar 2012 19:12:23 +0200
-Subject: [PATCH 56/64] Add support for limelight authentication
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 391a3b4..5ea1c76 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2511,6 +2511,18 @@ static void md5sum(const unsigned char *data, int len, unsigned char *out)
- #endif
-
- static const AVal av_authmod_adobe = AVC("authmod=adobe");
-+static const AVal av_authmod_llnw = AVC("authmod=llnw");
-+
-+static char *hexenc(unsigned char *inbuf, int len)
-+{
-+ char *dst = malloc(len * 2 + 1), *ptr = dst;
-+ while(len--) {
-+ sprintf(ptr, "%02x", *inbuf++);
-+ ptr += 2;
-+ }
-+ *ptr = '\0';
-+ return dst;
-+}
-
- static int
- PublisherAuth(RTMP *r, AVal *description)
-@@ -2671,6 +2683,178 @@ PublisherAuth(RTMP *r, AVal *description)
- r->Link.tcUrl.av_len, r->Link.tcUrl.av_val,
- r->Link.playpath.av_val);
- }
-+ else if (strstr(description->av_val, av_authmod_llnw.av_val) != NULL)
-+ {
-+ if(strstr(description->av_val, "code=403 need auth") != NULL)
-+ {
-+ /* This part seems to be the same for llnw and adobe */
-+
-+ if (strstr(r->Link.app.av_val, av_authmod_llnw.av_val) != NULL) {
-+ RTMP_Log(RTMP_LOGERROR, "%s, wrong pubUser & pubPasswd for publisher auth", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ } else if(r->Link.pubUser.av_len && r->Link.pubPasswd.av_len) {
-+ pubToken.av_val = malloc(r->Link.pubUser.av_len + av_authmod_llnw.av_len + 8);
-+ pubToken.av_len = sprintf(pubToken.av_val, "?%s&user=%s",
-+ av_authmod_llnw.av_val,
-+ r->Link.pubUser.av_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken1: %s", __FUNCTION__, pubToken.av_val);
-+ r->Link.pFlags |= RTMP_PUB_NAME;
-+ } else {
-+ RTMP_Log(RTMP_LOGERROR, "%s, need to set pubUser & pubPasswd for publisher auth", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ }
-+ else if((token_in = strstr(description->av_val, "?reason=needauth")) != NULL)
-+ {
-+ char *orig_ptr;
-+ char *par, *val = NULL;
-+ char *user = NULL;
-+ char *nonce = NULL;
-+
-+ ptr = orig_ptr = strdup(token_in);
-+ /* Extract parameters (we need user and nonce) */
-+ while (ptr)
-+ {
-+ par = ptr;
-+ ptr = strchr(par, '&');
-+ if(ptr)
-+ *ptr++ = '\0';
-+
-+ val = strchr(par, '=');
-+ if(val)
-+ *val++ = '\0';
-+
-+ if (strcmp(par, "user") == 0){
-+ user = val;
-+ } else if (strcmp(par, "nonce") == 0){
-+ nonce = val;
-+ }
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, par:\"%s\" = val:\"%s\"", __FUNCTION__, par, val);
-+ }
-+
-+ // FIXME: handle case where user==NULL or nonce==NULL
-+
-+ /* llnw auth method
-+ * Seems to be closely based on HTTP Digest Auth:
-+ * http://tools.ietf.org/html/rfc2617
-+ * http://en.wikipedia.org/wiki/Digest_access_authentication
-+ */
-+
-+ const char *authmod = "llnw";
-+ const char *realm = "live";
-+ const char *method = "publish";
-+ const char *qop = "auth";
-+ char *tmpbuf;
-+
-+ /* nc = 1..connection count (or rather, number of times cnonce has been reused) */
-+ int nc = 1;
-+ /* nchex = hexenc(nc) (8 hex digits according to RFC 2617) */
-+ char nchex[9];
-+ sprintf(nchex, "%08x", nc);
-+ /* cnonce = hexenc(4 random bytes) (initialized on first connection) */
-+ char cnonce[9];
-+ srand( time(NULL) ); // FIXME: a lib shouldn't call srand()
-+ sprintf(cnonce, "%08x", rand());
-+
-+ /* hash1 = hexenc(md5(user + ":" + realm + ":" + password)) */
-+ tmpbuf = malloc(strlen(user) + 1 + strlen(realm) + 1 + r->Link.pubPasswd.av_len + 1);
-+ sprintf(tmpbuf, "%s:%s:%s", user, realm, r->Link.pubPasswd.av_val);
-+ md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+ free(tmpbuf);
-+ char *hash1 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+
-+ /* hash2 = hexenc(md5(method + ":/" + app + "/" + appInstance)) */
-+ /* Extract appname + appinstance without query parameters */
-+ char *apptmp = malloc(r->Link.app.av_len + 1), *qpos;
-+ memcpy(apptmp, r->Link.app.av_val, r->Link.app.av_len);
-+ apptmp[r->Link.app.av_len] = '\0';
-+ if((qpos = strchr(apptmp, '?')))
-+ *qpos = '\0';
-+
-+ tmpbuf = malloc(strlen(method) + 2 + strlen(apptmp) + 1);
-+ sprintf(tmpbuf, "%s:/%s", method, apptmp);
-+ md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+ free(tmpbuf);
-+ char *hash2 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+
-+ free(apptmp);
-+
-+ /* hash3 = hexenc(md5(hash1 + ":" + nonce + ":" + nchex + ":" + cnonce + ":" + qop + ":" + hash2)) */
-+ tmpbuf = malloc(strlen(hash1) + 1 + strlen(nonce) + 1 + strlen(nchex) + 1 + strlen(cnonce) + 1 + strlen(qop) + 1 + strlen(hash2) + 1);
-+ sprintf(tmpbuf, "%s:%s:%s:%s:%s:%s", hash1, nonce, nchex, cnonce, qop, hash2);
-+ md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+ free(tmpbuf);
-+ char *hash3 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+
-+ /* pubToken = &authmod=<authmod>&user=<username>&nonce=<nonce>&cnonce=<cnonce>&nc=<nchex>&response=<hash3> */
-+ /* Append nonces and response to query string which already contains
-+ * user + authmod */
-+ pubToken.av_val = malloc(64 + strlen(authmod) + strlen(user) + strlen(nonce) + strlen(cnonce) + strlen(nchex) + strlen(hash3));
-+ sprintf(pubToken.av_val,
-+ "&nonce=%s&cnonce=%s&nc=%s&response=%s",
-+ nonce, cnonce, nchex, hash3);
-+ pubToken.av_len = strlen(pubToken.av_val);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken2: %s", __FUNCTION__, pubToken.av_val);
-+ r->Link.pFlags |= RTMP_PUB_RESP|RTMP_PUB_CLATE;
-+
-+ free(hash1);
-+ free(hash2);
-+ free(hash3);
-+ free(orig_ptr);
-+ }
-+ else if(strstr(description->av_val, "?reason=authfail") != NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ else if(strstr(description->av_val, "?reason=nosuchuser") != NULL)
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed: no such user", __FUNCTION__);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+ else
-+ {
-+ RTMP_Log(RTMP_LOGERROR, "%s, Authentication failed: unknown auth mode: %s",
-+ __FUNCTION__, description->av_val);
-+ r->Link.pFlags |= RTMP_PUB_CLEAN;
-+ return 0;
-+ }
-+
-+ ptr = malloc(r->Link.app.av_len + pubToken.av_len);
-+ strncpy(ptr, r->Link.app.av_val, r->Link.app.av_len);
-+ strncpy(ptr + r->Link.app.av_len, pubToken.av_val, pubToken.av_len);
-+ r->Link.app.av_len += pubToken.av_len;
-+ if(r->Link.pFlags & RTMP_PUB_ALLOC)
-+ free(r->Link.app.av_val);
-+ r->Link.app.av_val = ptr;
-+
-+ ptr = malloc(r->Link.tcUrl.av_len + pubToken.av_len);
-+ strncpy(ptr, r->Link.tcUrl.av_val, r->Link.tcUrl.av_len);
-+ strncpy(ptr + r->Link.tcUrl.av_len, pubToken.av_val, pubToken.av_len);
-+ r->Link.tcUrl.av_len += pubToken.av_len;
-+ if(r->Link.pFlags & RTMP_PUB_ALLOC)
-+ free(r->Link.tcUrl.av_val);
-+ r->Link.tcUrl.av_val = ptr;
-+
-+ free(pubToken.av_val);
-+ r->Link.pFlags |= RTMP_PUB_ALLOC;
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, new app: %.*s tcUrl: %.*s playpath: %s", __FUNCTION__,
-+ r->Link.app.av_len, r->Link.app.av_val,
-+ r->Link.tcUrl.av_len, r->Link.tcUrl.av_val,
-+ r->Link.playpath.av_val);
-+ }
- else
- {
- return 0;
---
-1.7.10.4
-
-
-From 883c33489403ed360a01d1a47ec76d476525b49e Mon Sep 17 00:00:00 2001
-From: LRN <lrn1986@gmail.com>
-Date: Sat, 5 May 2012 21:15:36 +0400
-Subject: [PATCH 57/64] Fix dll name to have SO_VERSION
-
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-subj is attached
-
-Changes librtmp.dll into librtmp-$(SO_VERSION).dll, the same form that
-libtool uses.
-librtmp.dll is still created from librtmp-$(SO_VERSION).dll via `ln
-- -sf'; obviously, it makes a hardlink when called in MSYS, but that's
-no worse than what we have right now.
-
-Please, CC me, since i'm not subscibed to this list
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.11 (MingW32)
-Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
-
-iQEcBAEBAgAGBQJPpWA2AAoJEOs4Jb6SI2Cw+xIH/jqI7SbM1nMHBhFDSDtDFxim
-zzlX5zsU9Ss45ZX9VMdzXLSDvxsuB6a97svMlipU2HOs4Ba1rcO8fdNII/8lD7nt
-yIWiGDcyZNXP7xBXJOVahYwzDzpyGhOychl2XlgW8/9lY7V1DYFjlPUSWdfw8IH0
-iUX6PKMjrN3n4TTIh1kTwG0YHBRq2JdsRAaTB1uQDwBwNFkNPegWTO8oVvtlb1sc
-gxhmN08o/S7nWAJRs5+Ah9eYSvWJral5yzIcxeOISGkZJxLs16F0b5iVtd2J1xN4
-3mNQH4W3n7q/EcsF18/UwI8VjcAZnyCXMGI1VXp9frFEvm8//Bv9jSrWKfrZPwI=
-=/n61
------END PGP SIGNATURE-----
-
-From 4d885c0ef9eab89ec7ed1383fd5cba5587a6a311 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?=
- =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= <lrn1986@gmail.com>
-Date: Sat, 5 May 2012 21:05:30 +0400
-Subject: [PATCH] Fix dll name to have SO_VERSION
-
-diff --git a/librtmp/Makefile b/librtmp/Makefile
-index 74ee3b5..96c076b 100644
---- a/librtmp/Makefile
-+++ b/librtmp/Makefile
-@@ -39,11 +39,11 @@ CRYPTO_DEF=$(DEF_$(CRYPTO))
- SO_VERSION=0
- SOX_posix=so
- SOX_darwin=dylib
--SOX_mingw=so # useless
-+SOX_mingw=dll
- SOX=$(SOX_$(SYS))
--SO_posix=$(SOX).$(SO_VERSION)
--SO_darwin=$(SO_VERSION).$(SOX)
--SO_mingw=dll
-+SO_posix=.$(SOX).$(SO_VERSION)
-+SO_darwin=.$(SO_VERSION).$(SOX)
-+SO_mingw=-$(SO_VERSION).$(SOX)
- SO_EXT=$(SO_$(SYS))
-
- SODIR_posix=$(LIBDIR)
-@@ -64,7 +64,7 @@ INSTALL_IMPLIB=$(INSTALL_IMPLIB_$(SYS))
-
- SHARED=yes
- SODEF_yes=-fPIC
--SOLIB_yes=librtmp.$(SO_EXT)
-+SOLIB_yes=librtmp$(SO_EXT)
- SOINST_yes=install_so
- SO_DEF=$(SODEF_$(SHARED))
- SO_LIB=$(SOLIB_$(SHARED))
-@@ -81,12 +81,12 @@ OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o
- all: librtmp.a $(SO_LIB)
-
- clean:
-- rm -f *.o *.a *.$(SOX) *.$(SO_EXT) librtmp.pc
-+ rm -f *.o *.a *.$(SOX) *$(SO_EXT) librtmp.pc
-
- librtmp.a: $(OBJS)
- $(AR) rs $@ $?
-
--librtmp.$(SO_EXT): $(OBJS)
-+librtmp$(SO_EXT): $(OBJS)
- $(CC) $(SO_LDFLAGS) $(LDFLAGS) -o $@ $^ $> $(CRYPTO_LIB)
- ln -sf $@ librtmp.$(SOX)
-
-@@ -111,8 +111,8 @@ install_base: librtmp.a librtmp.pc
- cp librtmp.pc $(LIBDIR)/pkgconfig
- cp librtmp.3 $(MANDIR)/man3
-
--install_so: librtmp.$(SO_EXT)
-- cp librtmp.$(SO_EXT) $(SODIR)
-+install_so: librtmp$(SO_EXT)
-+ cp librtmp$(SO_EXT) $(SODIR)
- $(INSTALL_IMPLIB)
-- cd $(SODIR); ln -sf librtmp.$(SO_EXT) librtmp.$(SOX)
-+ cd $(SODIR); ln -sf librtmp$(SO_EXT) librtmp.$(SOX)
-
---
-1.7.10.4
-
-
-From e42b5d0926b1a668d7fbd794a70f31040c5f198d Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 11:17:41 -0700
-Subject: [PATCH 58/64] Cleanup authentication code
-
-from commit 9ecf540e4d5bdc85c17668fa7ead93cc375111ca
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 5ea1c76..6d04708 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2497,17 +2497,16 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
- }
-
- #ifdef USE_POLARSSL
--#define md5sum(x,y,z) md5(x,y,z);
-+#define MD5_CTX md5_context
-+#define MD5_Init(ctx) md5_starts(ctx)
-+#define MD5_Update(ctx,data,len) md5_update(ctx,data,len)
-+#define MD5_Final(dig,ctx) md5_finish(ctx,dig)
- #elif defined(USE_GNUTLS)
--static void md5sum(const unsigned char *data, int len, unsigned char *out)
--{
-- struct md5_ctx ctx;
-- md5_init(&ctx);
-- md5_update(&ctx, len, data);
-- md5_digest(&ctx, MD5_DIGEST_LENGTH, out);
--}
-+typedef struct md5_ctx MD5_CTX
-+#define MD5_Init(ctx) md5_init(ctx)
-+#define MD5_Update(ctx,data,len) md5_update(ctx,len,data)
-+#define MD5_Final(dig,ctx) md5_digest(ctx,MD5_DIGEST_LENGTH,dig)
- #else
--#define md5sum(x,y,z) MD5(x,y,z);
- #endif
-
- static const AVal av_authmod_adobe = AVC("authmod=adobe");
-@@ -2530,10 +2529,14 @@ PublisherAuth(RTMP *r, AVal *description)
- char *token_in = NULL;
- char *ptr;
- unsigned char md5sum_val[MD5_DIGEST_LENGTH+1];
-+ MD5_CTX md5ctx;
- int challenge2_data;
- #define RESPONSE_LEN 32
- #define CHALLENGE2_LEN 16
- #define SALTED2_LEN (32+8+8+8)
-+#define B64DIGEST_LEN 22 /* 16 byte digest => 22 b64 chars */
-+#define B64INT_LEN 6 /* 4 byte int => 6 b64 chars */
-+#define HEXHASH_LEN (2*MD5_DIGEST_LENGTH)
- char response[RESPONSE_LEN];
- char challenge2[CHALLENGE2_LEN];
- char salted2[SALTED2_LEN];
-@@ -2563,11 +2566,9 @@ PublisherAuth(RTMP *r, AVal *description)
- else if((token_in = strstr(description->av_val, "?reason=needauth")) != NULL)
- {
- char *par, *val = NULL, *orig_ptr;
-- char *user = NULL;
-- char *salt = NULL;
-- char *opaque = NULL;
-- char *challenge = NULL;
-- char *salted1;
-+ AVal user, salt, opaque, challenge, *aptr = NULL;
-+ opaque.av_len = 0;
-+ challenge.av_len = 0;
-
- ptr = orig_ptr = strdup(token_in);
- while (ptr)
-@@ -2581,60 +2582,72 @@ PublisherAuth(RTMP *r, AVal *description)
- if(val)
- *val++ = '\0';
-
-+ if (aptr) {
-+ aptr->av_len = par - aptr->av_val - 1;
-+ aptr = NULL;
-+ }
- if (strcmp(par, "user") == 0){
-- user = val;
-+ user.av_val = val;
-+ aptr = &user;
- } else if (strcmp(par, "salt") == 0){
-- salt = val;
-+ salt.av_val = val;
-+ aptr = &salt;
- } else if (strcmp(par, "opaque") == 0){
-- opaque = val;
-+ opaque.av_val = val;
-+ aptr = &opaque;
- } else if (strcmp(par, "challenge") == 0){
-- challenge = val;
-+ challenge.av_val = val;
-+ aptr = &challenge;
- }
-
- RTMP_Log(RTMP_LOGDEBUG, "%s, par:\"%s\" = val:\"%s\"", __FUNCTION__, par, val);
- }
-+ if (aptr)
-+ aptr->av_len = strlen(aptr->av_val);
-+
-+ /* hash1 = base64enc(md5(user + _aodbeAuthSalt + password)) */
-+ MD5_Init(&md5ctx);
-+ MD5_Update(&md5ctx, user.av_val, user.av_len);
-+ MD5_Update(&md5ctx, salt.av_val, salt.av_len);
-+ MD5_Update(&md5ctx, r->Link.pubPasswd.av_val, r->Link.pubPasswd.av_len);
-+ MD5_Final(md5sum_val, &md5ctx);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s%s%s) =>", __FUNCTION__,
-+ user.av_val, salt.av_val, r->Link.pubPasswd.av_val);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-
-- /* hash1 = base64enc(md5(user + _aodbeAuthSalt + password)) */
-- salted1 = malloc(strlen(user)+strlen(salt)+r->Link.pubPasswd.av_len+1);
-- strcpy(salted1, user);
-- strcat(salted1, salt);
-- strcat(salted1, r->Link.pubPasswd.av_val);
-- md5sum((unsigned char*) salted1, strlen(salted1), md5sum_val);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, salted1);
-- free(salted1);
--
-- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
--
-- b64enc(md5sum_val, MD5_DIGEST_LENGTH, salted2, SALTED2_LEN);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_1) = %s", __FUNCTION__, salted2);
-+ b64enc(md5sum_val, MD5_DIGEST_LENGTH, salted2, SALTED2_LEN);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_1) = %s", __FUNCTION__, salted2);
-
-- srand( time(NULL) );
-+ /* FIXME: what byte order does this depend on? */
- challenge2_data = rand();
-
- b64enc((unsigned char *) &challenge2_data, sizeof(int), challenge2, CHALLENGE2_LEN);
- RTMP_Log(RTMP_LOGDEBUG, "%s, b64(%d) = %s", __FUNCTION__, challenge2_data, challenge2);
-
-+ MD5_Init(&md5ctx);
-+ MD5_Update(&md5ctx, salted2, B64DIGEST_LEN);
- /* response = base64enc(md5(hash1 + opaque + challenge2)) */
-- if (opaque)
-- strcat(salted2, opaque);
-- if (challenge)
-- strcat(salted2, challenge);
-- strcat(salted2, challenge2);
--
-- md5sum((unsigned char*) salted2, strlen(salted2), md5sum_val);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, salted2);
-- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-+ if (opaque.av_len)
-+ MD5_Update(&md5ctx, opaque.av_val, opaque.av_len);
-+ if (challenge.av_len)
-+ MD5_Update(&md5ctx, challenge.av_val, challenge.av_len);
-+ MD5_Update(&md5ctx, challenge2, B64INT_LEN);
-+ MD5_Final(md5sum_val, &md5ctx);
-+
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s%s%s) =>", __FUNCTION__,
-+ salted2, opaque.av_len ? opaque.av_val : "", challenge2);
-+ RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-
-- b64enc(md5sum_val, MD5_DIGEST_LENGTH, response, RESPONSE_LEN);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_2) = %s", __FUNCTION__, response);
-+ b64enc(md5sum_val, MD5_DIGEST_LENGTH, response, RESPONSE_LEN);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, b64(md5_2) = %s", __FUNCTION__, response);
-
- /* have all hashes, create auth token for the end of app */
-- pubToken.av_val = malloc(32 + strlen(challenge2) + strlen(response) + (opaque ? strlen(opaque) : 0));
-+ pubToken.av_val = malloc(32 + B64INT_LEN + B64DIGEST_LEN + opaque.av_len);
- pubToken.av_len = sprintf(pubToken.av_val,
- "&challenge=%s&response=%s&opaque=%s",
- challenge2,
- response,
-- opaque ? opaque : "");
-+ opaque.av_len ? opaque.av_val : "");
- RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken2: %s", __FUNCTION__, pubToken.av_val);
- free(orig_ptr);
- r->Link.pFlags |= RTMP_PUB_RESP|RTMP_PUB_CLATE;
-@@ -2710,8 +2723,26 @@ PublisherAuth(RTMP *r, AVal *description)
- {
- char *orig_ptr;
- char *par, *val = NULL;
-- char *user = NULL;
-- char *nonce = NULL;
-+ char *hash1, *hash2, *hash3;
-+ AVal user, nonce, *aptr = NULL;
-+ AVal apptmp;
-+
-+ /* llnw auth method
-+ * Seems to be closely based on HTTP Digest Auth:
-+ * http://tools.ietf.org/html/rfc2617
-+ * http://en.wikipedia.org/wiki/Digest_access_authentication
-+ */
-+
-+ const char authmod[] = "llnw";
-+ const char realm[] = "live";
-+ const char method[] = "publish";
-+ const char qop[] = "auth";
-+ /* nc = 1..connection count (or rather, number of times cnonce has been reused) */
-+ int nc = 1;
-+ /* nchex = hexenc(nc) (8 hex digits according to RFC 2617) */
-+ char nchex[9];
-+ /* cnonce = hexenc(4 random bytes) (initialized on first connection) */
-+ char cnonce[9];
-
- ptr = orig_ptr = strdup(token_in);
- /* Extract parameters (we need user and nonce) */
-@@ -2726,82 +2757,84 @@ PublisherAuth(RTMP *r, AVal *description)
- if(val)
- *val++ = '\0';
-
-+ if (aptr) {
-+ aptr->av_len = par - aptr->av_val - 1;
-+ aptr = NULL;
-+ }
- if (strcmp(par, "user") == 0){
-- user = val;
-+ user.av_val = val;
-+ aptr = &user;
- } else if (strcmp(par, "nonce") == 0){
-- nonce = val;
-+ nonce.av_val = val;
-+ aptr = &nonce;
- }
-
- RTMP_Log(RTMP_LOGDEBUG, "%s, par:\"%s\" = val:\"%s\"", __FUNCTION__, par, val);
- }
-+ if (aptr)
-+ aptr->av_len = strlen(aptr->av_val);
-
-- // FIXME: handle case where user==NULL or nonce==NULL
--
-- /* llnw auth method
-- * Seems to be closely based on HTTP Digest Auth:
-- * http://tools.ietf.org/html/rfc2617
-- * http://en.wikipedia.org/wiki/Digest_access_authentication
-- */
--
-- const char *authmod = "llnw";
-- const char *realm = "live";
-- const char *method = "publish";
-- const char *qop = "auth";
-- char *tmpbuf;
-+ /* FIXME: handle case where user==NULL or nonce==NULL */
-
-- /* nc = 1..connection count (or rather, number of times cnonce has been reused) */
-- int nc = 1;
-- /* nchex = hexenc(nc) (8 hex digits according to RFC 2617) */
-- char nchex[9];
- sprintf(nchex, "%08x", nc);
-- /* cnonce = hexenc(4 random bytes) (initialized on first connection) */
-- char cnonce[9];
-- srand( time(NULL) ); // FIXME: a lib shouldn't call srand()
- sprintf(cnonce, "%08x", rand());
-
- /* hash1 = hexenc(md5(user + ":" + realm + ":" + password)) */
-- tmpbuf = malloc(strlen(user) + 1 + strlen(realm) + 1 + r->Link.pubPasswd.av_len + 1);
-- sprintf(tmpbuf, "%s:%s:%s", user, realm, r->Link.pubPasswd.av_val);
-- md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ MD5_Init(&md5ctx);
-+ MD5_Update(&md5ctx, user.av_val, user.av_len);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, realm, sizeof(realm)-1);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, r->Link.pubPasswd.av_val, r->Link.pubPasswd.av_len);
-+ MD5_Final(md5sum_val, &md5ctx);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:%s:%s) =>", __FUNCTION__,
-+ user.av_val, realm, r->Link.pubPasswd.av_val);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- free(tmpbuf);
-- char *hash1 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+ hash1 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-
- /* hash2 = hexenc(md5(method + ":/" + app + "/" + appInstance)) */
- /* Extract appname + appinstance without query parameters */
-- char *apptmp = malloc(r->Link.app.av_len + 1), *qpos;
-- memcpy(apptmp, r->Link.app.av_val, r->Link.app.av_len);
-- apptmp[r->Link.app.av_len] = '\0';
-- if((qpos = strchr(apptmp, '?')))
-- *qpos = '\0';
--
-- tmpbuf = malloc(strlen(method) + 2 + strlen(apptmp) + 1);
-- sprintf(tmpbuf, "%s:/%s", method, apptmp);
-- md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ apptmp = r->Link.app;
-+ ptr = strchr(apptmp.av_val, '?');
-+ if (ptr)
-+ apptmp.av_len = ptr - apptmp.av_val;
-+
-+ MD5_Init(&md5ctx);
-+ MD5_Update(&md5ctx, method, sizeof(method)-1);
-+ MD5_Update(&md5ctx, ":/", 2);
-+ MD5_Update(&md5ctx, apptmp.av_val, apptmp.av_len);
-+ MD5_Final(md5sum_val, &md5ctx);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:/%.*s) =>", __FUNCTION__,
-+ method, apptmp.av_len, apptmp.av_val);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- free(tmpbuf);
-- char *hash2 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
--
-- free(apptmp);
-+ hash2 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-
- /* hash3 = hexenc(md5(hash1 + ":" + nonce + ":" + nchex + ":" + cnonce + ":" + qop + ":" + hash2)) */
-- tmpbuf = malloc(strlen(hash1) + 1 + strlen(nonce) + 1 + strlen(nchex) + 1 + strlen(cnonce) + 1 + strlen(qop) + 1 + strlen(hash2) + 1);
-- sprintf(tmpbuf, "%s:%s:%s:%s:%s:%s", hash1, nonce, nchex, cnonce, qop, hash2);
-- md5sum((unsigned char*)tmpbuf, strlen(tmpbuf), md5sum_val);
-- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s) =>", __FUNCTION__, tmpbuf);
-+ MD5_Init(&md5ctx);
-+ MD5_Update(&md5ctx, hash1, HEXHASH_LEN);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, nonce.av_val, nonce.av_len);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, nchex, sizeof(nchex)-1);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, cnonce, sizeof(cnonce)-1);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, qop, sizeof(qop)-1);
-+ MD5_Update(&md5ctx, ":", 1);
-+ MD5_Update(&md5ctx, hash2, HEXHASH_LEN);
-+ MD5_Final(md5sum_val, &md5ctx);
-+ RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:%s:%s:%s:%s:%s) =>", __FUNCTION__,
-+ hash1, nonce.av_val, nchex, cnonce, qop, hash2);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- free(tmpbuf);
-- char *hash3 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+ hash3 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-
- /* pubToken = &authmod=<authmod>&user=<username>&nonce=<nonce>&cnonce=<cnonce>&nc=<nchex>&response=<hash3> */
- /* Append nonces and response to query string which already contains
- * user + authmod */
-- pubToken.av_val = malloc(64 + strlen(authmod) + strlen(user) + strlen(nonce) + strlen(cnonce) + strlen(nchex) + strlen(hash3));
-+ pubToken.av_val = malloc(64 + sizeof(authmod)-1 + user.av_len + nonce.av_len + sizeof(cnonce)-1 + sizeof(nchex)-1 + HEXHASH_LEN);
- sprintf(pubToken.av_val,
- "&nonce=%s&cnonce=%s&nc=%s&response=%s",
-- nonce, cnonce, nchex, hash3);
-+ nonce.av_val, cnonce, nchex, hash3);
- pubToken.av_len = strlen(pubToken.av_val);
- RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken2: %s", __FUNCTION__, pubToken.av_val);
- r->Link.pFlags |= RTMP_PUB_RESP|RTMP_PUB_CLATE;
---
-1.7.10.4
-
-
-From 1f6c6434d6794b3ba14540a141bab358eba48b13 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 11:30:07 -0700
-Subject: [PATCH 59/64] More authentication cleanup
-
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 6d04708..4858e24 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2512,15 +2512,14 @@ typedef struct md5_ctx MD5_CTX
- static const AVal av_authmod_adobe = AVC("authmod=adobe");
- static const AVal av_authmod_llnw = AVC("authmod=llnw");
-
--static char *hexenc(unsigned char *inbuf, int len)
-+static void hexenc(unsigned char *inbuf, int len, char *dst)
- {
-- char *dst = malloc(len * 2 + 1), *ptr = dst;
-+ char *ptr = dst;
- while(len--) {
- sprintf(ptr, "%02x", *inbuf++);
- ptr += 2;
- }
- *ptr = '\0';
-- return dst;
- }
-
- static int
-@@ -2723,7 +2722,7 @@ PublisherAuth(RTMP *r, AVal *description)
- {
- char *orig_ptr;
- char *par, *val = NULL;
-- char *hash1, *hash2, *hash3;
-+ char hash1[HEXHASH_LEN+1], hash2[HEXHASH_LEN+1], hash3[HEXHASH_LEN+1];
- AVal user, nonce, *aptr = NULL;
- AVal apptmp;
-
-@@ -2790,7 +2789,7 @@ PublisherAuth(RTMP *r, AVal *description)
- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:%s:%s) =>", __FUNCTION__,
- user.av_val, realm, r->Link.pubPasswd.av_val);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- hash1 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+ hexenc(md5sum_val, MD5_DIGEST_LENGTH, hash1);
-
- /* hash2 = hexenc(md5(method + ":/" + app + "/" + appInstance)) */
- /* Extract appname + appinstance without query parameters */
-@@ -2807,7 +2806,7 @@ PublisherAuth(RTMP *r, AVal *description)
- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:/%.*s) =>", __FUNCTION__,
- method, apptmp.av_len, apptmp.av_val);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- hash2 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+ hexenc(md5sum_val, MD5_DIGEST_LENGTH, hash2);
-
- /* hash3 = hexenc(md5(hash1 + ":" + nonce + ":" + nchex + ":" + cnonce + ":" + qop + ":" + hash2)) */
- MD5_Init(&md5ctx);
-@@ -2826,7 +2825,7 @@ PublisherAuth(RTMP *r, AVal *description)
- RTMP_Log(RTMP_LOGDEBUG, "%s, md5(%s:%s:%s:%s:%s:%s) =>", __FUNCTION__,
- hash1, nonce.av_val, nchex, cnonce, qop, hash2);
- RTMP_LogHexString(RTMP_LOGDEBUG, md5sum_val, MD5_DIGEST_LENGTH);
-- hash3 = hexenc(md5sum_val, MD5_DIGEST_LENGTH);
-+ hexenc(md5sum_val, MD5_DIGEST_LENGTH, hash3);
-
- /* pubToken = &authmod=<authmod>&user=<username>&nonce=<nonce>&cnonce=<cnonce>&nc=<nchex>&response=<hash3> */
- /* Append nonces and response to query string which already contains
-@@ -2839,9 +2838,6 @@ PublisherAuth(RTMP *r, AVal *description)
- RTMP_Log(RTMP_LOGDEBUG, "%s, pubToken2: %s", __FUNCTION__, pubToken.av_val);
- r->Link.pFlags |= RTMP_PUB_RESP|RTMP_PUB_CLATE;
-
-- free(hash1);
-- free(hash2);
-- free(hash3);
- free(orig_ptr);
- }
- else if(strstr(description->av_val, "?reason=authfail") != NULL)
---
-1.7.10.4
-
-
-From 9d6dc72d7c43554dbe8cdb02f450807230df8c25 Mon Sep 17 00:00:00 2001
-From: Martin Storsjo <martin@martin.st>
-Date: Tue, 30 Oct 2012 19:22:16 +0200
-Subject: [PATCH 60/64] Simplify initializing the TLS server context
-
-This does the same thing, but I wasn't aware of these functions
-when I initially wrote this.
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 4858e24..d72f105 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -280,32 +280,14 @@ RTMP_TLS_AllocServerContext(const char* cert, const char* key)
- }
- #elif !defined(NO_SSL) /* USE_OPENSSL */
- ctx = SSL_CTX_new(SSLv23_server_method());
-- FILE *f = fopen(key, "r");
-- if (!f) {
-+ if (!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
- SSL_CTX_free(ctx);
- return NULL;
- }
-- EVP_PKEY *k = PEM_read_PrivateKey(f, NULL, NULL, NULL);
-- fclose(f);
-- if (!k) {
-+ if (!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
- 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;
---
-1.7.10.4
-
-
-From f3e3e6b507ac0df89a11764abd15cc9535593735 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Bj=C3=B6rn=20Axelsson?= <bjorn.axelsson@intinor.se>
-Date: Tue, 30 Oct 2012 19:31:01 +0200
-Subject: [PATCH 61/64] Look for a fourth slash when splitting the url into
- app+playpath
-
-
-diff --git a/librtmp/parseurl.c b/librtmp/parseurl.c
-index 0183958..646c70c 100644
---- a/librtmp/parseurl.c
-+++ b/librtmp/parseurl.c
-@@ -137,12 +137,14 @@ parsehost:
- * application = app[/appinstance]
- */
-
-- char *slash2, *slash3 = NULL;
-+ char *slash2, *slash3 = NULL, *slash4 = NULL;
- int applen, appnamelen;
-
- slash2 = strchr(p, '/');
- if(slash2)
- slash3 = strchr(slash2+1, '/');
-+ if(slash3)
-+ slash4 = strchr(slash3+1, '/');
-
- applen = end-p; /* ondemand, pass all parameters as app */
- appnamelen = applen; /* ondemand length */
-@@ -156,7 +158,9 @@ parsehost:
- appnamelen = 8;
- }
- else { /* app!=ondemand, so app is app[/appinstance] */
-- if(slash3)
-+ if(slash4)
-+ appnamelen = slash4-p;
-+ else if(slash3)
- appnamelen = slash3-p;
- else if(slash2)
- appnamelen = slash2-p;
---
-1.7.10.4
-
-
-From e79a07c8625b56ebb182c12343518faff4902de7 Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Tue, 30 Oct 2012 14:40:14 -0700
-Subject: [PATCH 62/64] PolarSSL version fixes
-
-Fix commit a312ac7770207bd7d07725c1aef43725206e803a
-
-diff --git a/librtmp/dh.h b/librtmp/dh.h
-index fa264f8..e29587b 100644
---- a/librtmp/dh.h
-+++ b/librtmp/dh.h
-@@ -29,9 +29,6 @@
-
- #ifdef USE_POLARSSL
- #include <polarssl/dhm.h>
--#if POLARSSL_VERSION_NUMBER < 0x01010100
--#define havege_random havege_rand
--#endif
- typedef mpi * MP_t;
- #define MP_new(m) m = malloc(sizeof(mpi)); mpi_init(m)
- #define MP_set_w(mpi, w) mpi_lset(mpi, w)
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index d72f105..720669e 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -34,7 +34,6 @@
-
- #ifdef CRYPTO
- #ifdef USE_POLARSSL
--#include <polarssl/version.h>
- #include <polarssl/havege.h>
- #include <polarssl/md5.h>
- #include <polarssl/base64.h>
-@@ -2435,7 +2434,7 @@ static int
- b64enc(const unsigned char *input, int length, char *output, int maxsize)
- {
- #ifdef USE_POLARSSL
-- int buf_size = maxsize;
-+ size_t buf_size = maxsize;
- if(base64_encode((unsigned char *) output, &buf_size, input, length) == 0)
- {
- output[buf_size] = '\0';
-@@ -2481,7 +2480,7 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
- #ifdef USE_POLARSSL
- #define MD5_CTX md5_context
- #define MD5_Init(ctx) md5_starts(ctx)
--#define MD5_Update(ctx,data,len) md5_update(ctx,data,len)
-+#define MD5_Update(ctx,data,len) md5_update(ctx,(unsigned char *)data,len)
- #define MD5_Final(dig,ctx) md5_finish(ctx,dig)
- #elif defined(USE_GNUTLS)
- typedef struct md5_ctx MD5_CTX
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index 2cdb705..6e2356a 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -65,7 +65,7 @@
- #include <polarssl/net.h>
- #include <polarssl/ssl.h>
- #include <polarssl/havege.h>
--#if POLARSSL_VERSION_NUMBER < 0x01010100
-+#if POLARSSL_VERSION_NUMBER < 0x01010000
- #define havege_random havege_rand
- #endif
- typedef struct tls_ctx {
-@@ -88,7 +88,7 @@ typedef struct tls_server_ctx {
- 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_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);\
---
-1.7.10.4
-
-
-From feb81c8b3e0102b2eed18a34cbfb1e8a513e99ae Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Thu, 1 Nov 2012 17:00:31 -0700
-Subject: [PATCH 63/64] Fix gnutls build
-
-Missing semicolon in e42b5d0926b1a668d7fbd794a70f31040c5f198d
-
-diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
-index 720669e..0e00059 100644
---- a/librtmp/rtmp.c
-+++ b/librtmp/rtmp.c
-@@ -2483,7 +2483,7 @@ b64enc(const unsigned char *input, int length, char *output, int maxsize)
- #define MD5_Update(ctx,data,len) md5_update(ctx,(unsigned char *)data,len)
- #define MD5_Final(dig,ctx) md5_finish(ctx,dig)
- #elif defined(USE_GNUTLS)
--typedef struct md5_ctx MD5_CTX
-+typedef struct md5_ctx MD5_CTX;
- #define MD5_Init(ctx) md5_init(ctx)
- #define MD5_Update(ctx,data,len) md5_update(ctx,len,data)
- #define MD5_Final(dig,ctx) md5_digest(ctx,MD5_DIGEST_LENGTH,dig)
---
-1.7.10.4
-
-
-From 19d36368f6c1ec6fa55df319173ca93048309f9a Mon Sep 17 00:00:00 2001
-From: Howard Chu <hyc@highlandsun.com>
-Date: Fri, 9 Nov 2012 07:58:08 -0800
-Subject: [PATCH 64/64] PolarSSL 1.2.x compat
-
-
-diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h
-index 6e2356a..85d7e53 100644
---- a/librtmp/rtmp_sys.h
-+++ b/librtmp/rtmp_sys.h
-@@ -68,6 +68,11 @@
- #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;
-@@ -85,12 +90,12 @@ typedef struct tls_server_ctx {
- 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)
-+ 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_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)
---
-1.7.10.4
-