[rtmpdump] r115 - in trunk: rtmp.c rtmp.h rtmpdump.c rtmpsrv.c streams.c
hyc
subversion at mplayerhq.hu
Sun Dec 27 00:37:46 CET 2009
Author: hyc
Date: Sun Dec 27 00:37:45 2009
New Revision: 115
Log:
SecureToken support
Modified:
trunk/rtmp.c
trunk/rtmp.h
trunk/rtmpdump.c
trunk/rtmpsrv.c
trunk/streams.c
Modified: trunk/rtmp.c
==============================================================================
--- trunk/rtmp.c Sun Dec 27 00:36:35 2009 (r114)
+++ trunk/rtmp.c Sun Dec 27 00:37:45 2009 (r115)
@@ -110,6 +110,8 @@ static bool WriteN(RTMP * r, const char
static bool FillBuffer(RTMP * r);
+static void DecodeTEA(AVal *key, AVal *text);
+
uint32_t
RTMP_GetTime()
{
@@ -872,6 +874,8 @@ SAVC(audioCodecs);
SAVC(videoCodecs);
SAVC(videoFunction);
SAVC(objectEncoding);
+SAVC(secureToken);
+SAVC(secureTokenResponse);
static bool
SendConnectPacket(RTMP * r)
@@ -1292,6 +1296,33 @@ SendPlay(RTMP * r)
return RTMP_SendPacket(r, &packet, true);
}
+static bool
+SendSecureTokenResponse(RTMP *r, AVal *resp)
+{
+ RTMPPacket packet;
+ char pbuf[1024], *pend = pbuf+sizeof(pbuf);
+
+ packet.m_nChannel = 0x03; /* control channel (invoke) */
+ packet.m_headerType = RTMP_PACKET_SIZE_MEDIUM;
+ packet.m_packetType = 0x14;
+ packet.m_nInfoField2 = 0;
+ packet.m_nInfoField1 = 0;
+ packet.m_hasAbsTimestamp = 0;
+ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
+
+ char *enc = packet.m_body;
+ enc = AMF_EncodeString(enc, pend, &av_secureTokenResponse);
+ enc = AMF_EncodeNumber(enc, pend, 0.0);
+ *enc++ = AMF_NULL;
+ enc = AMF_EncodeString(enc, pend, resp);
+ if (!enc)
+ return false;
+
+ packet.m_nBodySize = enc - packet.m_body;
+
+ return RTMP_SendPacket(r, &packet, false);
+}
+
/*
from http://jira.red5.org/confluence/display/docs/Ping:
@@ -1445,12 +1476,21 @@ HandleInvoke(RTMP * r, const char *body,
if (AVMATCH(&methodInvoked, &av_connect))
{
+ if (r->Link.token.av_len)
+ {
+ AMFObjectProperty p;
+ if (RTMP_FindFirstMatchingProperty(&obj, &av_secureToken, &p))
+ {
+ DecodeTEA(&r->Link.token, &p.p_vu.p_aval);
+ SendSecureTokenResponse(r, &p.p_vu.p_aval);
+ }
+ }
SendServerBW(r);
SendCtrl(r, 3, 0, 300);
SendCreateStream(r, 2.0);
- // Send the FCSubscribe if live stream or if subscribepath is set
+ /* Send the FCSubscribe if live stream or if subscribepath is set */
if (r->Link.subscribepath.av_len)
SendFCSubscribe(r, &r->Link.subscribepath);
else if (r->Link.bLiveStream)
@@ -1572,8 +1612,8 @@ RTMP_FindFirstMatchingProperty(AMFObject
if (prop->p_type == AMF_OBJECT)
{
- return RTMP_FindFirstMatchingProperty(&prop->p_vu.p_object, name,
- p);
+ if (RTMP_FindFirstMatchingProperty(&prop->p_vu.p_object, name, p))
+ return true;
}
}
return false;
@@ -2273,3 +2313,71 @@ again:
return true;
}
+
+#define HEX2BIN(a) (((a)&0x40)?((a)&0xf)+9:((a)&0xf))
+#define BIN2HEX(a) (((a)>9)?((a)+96):((a)+48))
+
+static void
+DecodeTEA(AVal *key, AVal *text)
+{
+ uint32_t *v, k[4] = {0}, u;
+ uint32_t z, y, sum=0, e, DELTA=0x9e3779b9;
+ int32_t p, q;
+ int i, n;
+ unsigned char *ptr, *out;
+
+ /* prep key */
+ ptr = (unsigned char *)key->av_val;
+ u = 0; n = 0;
+ v = k;
+ p = key->av_len > 16 ? 16:key->av_len;
+ for (i=0; i<p; i++)
+ {
+ u |= ptr[i] << (n*8);
+ if (n==3)
+ {
+ *v++ = u;
+ u = 0;
+ n = 0;
+ }
+ else
+ {
+ n++;
+ }
+ }
+ *v = u;
+
+ /* prep text */
+ n = (text->av_len+7)/8;
+ out = malloc(n*8);
+ ptr = (unsigned char *)text->av_val;
+ v = (uint32_t *)out;
+ for (i=0; i<n; i++)
+ {
+ u = (HEX2BIN(ptr[0]) << 4) + HEX2BIN(ptr[1]);
+ u |= ((HEX2BIN(ptr[2]) << 4) + HEX2BIN(ptr[3])) << 8;
+ u |= ((HEX2BIN(ptr[4]) << 4) + HEX2BIN(ptr[5])) << 16;
+ u |= ((HEX2BIN(ptr[6]) << 4) + HEX2BIN(ptr[7])) << 24;
+ *v++ = u;
+ ptr += 8;
+ }
+ v = (uint32_t *)out;
+
+#define MX (((z>>5)^(y<<2)) + ((y>>3)^(z<<4))) ^ ((sum^y) + (k[(p&3)^e]^z));
+ z=v[n-1];
+ y=v[0];
+ q = 6+52/n ;
+ sum = q*DELTA ;
+ while (sum != 0)
+ {
+ e = sum>>2 & 3;
+ for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX;
+ z = v[n-1];
+ y = v[0] -= MX;
+ sum -= DELTA;
+ }
+ /* bin 2 hex */
+ text->av_len /= 2;
+ memcpy(text->av_val, out, text->av_len);
+ free(out);
+}
Modified: trunk/rtmp.h
==============================================================================
--- trunk/rtmp.h Sun Dec 27 00:36:35 2009 (r114)
+++ trunk/rtmp.h Sun Dec 27 00:37:45 2009 (r115)
@@ -104,6 +104,7 @@ typedef struct RTMP_LNK
AVal auth;
AVal flashVer;
AVal subscribepath;
+ AVal token;
double seekTime;
uint32_t length;
Modified: trunk/rtmpdump.c
==============================================================================
--- trunk/rtmpdump.c Sun Dec 27 00:36:35 2009 (r114)
+++ trunk/rtmpdump.c Sun Dec 27 00:37:45 2009 (r115)
@@ -1096,6 +1096,7 @@ main(int argc, char **argv)
AVal swfHash = { 0, 0 };
uint32_t swfSize = 0;
AVal flashVer = { 0, 0 };
+ AVal token = { 0, 0 };
char *sockshost = 0;
char *flvFile = 0;
@@ -1161,6 +1162,7 @@ main(int argc, char **argv)
{"subscribe", 1, NULL, 'd'},
{"start", 1, NULL, 'A'},
{"stop", 1, NULL, 'B'},
+ {"token", 1, NULL, 'T'},
{"hashes", 0, NULL, '#'},
{"debug", 0, NULL, 'z'},
{"quiet", 0, NULL, 'q'},
@@ -1170,7 +1172,7 @@ main(int argc, char **argv)
while ((opt =
getopt_long(argc, argv,
- "hVveqzr:s:t:p:a:b:f:o:u:n:c:l:y:m:k:d:A:B:w:x:S:#",
+ "hVveqzr:s:t:p:a:b:f:o:u:n:c:l:y:m:k:d:A:B:T:w:x:S:#",
longopts, NULL)) != -1)
{
switch (opt)
@@ -1223,6 +1225,8 @@ main(int argc, char **argv)
LogPrintf
("--stop|-B num Stop at num seconds into stream\n");
LogPrintf
+ ("--token|-T key Key for SecureToken response\n");
+ LogPrintf
("--hashes|-# Display progress with hashes, not with the byte counter\n");
LogPrintf
("--buffer|-b Buffer time in milliseconds (default: %lu), this option makes only sense in stdout mode (-o -)\n",
@@ -1391,6 +1395,9 @@ main(int argc, char **argv)
case 'B':
dStopOffset = (int) (atof(optarg) * 1000.0);
break;
+ case 'T':
+ STR2AVAL(token, optarg);
+ break;
case '#':
bHashes = true;
break;
@@ -1519,6 +1526,7 @@ main(int argc, char **argv)
&tcUrl, &swfUrl, &pageUrl, &app, &auth, &swfHash, swfSize,
&flashVer, &subscribepath, dSeek, 0, bLiveStream, timeout);
+ rtmp.Link.token = token;
off_t size = 0;
// ok, we have to get the timestamp of the last keyframe (only keyframes are seekable) / last audio frame (audio only streams)
Modified: trunk/rtmpsrv.c
==============================================================================
--- trunk/rtmpsrv.c Sun Dec 27 00:36:35 2009 (r114)
+++ trunk/rtmpsrv.c Sun Dec 27 00:37:45 2009 (r115)
@@ -133,6 +133,7 @@ SAVC(mode);
SAVC(level);
SAVC(code);
SAVC(description);
+SAVC(secureToken);
static bool
SendConnectResult(RTMP *r, double txn)
@@ -173,6 +174,10 @@ SendConnectResult(RTMP *r, double txn)
STR2AVAL(av, "Connection succeeded.");
enc = AMF_EncodeNamedString(enc, pend, &av_description, &av);
enc = AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, r->m_fEncoding);
+#if 0
+ STR2AVAL(av, "58656322c972d6cdf2d776167575045f8484ea888e31c086f7b5ffbd0baec55ce442c2fb");
+ enc = AMF_EncodeNamedString(enc, pend, &av_secureToken, &av);
+#endif
STR2AVAL(p.p_name, "version");
STR2AVAL(p.p_vu.p_aval, "3,5,1,525");
p.p_type = AMF_STRING;
Modified: trunk/streams.c
==============================================================================
--- trunk/streams.c Sun Dec 27 00:36:35 2009 (r114)
+++ trunk/streams.c Sun Dec 27 00:37:45 2009 (r115)
@@ -100,6 +100,7 @@ typedef struct
AVal auth;
AVal swfHash;
AVal flashVer;
+ AVal token;
AVal subscribepath;
uint32_t swfSize;
@@ -674,6 +675,7 @@ void processTCPrequest(STREAMING_SERVER
RTMP_SetupStream(&rtmp, req.protocol, req.hostname, req.rtmpport, NULL, // sockshost
&req.playpath, &req.tcUrl, &req.swfUrl, &req.pageUrl, &req.app, &req.auth, &req.swfHash, req.swfSize, &req.flashVer, &req.subscribepath, dSeek, -1, // length
req.bLiveStream, req.timeout);
+ rtmp.Link.token = req.token;
LogPrintf("Connecting ... port: %d, app: %s\n", req.rtmpport, req.app);
if (!RTMP_Connect(&rtmp))
@@ -1044,6 +1046,9 @@ ParseOption(char opt, char *arg, RTMP_RE
req->dStopOffset = atoi(arg) * 1000;
//printf("dStartOffset = %d\n", dStartOffset);
break;
+ case 'T':
+ STR2AVAL(req->token, arg);
+ break;
case 'q':
debuglevel = LOGCRIT;
break;
@@ -1112,6 +1117,7 @@ main(int argc, char **argv)
{"subscribe", 1, NULL, 'd'},
{"start", 1, NULL, 'A'},
{"stop", 1, NULL, 'B'},
+ {"token", 1, NULL, 'T'},
{"debug", 0, NULL, 'z'},
{"quiet", 0, NULL, 'q'},
{"verbose", 0, NULL, 'V'},
@@ -1123,7 +1129,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:g:w:x:", longopts,
+ "hvqVzr:s:t:p:a:f:u:n:c:l:y:m:d:D:A:B:T:g:w:x:", longopts,
NULL)) != -1)
{
switch (opt)
@@ -1168,6 +1174,8 @@ main(int argc, char **argv)
LogPrintf
("--stop|-B num Stop at num seconds into stream\n");
LogPrintf
+ ("--token|-T key Key for SecureToken response\n");
+ LogPrintf
("--buffer|-b Buffer time in milliseconds (default: %lu)\n\n",
defaultRTMPRequest.bufferTime);
More information about the rtmpdump
mailing list