1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * RTMP protocol
25  */
26 
27 #include "config_components.h"
28 
29 #include "libavcodec/bytestream.h"
30 #include "libavutil/avstring.h"
31 #include "libavutil/base64.h"
32 #include "libavutil/intfloat.h"
33 #include "libavutil/lfg.h"
34 #include "libavutil/md5.h"
35 #include "libavutil/opt.h"
36 #include "libavutil/random_seed.h"
37 #include "avformat.h"
38 #include "internal.h"
39 
40 #include "network.h"
41 
42 #include "flv.h"
43 #include "rtmp.h"
44 #include "rtmpcrypt.h"
45 #include "rtmppkt.h"
46 #include "url.h"
47 #include "version.h"
48 
49 #if CONFIG_ZLIB
50 #include <zlib.h>
51 #endif
52 
53 #define APP_MAX_LENGTH 1024
54 #define TCURL_MAX_LENGTH 1024
55 #define FLASHVER_MAX_LENGTH 64
56 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
57 #define RTMP_HEADER 11
58 
59 /** RTMP protocol handler state */
60 typedef enum {
61     STATE_START,      ///< client has not done anything yet
62     STATE_HANDSHAKED, ///< client has performed handshake
63     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
64     STATE_PLAYING,    ///< client has started receiving multimedia data from server
65     STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
66     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
67     STATE_RECEIVING,  ///< received a publish command (for input)
68     STATE_SENDING,    ///< received a play command (for output)
69     STATE_STOPPED,    ///< the broadcast has been stopped
70 } ClientState;
71 
72 typedef struct TrackedMethod {
73     char *name;
74     int id;
75 } TrackedMethod;
76 
77 /** protocol handler context */
78 typedef struct RTMPContext {
79     const AVClass *class;
80     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
81     RTMPPacket    *prev_pkt[2];               ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
82     int           nb_prev_pkt[2];             ///< number of elements in prev_pkt
83     int           in_chunk_size;              ///< size of the chunks incoming RTMP packets are divided into
84     int           out_chunk_size;             ///< size of the chunks outgoing RTMP packets are divided into
85     int           is_input;                   ///< input/output flag
86     char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
87     int           live;                       ///< 0: recorded, -1: live, -2: both
88     char          *app;                       ///< name of application
89     char          *conn;                      ///< append arbitrary AMF data to the Connect message
90     ClientState   state;                      ///< current state
91     int           stream_id;                  ///< ID assigned by the server for the stream
92     uint8_t*      flv_data;                   ///< buffer with data for demuxer
93     int           flv_size;                   ///< current buffer size
94     int           flv_off;                    ///< number of bytes read from current buffer
95     int           flv_nb_packets;             ///< number of flv packets published
96     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
97     uint32_t      receive_report_size;        ///< number of bytes after which we should report the number of received bytes to the peer
98     uint64_t      bytes_read;                 ///< number of bytes read from server
99     uint64_t      last_bytes_read;            ///< number of bytes read last reported to server
100     uint32_t      last_timestamp;             ///< last timestamp received in a packet
101     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
102     int           has_audio;                  ///< presence of audio data
103     int           has_video;                  ///< presence of video data
104     int           received_metadata;          ///< Indicates if we have received metadata about the streams
105     uint8_t       flv_header[RTMP_HEADER];    ///< partial incoming flv packet header
106     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
107     int           nb_invokes;                 ///< keeps track of invoke messages
108     char*         tcurl;                      ///< url of the target stream
109     char*         flashver;                   ///< version of the flash plugin
110     char*         swfhash;                    ///< SHA256 hash of the decompressed SWF file (32 bytes)
111     int           swfhash_len;                ///< length of the SHA256 hash
112     int           swfsize;                    ///< size of the decompressed SWF file
113     char*         swfurl;                     ///< url of the swf player
114     char*         swfverify;                  ///< URL to player swf file, compute hash/size automatically
115     char          swfverification[42];        ///< hash of the SWF verification
116     char*         pageurl;                    ///< url of the web page
117     char*         subscribe;                  ///< name of live stream to subscribe
118     int           max_sent_unacked;           ///< max unacked sent bytes
119     int           client_buffer_time;         ///< client buffer time in ms
120     int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
121     int           encrypted;                  ///< use an encrypted connection (RTMPE only)
122     TrackedMethod*tracked_methods;            ///< tracked methods buffer
123     int           nb_tracked_methods;         ///< number of tracked methods
124     int           tracked_methods_size;       ///< size of the tracked methods buffer
125     int           listen;                     ///< listen mode flag
126     int           listen_timeout;             ///< listen timeout to wait for new connections
127     int           nb_streamid;                ///< The next stream id to return on createStream calls
128     double        duration;                   ///< Duration of the stream in seconds as returned by the server (only valid if non-zero)
129     int           tcp_nodelay;                ///< Use TCP_NODELAY to disable Nagle's algorithm if set to 1
130     char          username[50];
131     char          password[50];
132     char          auth_params[500];
133     int           do_reconnect;
134     int           auth_tried;
135 } RTMPContext;
136 
137 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
138 /** Client key used for digest signing */
139 static const uint8_t rtmp_player_key[] = {
140     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
141     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
142 
143     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
144     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
145     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
146 };
147 
148 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
149 /** Key used for RTMP server digest signing */
150 static const uint8_t rtmp_server_key[] = {
151     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
152     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
153     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
154 
155     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
156     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
157     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
158 };
159 
160 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt);
161 static int handle_window_ack_size(URLContext *s, RTMPPacket *pkt);
162 static int handle_set_peer_bw(URLContext *s, RTMPPacket *pkt);
163 
add_tracked_method(RTMPContext *rt, const char *name, int id)164 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
165 {
166     int err;
167 
168     if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
169         rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
170         if ((err = av_reallocp_array(&rt->tracked_methods, rt->tracked_methods_size,
171                                sizeof(*rt->tracked_methods))) < 0) {
172             rt->nb_tracked_methods = 0;
173             rt->tracked_methods_size = 0;
174             return err;
175         }
176     }
177 
178     rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
179     if (!rt->tracked_methods[rt->nb_tracked_methods].name)
180         return AVERROR(ENOMEM);
181     rt->tracked_methods[rt->nb_tracked_methods].id = id;
182     rt->nb_tracked_methods++;
183 
184     return 0;
185 }
186 
del_tracked_method(RTMPContext *rt, int index)187 static void del_tracked_method(RTMPContext *rt, int index)
188 {
189     memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
190             sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
191     rt->nb_tracked_methods--;
192 }
193 
find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset, char **tracked_method)194 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
195                                char **tracked_method)
196 {
197     RTMPContext *rt = s->priv_data;
198     GetByteContext gbc;
199     double pkt_id;
200     int ret;
201     int i;
202 
203     bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
204     if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
205         return ret;
206 
207     for (i = 0; i < rt->nb_tracked_methods; i++) {
208         if (rt->tracked_methods[i].id != pkt_id)
209             continue;
210 
211         *tracked_method = rt->tracked_methods[i].name;
212         del_tracked_method(rt, i);
213         break;
214     }
215 
216     return 0;
217 }
218 
free_tracked_methods(RTMPContext *rt)219 static void free_tracked_methods(RTMPContext *rt)
220 {
221     int i;
222 
223     for (i = 0; i < rt->nb_tracked_methods; i ++)
224         av_freep(&rt->tracked_methods[i].name);
225     av_freep(&rt->tracked_methods);
226     rt->tracked_methods_size = 0;
227     rt->nb_tracked_methods   = 0;
228 }
229 
rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)230 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
231 {
232     int ret;
233 
234     if (pkt->type == RTMP_PT_INVOKE && track) {
235         GetByteContext gbc;
236         char name[128];
237         double pkt_id;
238         int len;
239 
240         bytestream2_init(&gbc, pkt->data, pkt->size);
241         if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
242             goto fail;
243 
244         if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
245             goto fail;
246 
247         if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
248             goto fail;
249     }
250 
251     ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
252                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
253 fail:
254     ff_rtmp_packet_destroy(pkt);
255     return ret;
256 }
257 
rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)258 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
259 {
260     char *field, *value;
261     char type;
262 
263     /* The type must be B for Boolean, N for number, S for string, O for
264      * object, or Z for null. For Booleans the data must be either 0 or 1 for
265      * FALSE or TRUE, respectively. Likewise for Objects the data must be
266      * 0 or 1 to end or begin an object, respectively. Data items in subobjects
267      * may be named, by prefixing the type with 'N' and specifying the name
268      * before the value (ie. NB:myFlag:1). This option may be used multiple times
269      * to construct arbitrary AMF sequences. */
270     if (param[0] && param[1] == ':') {
271         type = param[0];
272         value = param + 2;
273     } else if (param[0] == 'N' && param[1] && param[2] == ':') {
274         type = param[1];
275         field = param + 3;
276         value = strchr(field, ':');
277         if (!value)
278             goto fail;
279         *value = '\0';
280         value++;
281 
282         ff_amf_write_field_name(p, field);
283     } else {
284         goto fail;
285     }
286 
287     switch (type) {
288     case 'B':
289         ff_amf_write_bool(p, value[0] != '0');
290         break;
291     case 'S':
292         ff_amf_write_string(p, value);
293         break;
294     case 'N':
295         ff_amf_write_number(p, strtod(value, NULL));
296         break;
297     case 'Z':
298         ff_amf_write_null(p);
299         break;
300     case 'O':
301         if (value[0] != '0')
302             ff_amf_write_object_start(p);
303         else
304             ff_amf_write_object_end(p);
305         break;
306     default:
307         goto fail;
308         break;
309     }
310 
311     return 0;
312 
313 fail:
314     av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
315     return AVERROR(EINVAL);
316 }
317 
318 /**
319  * Generate 'connect' call and send it to the server.
320  */
gen_connect(URLContext *s, RTMPContext *rt)321 static int gen_connect(URLContext *s, RTMPContext *rt)
322 {
323     RTMPPacket pkt;
324     uint8_t *p;
325     int ret;
326 
327     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
328                                      0, 4096 + APP_MAX_LENGTH)) < 0)
329         return ret;
330 
331     p = pkt.data;
332 
333     ff_amf_write_string(&p, "connect");
334     ff_amf_write_number(&p, ++rt->nb_invokes);
335     ff_amf_write_object_start(&p);
336     ff_amf_write_field_name(&p, "app");
337     ff_amf_write_string2(&p, rt->app, rt->auth_params);
338 
339     if (!rt->is_input) {
340         ff_amf_write_field_name(&p, "type");
341         ff_amf_write_string(&p, "nonprivate");
342     }
343     ff_amf_write_field_name(&p, "flashVer");
344     ff_amf_write_string(&p, rt->flashver);
345 
346     if (rt->swfurl || rt->swfverify) {
347         ff_amf_write_field_name(&p, "swfUrl");
348         if (rt->swfurl)
349             ff_amf_write_string(&p, rt->swfurl);
350         else
351             ff_amf_write_string(&p, rt->swfverify);
352     }
353 
354     ff_amf_write_field_name(&p, "tcUrl");
355     ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
356     if (rt->is_input) {
357         ff_amf_write_field_name(&p, "fpad");
358         ff_amf_write_bool(&p, 0);
359         ff_amf_write_field_name(&p, "capabilities");
360         ff_amf_write_number(&p, 15.0);
361 
362         /* Tell the server we support all the audio codecs except
363          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
364          * which are unused in the RTMP protocol implementation. */
365         ff_amf_write_field_name(&p, "audioCodecs");
366         ff_amf_write_number(&p, 4071.0);
367         ff_amf_write_field_name(&p, "videoCodecs");
368         ff_amf_write_number(&p, 252.0);
369         ff_amf_write_field_name(&p, "videoFunction");
370         ff_amf_write_number(&p, 1.0);
371 
372         if (rt->pageurl) {
373             ff_amf_write_field_name(&p, "pageUrl");
374             ff_amf_write_string(&p, rt->pageurl);
375         }
376     }
377     ff_amf_write_object_end(&p);
378 
379     if (rt->conn) {
380         char *param = rt->conn;
381 
382         // Write arbitrary AMF data to the Connect message.
383         while (param) {
384             char *sep;
385             param += strspn(param, " ");
386             if (!*param)
387                 break;
388             sep = strchr(param, ' ');
389             if (sep)
390                 *sep = '\0';
391             if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
392                 // Invalid AMF parameter.
393                 ff_rtmp_packet_destroy(&pkt);
394                 return ret;
395             }
396 
397             if (sep)
398                 param = sep + 1;
399             else
400                 break;
401         }
402     }
403 
404     pkt.size = p - pkt.data;
405 
406     return rtmp_send_packet(rt, &pkt, 1);
407 }
408 
409 
410 #define RTMP_CTRL_ABORT_MESSAGE  (2)
411 
read_connect(URLContext *s, RTMPContext *rt)412 static int read_connect(URLContext *s, RTMPContext *rt)
413 {
414     RTMPPacket pkt = { 0 };
415     uint8_t *p;
416     const uint8_t *cp;
417     int ret;
418     char command[64];
419     int stringlen;
420     double seqnum;
421     uint8_t tmpstr[256];
422     GetByteContext gbc;
423 
424     // handle RTMP Protocol Control Messages
425     for (;;) {
426         if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
427                                        &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
428             return ret;
429 #ifdef DEBUG
430         ff_rtmp_packet_dump(s, &pkt);
431 #endif
432         if (pkt.type == RTMP_PT_CHUNK_SIZE) {
433             if ((ret = handle_chunk_size(s, &pkt)) < 0) {
434                 ff_rtmp_packet_destroy(&pkt);
435                 return ret;
436             }
437         } else if (pkt.type == RTMP_CTRL_ABORT_MESSAGE) {
438             av_log(s, AV_LOG_ERROR, "received abort message\n");
439             ff_rtmp_packet_destroy(&pkt);
440             return AVERROR_UNKNOWN;
441         } else if (pkt.type == RTMP_PT_BYTES_READ) {
442             av_log(s, AV_LOG_TRACE, "received acknowledgement\n");
443         } else if (pkt.type == RTMP_PT_WINDOW_ACK_SIZE) {
444             if ((ret = handle_window_ack_size(s, &pkt)) < 0) {
445                 ff_rtmp_packet_destroy(&pkt);
446                 return ret;
447             }
448         } else if (pkt.type == RTMP_PT_SET_PEER_BW) {
449             if ((ret = handle_set_peer_bw(s, &pkt)) < 0) {
450                 ff_rtmp_packet_destroy(&pkt);
451                 return ret;
452             }
453         } else if (pkt.type == RTMP_PT_INVOKE) {
454             // received RTMP Command Message
455             break;
456         } else {
457             av_log(s, AV_LOG_ERROR, "Unknown control message type (%d)\n", pkt.type);
458         }
459         ff_rtmp_packet_destroy(&pkt);
460     }
461 
462     cp = pkt.data;
463     bytestream2_init(&gbc, cp, pkt.size);
464     if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
465         av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
466         ff_rtmp_packet_destroy(&pkt);
467         return AVERROR_INVALIDDATA;
468     }
469     if (strcmp(command, "connect")) {
470         av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
471         ff_rtmp_packet_destroy(&pkt);
472         return AVERROR_INVALIDDATA;
473     }
474     ret = ff_amf_read_number(&gbc, &seqnum);
475     if (ret)
476         av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
477     /* Here one could parse an AMF Object with data as flashVers and others. */
478     ret = ff_amf_get_field_value(gbc.buffer,
479                                  gbc.buffer + bytestream2_get_bytes_left(&gbc),
480                                  "app", tmpstr, sizeof(tmpstr));
481     if (ret)
482         av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
483     if (!ret && strcmp(tmpstr, rt->app))
484         av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
485                tmpstr, rt->app);
486     ff_rtmp_packet_destroy(&pkt);
487 
488     // Send Window Acknowledgement Size (as defined in specification)
489     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
490                                      RTMP_PT_WINDOW_ACK_SIZE, 0, 4)) < 0)
491         return ret;
492     p = pkt.data;
493     // Inform the peer about how often we want acknowledgements about what
494     // we send. (We don't check for the acknowledgements currently.)
495     bytestream_put_be32(&p, rt->max_sent_unacked);
496     pkt.size = p - pkt.data;
497     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
498                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
499     ff_rtmp_packet_destroy(&pkt);
500     if (ret < 0)
501         return ret;
502     // Set Peer Bandwidth
503     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
504                                      RTMP_PT_SET_PEER_BW, 0, 5)) < 0)
505         return ret;
506     p = pkt.data;
507     // Tell the peer to only send this many bytes unless it gets acknowledgements.
508     // This could be any arbitrary value we want here.
509     bytestream_put_be32(&p, rt->max_sent_unacked);
510     bytestream_put_byte(&p, 2); // dynamic
511     pkt.size = p - pkt.data;
512     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
513                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
514     ff_rtmp_packet_destroy(&pkt);
515     if (ret < 0)
516         return ret;
517 
518     // User control
519     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
520                                      RTMP_PT_USER_CONTROL, 0, 6)) < 0)
521         return ret;
522 
523     p = pkt.data;
524     bytestream_put_be16(&p, 0); // 0 -> Stream Begin
525     bytestream_put_be32(&p, 0); // Stream 0
526     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
527                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
528     ff_rtmp_packet_destroy(&pkt);
529     if (ret < 0)
530         return ret;
531 
532     // Chunk size
533     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
534                                      RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
535         return ret;
536 
537     p = pkt.data;
538     bytestream_put_be32(&p, rt->out_chunk_size);
539     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
540                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
541     ff_rtmp_packet_destroy(&pkt);
542     if (ret < 0)
543         return ret;
544 
545     // Send _result NetConnection.Connect.Success to connect
546     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
547                                      RTMP_PT_INVOKE, 0,
548                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
549         return ret;
550 
551     p = pkt.data;
552     ff_amf_write_string(&p, "_result");
553     ff_amf_write_number(&p, seqnum);
554 
555     ff_amf_write_object_start(&p);
556     ff_amf_write_field_name(&p, "fmsVer");
557     ff_amf_write_string(&p, "FMS/3,0,1,123");
558     ff_amf_write_field_name(&p, "capabilities");
559     ff_amf_write_number(&p, 31);
560     ff_amf_write_object_end(&p);
561 
562     ff_amf_write_object_start(&p);
563     ff_amf_write_field_name(&p, "level");
564     ff_amf_write_string(&p, "status");
565     ff_amf_write_field_name(&p, "code");
566     ff_amf_write_string(&p, "NetConnection.Connect.Success");
567     ff_amf_write_field_name(&p, "description");
568     ff_amf_write_string(&p, "Connection succeeded.");
569     ff_amf_write_field_name(&p, "objectEncoding");
570     ff_amf_write_number(&p, 0);
571     ff_amf_write_object_end(&p);
572 
573     pkt.size = p - pkt.data;
574     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
575                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
576     ff_rtmp_packet_destroy(&pkt);
577     if (ret < 0)
578         return ret;
579 
580     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
581                                      RTMP_PT_INVOKE, 0, 30)) < 0)
582         return ret;
583     p = pkt.data;
584     ff_amf_write_string(&p, "onBWDone");
585     ff_amf_write_number(&p, 0);
586     ff_amf_write_null(&p);
587     ff_amf_write_number(&p, 8192);
588     pkt.size = p - pkt.data;
589     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
590                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
591     ff_rtmp_packet_destroy(&pkt);
592 
593     return ret;
594 }
595 
596 /**
597  * Generate 'releaseStream' call and send it to the server. It should make
598  * the server release some channel for media streams.
599  */
gen_release_stream(URLContext *s, RTMPContext *rt)600 static int gen_release_stream(URLContext *s, RTMPContext *rt)
601 {
602     RTMPPacket pkt;
603     uint8_t *p;
604     int ret;
605 
606     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
607                                      0, 29 + strlen(rt->playpath))) < 0)
608         return ret;
609 
610     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
611     p = pkt.data;
612     ff_amf_write_string(&p, "releaseStream");
613     ff_amf_write_number(&p, ++rt->nb_invokes);
614     ff_amf_write_null(&p);
615     ff_amf_write_string(&p, rt->playpath);
616 
617     return rtmp_send_packet(rt, &pkt, 1);
618 }
619 
620 /**
621  * Generate 'FCPublish' call and send it to the server. It should make
622  * the server prepare for receiving media streams.
623  */
gen_fcpublish_stream(URLContext *s, RTMPContext *rt)624 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
625 {
626     RTMPPacket pkt;
627     uint8_t *p;
628     int ret;
629 
630     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
631                                      0, 25 + strlen(rt->playpath))) < 0)
632         return ret;
633 
634     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
635     p = pkt.data;
636     ff_amf_write_string(&p, "FCPublish");
637     ff_amf_write_number(&p, ++rt->nb_invokes);
638     ff_amf_write_null(&p);
639     ff_amf_write_string(&p, rt->playpath);
640 
641     return rtmp_send_packet(rt, &pkt, 1);
642 }
643 
644 /**
645  * Generate 'FCUnpublish' call and send it to the server. It should make
646  * the server destroy stream.
647  */
gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)648 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
649 {
650     RTMPPacket pkt;
651     uint8_t *p;
652     int ret;
653 
654     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
655                                      0, 27 + strlen(rt->playpath))) < 0)
656         return ret;
657 
658     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
659     p = pkt.data;
660     ff_amf_write_string(&p, "FCUnpublish");
661     ff_amf_write_number(&p, ++rt->nb_invokes);
662     ff_amf_write_null(&p);
663     ff_amf_write_string(&p, rt->playpath);
664 
665     return rtmp_send_packet(rt, &pkt, 0);
666 }
667 
668 /**
669  * Generate 'createStream' call and send it to the server. It should make
670  * the server allocate some channel for media streams.
671  */
gen_create_stream(URLContext *s, RTMPContext *rt)672 static int gen_create_stream(URLContext *s, RTMPContext *rt)
673 {
674     RTMPPacket pkt;
675     uint8_t *p;
676     int ret;
677 
678     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
679 
680     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
681                                      0, 25)) < 0)
682         return ret;
683 
684     p = pkt.data;
685     ff_amf_write_string(&p, "createStream");
686     ff_amf_write_number(&p, ++rt->nb_invokes);
687     ff_amf_write_null(&p);
688 
689     return rtmp_send_packet(rt, &pkt, 1);
690 }
691 
692 
693 /**
694  * Generate 'deleteStream' call and send it to the server. It should make
695  * the server remove some channel for media streams.
696  */
gen_delete_stream(URLContext *s, RTMPContext *rt)697 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
698 {
699     RTMPPacket pkt;
700     uint8_t *p;
701     int ret;
702 
703     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
704 
705     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
706                                      0, 34)) < 0)
707         return ret;
708 
709     p = pkt.data;
710     ff_amf_write_string(&p, "deleteStream");
711     ff_amf_write_number(&p, ++rt->nb_invokes);
712     ff_amf_write_null(&p);
713     ff_amf_write_number(&p, rt->stream_id);
714 
715     return rtmp_send_packet(rt, &pkt, 0);
716 }
717 
718 /**
719  * Generate 'getStreamLength' call and send it to the server. If the server
720  * knows the duration of the selected stream, it will reply with the duration
721  * in seconds.
722  */
gen_get_stream_length(URLContext *s, RTMPContext *rt)723 static int gen_get_stream_length(URLContext *s, RTMPContext *rt)
724 {
725     RTMPPacket pkt;
726     uint8_t *p;
727     int ret;
728 
729     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
730                                      0, 31 + strlen(rt->playpath))) < 0)
731         return ret;
732 
733     p = pkt.data;
734     ff_amf_write_string(&p, "getStreamLength");
735     ff_amf_write_number(&p, ++rt->nb_invokes);
736     ff_amf_write_null(&p);
737     ff_amf_write_string(&p, rt->playpath);
738 
739     return rtmp_send_packet(rt, &pkt, 1);
740 }
741 
742 /**
743  * Generate client buffer time and send it to the server.
744  */
gen_buffer_time(URLContext *s, RTMPContext *rt)745 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
746 {
747     RTMPPacket pkt;
748     uint8_t *p;
749     int ret;
750 
751     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_USER_CONTROL,
752                                      1, 10)) < 0)
753         return ret;
754 
755     p = pkt.data;
756     bytestream_put_be16(&p, 3); // SetBuffer Length
757     bytestream_put_be32(&p, rt->stream_id);
758     bytestream_put_be32(&p, rt->client_buffer_time);
759 
760     return rtmp_send_packet(rt, &pkt, 0);
761 }
762 
763 /**
764  * Generate 'play' call and send it to the server, then ping the server
765  * to start actual playing.
766  */
gen_play(URLContext *s, RTMPContext *rt)767 static int gen_play(URLContext *s, RTMPContext *rt)
768 {
769     RTMPPacket pkt;
770     uint8_t *p;
771     int ret;
772 
773     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
774 
775     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
776                                      0, 29 + strlen(rt->playpath))) < 0)
777         return ret;
778 
779     pkt.extra = rt->stream_id;
780 
781     p = pkt.data;
782     ff_amf_write_string(&p, "play");
783     ff_amf_write_number(&p, ++rt->nb_invokes);
784     ff_amf_write_null(&p);
785     ff_amf_write_string(&p, rt->playpath);
786     ff_amf_write_number(&p, rt->live * 1000);
787 
788     return rtmp_send_packet(rt, &pkt, 1);
789 }
790 
gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)791 static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
792 {
793     RTMPPacket pkt;
794     uint8_t *p;
795     int ret;
796 
797     av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
798            timestamp);
799 
800     if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
801         return ret;
802 
803     pkt.extra = rt->stream_id;
804 
805     p = pkt.data;
806     ff_amf_write_string(&p, "seek");
807     ff_amf_write_number(&p, 0); //no tracking back responses
808     ff_amf_write_null(&p); //as usual, the first null param
809     ff_amf_write_number(&p, timestamp); //where we want to jump
810 
811     return rtmp_send_packet(rt, &pkt, 1);
812 }
813 
814 /**
815  * Generate a pause packet that either pauses or unpauses the current stream.
816  */
gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)817 static int gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)
818 {
819     RTMPPacket pkt;
820     uint8_t *p;
821     int ret;
822 
823     av_log(s, AV_LOG_DEBUG, "Sending pause command for timestamp %d\n",
824            timestamp);
825 
826     if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 29)) < 0)
827         return ret;
828 
829     pkt.extra = rt->stream_id;
830 
831     p = pkt.data;
832     ff_amf_write_string(&p, "pause");
833     ff_amf_write_number(&p, 0); //no tracking back responses
834     ff_amf_write_null(&p); //as usual, the first null param
835     ff_amf_write_bool(&p, pause); // pause or unpause
836     ff_amf_write_number(&p, timestamp); //where we pause the stream
837 
838     return rtmp_send_packet(rt, &pkt, 1);
839 }
840 
841 /**
842  * Generate 'publish' call and send it to the server.
843  */
gen_publish(URLContext *s, RTMPContext *rt)844 static int gen_publish(URLContext *s, RTMPContext *rt)
845 {
846     RTMPPacket pkt;
847     uint8_t *p;
848     int ret;
849 
850     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
851 
852     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
853                                      0, 30 + strlen(rt->playpath))) < 0)
854         return ret;
855 
856     pkt.extra = rt->stream_id;
857 
858     p = pkt.data;
859     ff_amf_write_string(&p, "publish");
860     ff_amf_write_number(&p, ++rt->nb_invokes);
861     ff_amf_write_null(&p);
862     ff_amf_write_string(&p, rt->playpath);
863     ff_amf_write_string(&p, "live");
864 
865     return rtmp_send_packet(rt, &pkt, 1);
866 }
867 
868 /**
869  * Generate ping reply and send it to the server.
870  */
gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)871 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
872 {
873     RTMPPacket pkt;
874     uint8_t *p;
875     int ret;
876 
877     if (ppkt->size < 6) {
878         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
879                ppkt->size);
880         return AVERROR_INVALIDDATA;
881     }
882 
883     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,RTMP_PT_USER_CONTROL,
884                                      ppkt->timestamp + 1, 6)) < 0)
885         return ret;
886 
887     p = pkt.data;
888     bytestream_put_be16(&p, 7); // PingResponse
889     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
890 
891     return rtmp_send_packet(rt, &pkt, 0);
892 }
893 
894 /**
895  * Generate SWF verification message and send it to the server.
896  */
gen_swf_verification(URLContext *s, RTMPContext *rt)897 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
898 {
899     RTMPPacket pkt;
900     uint8_t *p;
901     int ret;
902 
903     av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
904     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_USER_CONTROL,
905                                      0, 44)) < 0)
906         return ret;
907 
908     p = pkt.data;
909     bytestream_put_be16(&p, 27);
910     memcpy(p, rt->swfverification, 42);
911 
912     return rtmp_send_packet(rt, &pkt, 0);
913 }
914 
915 /**
916  * Generate window acknowledgement size message and send it to the server.
917  */
gen_window_ack_size(URLContext *s, RTMPContext *rt)918 static int gen_window_ack_size(URLContext *s, RTMPContext *rt)
919 {
920     RTMPPacket pkt;
921     uint8_t *p;
922     int ret;
923 
924     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_WINDOW_ACK_SIZE,
925                                      0, 4)) < 0)
926         return ret;
927 
928     p = pkt.data;
929     bytestream_put_be32(&p, rt->max_sent_unacked);
930 
931     return rtmp_send_packet(rt, &pkt, 0);
932 }
933 
934 /**
935  * Generate check bandwidth message and send it to the server.
936  */
gen_check_bw(URLContext *s, RTMPContext *rt)937 static int gen_check_bw(URLContext *s, RTMPContext *rt)
938 {
939     RTMPPacket pkt;
940     uint8_t *p;
941     int ret;
942 
943     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
944                                      0, 21)) < 0)
945         return ret;
946 
947     p = pkt.data;
948     ff_amf_write_string(&p, "_checkbw");
949     ff_amf_write_number(&p, ++rt->nb_invokes);
950     ff_amf_write_null(&p);
951 
952     return rtmp_send_packet(rt, &pkt, 1);
953 }
954 
955 /**
956  * Generate report on bytes read so far and send it to the server.
957  */
gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)958 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
959 {
960     RTMPPacket pkt;
961     uint8_t *p;
962     int ret;
963 
964     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
965                                      ts, 4)) < 0)
966         return ret;
967 
968     p = pkt.data;
969     bytestream_put_be32(&p, rt->bytes_read);
970 
971     return rtmp_send_packet(rt, &pkt, 0);
972 }
973 
gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt, const char *subscribe)974 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
975                                   const char *subscribe)
976 {
977     RTMPPacket pkt;
978     uint8_t *p;
979     int ret;
980 
981     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
982                                      0, 27 + strlen(subscribe))) < 0)
983         return ret;
984 
985     p = pkt.data;
986     ff_amf_write_string(&p, "FCSubscribe");
987     ff_amf_write_number(&p, ++rt->nb_invokes);
988     ff_amf_write_null(&p);
989     ff_amf_write_string(&p, subscribe);
990 
991     return rtmp_send_packet(rt, &pkt, 1);
992 }
993 
994 /**
995  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
996  * will be stored) into that packet.
997  *
998  * @param buf handshake data (1536 bytes)
999  * @param encrypted use an encrypted connection (RTMPE)
1000  * @return offset to the digest inside input data
1001  */
rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)1002 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
1003 {
1004     int ret, digest_pos;
1005 
1006     if (encrypted)
1007         digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
1008     else
1009         digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
1010 
1011     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1012                               rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
1013                               buf + digest_pos);
1014     if (ret < 0)
1015         return ret;
1016 
1017     return digest_pos;
1018 }
1019 
1020 /**
1021  * Verify that the received server response has the expected digest value.
1022  *
1023  * @param buf handshake data received from the server (1536 bytes)
1024  * @param off position to search digest offset from
1025  * @return 0 if digest is valid, digest position otherwise
1026  */
rtmp_validate_digest(uint8_t *buf, int off)1027 static int rtmp_validate_digest(uint8_t *buf, int off)
1028 {
1029     uint8_t digest[32];
1030     int ret, digest_pos;
1031 
1032     digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
1033 
1034     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1035                               rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
1036                               digest);
1037     if (ret < 0)
1038         return ret;
1039 
1040     if (!memcmp(digest, buf + digest_pos, 32))
1041         return digest_pos;
1042     return 0;
1043 }
1044 
rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt, uint8_t *buf)1045 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
1046                                       uint8_t *buf)
1047 {
1048     uint8_t *p;
1049     int ret;
1050 
1051     if (rt->swfhash_len != 32) {
1052         av_log(s, AV_LOG_ERROR,
1053                "Hash of the decompressed SWF file is not 32 bytes long.\n");
1054         return AVERROR(EINVAL);
1055     }
1056 
1057     p = &rt->swfverification[0];
1058     bytestream_put_byte(&p, 1);
1059     bytestream_put_byte(&p, 1);
1060     bytestream_put_be32(&p, rt->swfsize);
1061     bytestream_put_be32(&p, rt->swfsize);
1062 
1063     if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1064         return ret;
1065 
1066     return 0;
1067 }
1068 
1069 #if CONFIG_ZLIB
rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size, uint8_t **out_data, int64_t *out_size)1070 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
1071                                      uint8_t **out_data, int64_t *out_size)
1072 {
1073     z_stream zs = { 0 };
1074     void *ptr;
1075     int size;
1076     int ret = 0;
1077 
1078     zs.avail_in = in_size;
1079     zs.next_in  = in_data;
1080     ret = inflateInit(&zs);
1081     if (ret != Z_OK)
1082         return AVERROR_UNKNOWN;
1083 
1084     do {
1085         uint8_t tmp_buf[16384];
1086 
1087         zs.avail_out = sizeof(tmp_buf);
1088         zs.next_out  = tmp_buf;
1089 
1090         ret = inflate(&zs, Z_NO_FLUSH);
1091         if (ret != Z_OK && ret != Z_STREAM_END) {
1092             ret = AVERROR_UNKNOWN;
1093             goto fail;
1094         }
1095 
1096         size = sizeof(tmp_buf) - zs.avail_out;
1097         if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1098             ret = AVERROR(ENOMEM);
1099             goto fail;
1100         }
1101         *out_data = ptr;
1102 
1103         memcpy(*out_data + *out_size, tmp_buf, size);
1104         *out_size += size;
1105     } while (zs.avail_out == 0);
1106 
1107 fail:
1108     inflateEnd(&zs);
1109     return ret;
1110 }
1111 #endif
1112 
rtmp_calc_swfhash(URLContext *s)1113 static int rtmp_calc_swfhash(URLContext *s)
1114 {
1115     RTMPContext *rt = s->priv_data;
1116     uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1117     int64_t in_size;
1118     URLContext *stream = NULL;
1119     char swfhash[32];
1120     int swfsize;
1121     int ret = 0;
1122 
1123     /* Get the SWF player file. */
1124     if ((ret = ffurl_open_whitelist(&stream, rt->swfverify, AVIO_FLAG_READ,
1125                                     &s->interrupt_callback, NULL,
1126                                     s->protocol_whitelist, s->protocol_blacklist, s)) < 0) {
1127         av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1128         goto fail;
1129     }
1130 
1131     if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1132         ret = AVERROR(EIO);
1133         goto fail;
1134     }
1135 
1136     if (!(in_data = av_malloc(in_size))) {
1137         ret = AVERROR(ENOMEM);
1138         goto fail;
1139     }
1140 
1141     if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1142         goto fail;
1143 
1144     if (in_size < 3) {
1145         ret = AVERROR_INVALIDDATA;
1146         goto fail;
1147     }
1148 
1149     if (!memcmp(in_data, "CWS", 3)) {
1150 #if CONFIG_ZLIB
1151         int64_t out_size;
1152         /* Decompress the SWF player file using Zlib. */
1153         if (!(out_data = av_malloc(8))) {
1154             ret = AVERROR(ENOMEM);
1155             goto fail;
1156         }
1157         *in_data = 'F'; // magic stuff
1158         memcpy(out_data, in_data, 8);
1159         out_size = 8;
1160 
1161         if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1162                                              &out_data, &out_size)) < 0)
1163             goto fail;
1164         swfsize = out_size;
1165         swfdata = out_data;
1166 #else
1167         av_log(s, AV_LOG_ERROR,
1168                "Zlib is required for decompressing the SWF player file.\n");
1169         ret = AVERROR(EINVAL);
1170         goto fail;
1171 #endif
1172     } else {
1173         swfsize = in_size;
1174         swfdata = in_data;
1175     }
1176 
1177     /* Compute the SHA256 hash of the SWF player file. */
1178     if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1179                                    "Genuine Adobe Flash Player 001", 30,
1180                                    swfhash)) < 0)
1181         goto fail;
1182 
1183     /* Set SWFVerification parameters. */
1184     av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1185     rt->swfsize = swfsize;
1186 
1187 fail:
1188     av_freep(&in_data);
1189     av_freep(&out_data);
1190     ffurl_close(stream);
1191     return ret;
1192 }
1193 
1194 /**
1195  * Perform handshake with the server by means of exchanging pseudorandom data
1196  * signed with HMAC-SHA2 digest.
1197  *
1198  * @return 0 if handshake succeeds, negative value otherwise
1199  */
rtmp_handshake(URLContext *s, RTMPContext *rt)1200 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1201 {
1202     AVLFG rnd;
1203     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1204         3,                // unencrypted data
1205         0, 0, 0, 0,       // client uptime
1206         RTMP_CLIENT_VER1,
1207         RTMP_CLIENT_VER2,
1208         RTMP_CLIENT_VER3,
1209         RTMP_CLIENT_VER4,
1210     };
1211     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1212     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1213     int i;
1214     int server_pos, client_pos;
1215     uint8_t digest[32], signature[32];
1216     int ret, type = 0;
1217 
1218     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1219 
1220     av_lfg_init(&rnd, 0xDEADC0DE);
1221     // generate handshake packet - 1536 bytes of pseudorandom data
1222     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1223         tosend[i] = av_lfg_get(&rnd) >> 24;
1224 
1225     if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1226         /* When the client wants to use RTMPE, we have to change the command
1227          * byte to 0x06 which means to use encrypted data and we have to set
1228          * the flash version to at least 9.0.115.0. */
1229         tosend[0] = 6;
1230         tosend[5] = 128;
1231         tosend[6] = 0;
1232         tosend[7] = 3;
1233         tosend[8] = 2;
1234 
1235         /* Initialize the Diffie-Hellmann context and generate the public key
1236          * to send to the server. */
1237         if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1238             return ret;
1239     }
1240 
1241     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1242     if (client_pos < 0)
1243         return client_pos;
1244 
1245     if ((ret = ffurl_write(rt->stream, tosend,
1246                            RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1247         av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1248         return ret;
1249     }
1250 
1251     if ((ret = ffurl_read_complete(rt->stream, serverdata,
1252                                    RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1253         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1254         return ret;
1255     }
1256 
1257     if ((ret = ffurl_read_complete(rt->stream, clientdata,
1258                                    RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1259         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1260         return ret;
1261     }
1262 
1263     av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1264     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1265            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1266 
1267     if (rt->is_input && serverdata[5] >= 3) {
1268         server_pos = rtmp_validate_digest(serverdata + 1, 772);
1269         if (server_pos < 0)
1270             return server_pos;
1271 
1272         if (!server_pos) {
1273             type = 1;
1274             server_pos = rtmp_validate_digest(serverdata + 1, 8);
1275             if (server_pos < 0)
1276                 return server_pos;
1277 
1278             if (!server_pos) {
1279                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1280                 return AVERROR(EIO);
1281             }
1282         }
1283 
1284         /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1285          * key are the last 32 bytes of the server handshake. */
1286         if (rt->swfsize) {
1287             if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1288                                                   RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1289                 return ret;
1290         }
1291 
1292         ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1293                                   rtmp_server_key, sizeof(rtmp_server_key),
1294                                   digest);
1295         if (ret < 0)
1296             return ret;
1297 
1298         ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1299                                   0, digest, 32, signature);
1300         if (ret < 0)
1301             return ret;
1302 
1303         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1304             /* Compute the shared secret key sent by the server and initialize
1305              * the RC4 encryption. */
1306             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1307                                                    tosend + 1, type)) < 0)
1308                 return ret;
1309 
1310             /* Encrypt the signature received by the server. */
1311             ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1312         }
1313 
1314         if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1315             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1316             return AVERROR(EIO);
1317         }
1318 
1319         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1320             tosend[i] = av_lfg_get(&rnd) >> 24;
1321         ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1322                                   rtmp_player_key, sizeof(rtmp_player_key),
1323                                   digest);
1324         if (ret < 0)
1325             return ret;
1326 
1327         ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1328                                   digest, 32,
1329                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1330         if (ret < 0)
1331             return ret;
1332 
1333         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1334             /* Encrypt the signature to be send to the server. */
1335             ff_rtmpe_encrypt_sig(rt->stream, tosend +
1336                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1337                                  serverdata[0]);
1338         }
1339 
1340         // write reply back to the server
1341         if ((ret = ffurl_write(rt->stream, tosend,
1342                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1343             return ret;
1344 
1345         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1346             /* Set RC4 keys for encryption and update the keystreams. */
1347             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1348                 return ret;
1349         }
1350     } else {
1351         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1352             /* Compute the shared secret key sent by the server and initialize
1353              * the RC4 encryption. */
1354             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1355                             tosend + 1, 1)) < 0)
1356                 return ret;
1357 
1358             if (serverdata[0] == 9) {
1359                 /* Encrypt the signature received by the server. */
1360                 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1361                                      serverdata[0]);
1362             }
1363         }
1364 
1365         if ((ret = ffurl_write(rt->stream, serverdata + 1,
1366                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1367             return ret;
1368 
1369         if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1370             /* Set RC4 keys for encryption and update the keystreams. */
1371             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1372                 return ret;
1373         }
1374     }
1375 
1376     return 0;
1377 }
1378 
rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int, uint32_t *second_int, char *arraydata, int size)1379 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1380                                   uint32_t *second_int, char *arraydata,
1381                                   int size)
1382 {
1383     int inoutsize;
1384 
1385     inoutsize = ffurl_read_complete(rt->stream, arraydata,
1386                                     RTMP_HANDSHAKE_PACKET_SIZE);
1387     if (inoutsize <= 0)
1388         return AVERROR(EIO);
1389     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1390         av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1391                " not following standard\n", (int)inoutsize);
1392         return AVERROR(EINVAL);
1393     }
1394 
1395     *first_int  = AV_RB32(arraydata);
1396     *second_int = AV_RB32(arraydata + 4);
1397     return 0;
1398 }
1399 
rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int, uint32_t second_int, char *arraydata, int size)1400 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1401                                uint32_t second_int, char *arraydata, int size)
1402 {
1403     int inoutsize;
1404 
1405     AV_WB32(arraydata, first_int);
1406     AV_WB32(arraydata + 4, second_int);
1407     inoutsize = ffurl_write(rt->stream, arraydata,
1408                             RTMP_HANDSHAKE_PACKET_SIZE);
1409     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1410         av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1411         return AVERROR(EIO);
1412     }
1413 
1414     return 0;
1415 }
1416 
1417 /**
1418  * rtmp handshake server side
1419  */
rtmp_server_handshake(URLContext *s, RTMPContext *rt)1420 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1421 {
1422     uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1423     uint32_t hs_epoch;
1424     uint32_t hs_my_epoch;
1425     uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1426     uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1427     uint32_t zeroes;
1428     uint32_t temp       = 0;
1429     int randomidx       = 0;
1430     int inoutsize       = 0;
1431     int ret;
1432 
1433     inoutsize = ffurl_read_complete(rt->stream, buffer, 1);       // Receive C0
1434     if (inoutsize <= 0) {
1435         av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1436         return AVERROR(EIO);
1437     }
1438     // Check Version
1439     if (buffer[0] != 3) {
1440         av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1441         return AVERROR(EIO);
1442     }
1443     if (ffurl_write(rt->stream, buffer, 1) <= 0) {                 // Send S0
1444         av_log(s, AV_LOG_ERROR,
1445                "Unable to write answer - RTMP S0\n");
1446         return AVERROR(EIO);
1447     }
1448     /* Receive C1 */
1449     ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1450                                  RTMP_HANDSHAKE_PACKET_SIZE);
1451     if (ret) {
1452         av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1453         return ret;
1454     }
1455     /* Send S1 */
1456     /* By now same epoch will be sent */
1457     hs_my_epoch = hs_epoch;
1458     /* Generate random */
1459     for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1460          randomidx += 4)
1461         AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1462 
1463     ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1464                               RTMP_HANDSHAKE_PACKET_SIZE);
1465     if (ret) {
1466         av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1467         return ret;
1468     }
1469     /* Send S2 */
1470     ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1471                               RTMP_HANDSHAKE_PACKET_SIZE);
1472     if (ret) {
1473         av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1474         return ret;
1475     }
1476     /* Receive C2 */
1477     ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1478                                  RTMP_HANDSHAKE_PACKET_SIZE);
1479     if (ret) {
1480         av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1481         return ret;
1482     }
1483     if (temp != hs_my_epoch)
1484         av_log(s, AV_LOG_WARNING,
1485                "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1486     if (memcmp(buffer + 8, hs_s1 + 8,
1487                RTMP_HANDSHAKE_PACKET_SIZE - 8))
1488         av_log(s, AV_LOG_WARNING,
1489                "Erroneous C2 Message random does not match up\n");
1490 
1491     return 0;
1492 }
1493 
handle_chunk_size(URLContext *s, RTMPPacket *pkt)1494 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1495 {
1496     RTMPContext *rt = s->priv_data;
1497     int ret;
1498 
1499     if (pkt->size < 4) {
1500         av_log(s, AV_LOG_ERROR,
1501                "Too short chunk size change packet (%d)\n",
1502                pkt->size);
1503         return AVERROR_INVALIDDATA;
1504     }
1505 
1506     if (!rt->is_input) {
1507         /* Send the same chunk size change packet back to the server,
1508          * setting the outgoing chunk size to the same as the incoming one. */
1509         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1510                                         &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
1511             return ret;
1512         rt->out_chunk_size = AV_RB32(pkt->data);
1513     }
1514 
1515     rt->in_chunk_size = AV_RB32(pkt->data);
1516     if (rt->in_chunk_size <= 0) {
1517         av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1518                rt->in_chunk_size);
1519         return AVERROR_INVALIDDATA;
1520     }
1521     av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1522            rt->in_chunk_size);
1523 
1524     return 0;
1525 }
1526 
handle_user_control(URLContext *s, RTMPPacket *pkt)1527 static int handle_user_control(URLContext *s, RTMPPacket *pkt)
1528 {
1529     RTMPContext *rt = s->priv_data;
1530     int t, ret;
1531 
1532     if (pkt->size < 2) {
1533         av_log(s, AV_LOG_ERROR, "Too short user control packet (%d)\n",
1534                pkt->size);
1535         return AVERROR_INVALIDDATA;
1536     }
1537 
1538     t = AV_RB16(pkt->data);
1539     if (t == 6) { // PingRequest
1540         if ((ret = gen_pong(s, rt, pkt)) < 0)
1541             return ret;
1542     } else if (t == 26) {
1543         if (rt->swfsize) {
1544             if ((ret = gen_swf_verification(s, rt)) < 0)
1545                 return ret;
1546         } else {
1547             av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1548         }
1549     }
1550 
1551     return 0;
1552 }
1553 
handle_set_peer_bw(URLContext *s, RTMPPacket *pkt)1554 static int handle_set_peer_bw(URLContext *s, RTMPPacket *pkt)
1555 {
1556     RTMPContext *rt = s->priv_data;
1557 
1558     if (pkt->size < 4) {
1559         av_log(s, AV_LOG_ERROR,
1560                "Peer bandwidth packet is less than 4 bytes long (%d)\n",
1561                pkt->size);
1562         return AVERROR_INVALIDDATA;
1563     }
1564 
1565     // We currently don't check how much the peer has acknowledged of
1566     // what we have sent. To do that properly, we should call
1567     // gen_window_ack_size here, to tell the peer that we want an
1568     // acknowledgement with (at least) that interval.
1569     rt->max_sent_unacked = AV_RB32(pkt->data);
1570     if (rt->max_sent_unacked <= 0) {
1571         av_log(s, AV_LOG_ERROR, "Incorrect set peer bandwidth %d\n",
1572                rt->max_sent_unacked);
1573         return AVERROR_INVALIDDATA;
1574 
1575     }
1576     av_log(s, AV_LOG_DEBUG, "Max sent, unacked = %d\n", rt->max_sent_unacked);
1577 
1578     return 0;
1579 }
1580 
handle_window_ack_size(URLContext *s, RTMPPacket *pkt)1581 static int handle_window_ack_size(URLContext *s, RTMPPacket *pkt)
1582 {
1583     RTMPContext *rt = s->priv_data;
1584 
1585     if (pkt->size < 4) {
1586         av_log(s, AV_LOG_ERROR,
1587                "Too short window acknowledgement size packet (%d)\n",
1588                pkt->size);
1589         return AVERROR_INVALIDDATA;
1590     }
1591 
1592     rt->receive_report_size = AV_RB32(pkt->data);
1593     if (rt->receive_report_size <= 0) {
1594         av_log(s, AV_LOG_ERROR, "Incorrect window acknowledgement size %d\n",
1595                rt->receive_report_size);
1596         return AVERROR_INVALIDDATA;
1597     }
1598     av_log(s, AV_LOG_DEBUG, "Window acknowledgement size = %d\n", rt->receive_report_size);
1599     // Send an Acknowledgement packet after receiving half the maximum
1600     // size, to make sure the peer can keep on sending without waiting
1601     // for acknowledgements.
1602     rt->receive_report_size >>= 1;
1603 
1604     return 0;
1605 }
1606 
do_adobe_auth(RTMPContext *rt, const char *user, const char *salt, const char *opaque, const char *challenge)1607 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1608                          const char *opaque, const char *challenge)
1609 {
1610     uint8_t hash[16];
1611     char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1612     struct AVMD5 *md5 = av_md5_alloc();
1613     if (!md5)
1614         return AVERROR(ENOMEM);
1615 
1616     snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1617 
1618     av_md5_init(md5);
1619     av_md5_update(md5, user, strlen(user));
1620     av_md5_update(md5, salt, strlen(salt));
1621     av_md5_update(md5, rt->password, strlen(rt->password));
1622     av_md5_final(md5, hash);
1623     av_base64_encode(hashstr, sizeof(hashstr), hash,
1624                      sizeof(hash));
1625     av_md5_init(md5);
1626     av_md5_update(md5, hashstr, strlen(hashstr));
1627     if (opaque)
1628         av_md5_update(md5, opaque, strlen(opaque));
1629     else if (challenge)
1630         av_md5_update(md5, challenge, strlen(challenge));
1631     av_md5_update(md5, challenge2, strlen(challenge2));
1632     av_md5_final(md5, hash);
1633     av_base64_encode(hashstr, sizeof(hashstr), hash,
1634                      sizeof(hash));
1635     snprintf(rt->auth_params, sizeof(rt->auth_params),
1636              "?authmod=%s&user=%s&challenge=%s&response=%s",
1637              "adobe", user, challenge2, hashstr);
1638     if (opaque)
1639         av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1640                     "&opaque=%s", opaque);
1641 
1642     av_free(md5);
1643     return 0;
1644 }
1645 
do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)1646 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1647 {
1648     uint8_t hash[16];
1649     char hashstr1[33], hashstr2[33];
1650     const char *realm = "live";
1651     const char *method = "publish";
1652     const char *qop = "auth";
1653     const char *nc = "00000001";
1654     char cnonce[10];
1655     struct AVMD5 *md5 = av_md5_alloc();
1656     if (!md5)
1657         return AVERROR(ENOMEM);
1658 
1659     snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1660 
1661     av_md5_init(md5);
1662     av_md5_update(md5, user, strlen(user));
1663     av_md5_update(md5, ":", 1);
1664     av_md5_update(md5, realm, strlen(realm));
1665     av_md5_update(md5, ":", 1);
1666     av_md5_update(md5, rt->password, strlen(rt->password));
1667     av_md5_final(md5, hash);
1668     ff_data_to_hex(hashstr1, hash, 16, 1);
1669 
1670     av_md5_init(md5);
1671     av_md5_update(md5, method, strlen(method));
1672     av_md5_update(md5, ":/", 2);
1673     av_md5_update(md5, rt->app, strlen(rt->app));
1674     if (!strchr(rt->app, '/'))
1675         av_md5_update(md5, "/_definst_", strlen("/_definst_"));
1676     av_md5_final(md5, hash);
1677     ff_data_to_hex(hashstr2, hash, 16, 1);
1678 
1679     av_md5_init(md5);
1680     av_md5_update(md5, hashstr1, strlen(hashstr1));
1681     av_md5_update(md5, ":", 1);
1682     if (nonce)
1683         av_md5_update(md5, nonce, strlen(nonce));
1684     av_md5_update(md5, ":", 1);
1685     av_md5_update(md5, nc, strlen(nc));
1686     av_md5_update(md5, ":", 1);
1687     av_md5_update(md5, cnonce, strlen(cnonce));
1688     av_md5_update(md5, ":", 1);
1689     av_md5_update(md5, qop, strlen(qop));
1690     av_md5_update(md5, ":", 1);
1691     av_md5_update(md5, hashstr2, strlen(hashstr2));
1692     av_md5_final(md5, hash);
1693     ff_data_to_hex(hashstr1, hash, 16, 1);
1694 
1695     snprintf(rt->auth_params, sizeof(rt->auth_params),
1696              "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1697              "llnw", user, nonce, cnonce, nc, hashstr1);
1698 
1699     av_free(md5);
1700     return 0;
1701 }
1702 
handle_connect_error(URLContext *s, const char *desc)1703 static int handle_connect_error(URLContext *s, const char *desc)
1704 {
1705     RTMPContext *rt = s->priv_data;
1706     char buf[300], *ptr, authmod[15];
1707     int i = 0, ret = 0;
1708     const char *user = "", *salt = "", *opaque = NULL,
1709                *challenge = NULL, *cptr = NULL, *nonce = NULL;
1710 
1711     if (!(cptr = strstr(desc, "authmod=adobe")) &&
1712         !(cptr = strstr(desc, "authmod=llnw"))) {
1713         av_log(s, AV_LOG_ERROR,
1714                "Unknown connect error (unsupported authentication method?)\n");
1715         return AVERROR_UNKNOWN;
1716     }
1717     cptr += strlen("authmod=");
1718     while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1719         authmod[i++] = *cptr++;
1720     authmod[i] = '\0';
1721 
1722     if (!rt->username[0] || !rt->password[0]) {
1723         av_log(s, AV_LOG_ERROR, "No credentials set\n");
1724         return AVERROR_UNKNOWN;
1725     }
1726 
1727     if (strstr(desc, "?reason=authfailed")) {
1728         av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1729         return AVERROR_UNKNOWN;
1730     } else if (strstr(desc, "?reason=nosuchuser")) {
1731         av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1732         return AVERROR_UNKNOWN;
1733     }
1734 
1735     if (rt->auth_tried) {
1736         av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1737         return AVERROR_UNKNOWN;
1738     }
1739 
1740     rt->auth_params[0] = '\0';
1741 
1742     if (strstr(desc, "code=403 need auth")) {
1743         snprintf(rt->auth_params, sizeof(rt->auth_params),
1744                  "?authmod=%s&user=%s", authmod, rt->username);
1745         return 0;
1746     }
1747 
1748     if (!(cptr = strstr(desc, "?reason=needauth"))) {
1749         av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1750         return AVERROR_UNKNOWN;
1751     }
1752 
1753     av_strlcpy(buf, cptr + 1, sizeof(buf));
1754     ptr = buf;
1755 
1756     while (ptr) {
1757         char *next  = strchr(ptr, '&');
1758         char *value = strchr(ptr, '=');
1759         if (next)
1760             *next++ = '\0';
1761         if (value) {
1762             *value++ = '\0';
1763             if (!strcmp(ptr, "user")) {
1764                 user = value;
1765             } else if (!strcmp(ptr, "salt")) {
1766                 salt = value;
1767             } else if (!strcmp(ptr, "opaque")) {
1768                 opaque = value;
1769             } else if (!strcmp(ptr, "challenge")) {
1770                 challenge = value;
1771             } else if (!strcmp(ptr, "nonce")) {
1772                 nonce = value;
1773             } else {
1774                 av_log(s, AV_LOG_INFO, "Ignoring unsupported var %s\n", ptr);
1775             }
1776         } else {
1777             av_log(s, AV_LOG_WARNING, "Variable %s has NULL value\n", ptr);
1778         }
1779         ptr = next;
1780     }
1781 
1782     if (!strcmp(authmod, "adobe")) {
1783         if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1784             return ret;
1785     } else {
1786         if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1787             return ret;
1788     }
1789 
1790     rt->auth_tried = 1;
1791     return 0;
1792 }
1793 
handle_invoke_error(URLContext *s, RTMPPacket *pkt)1794 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1795 {
1796     RTMPContext *rt = s->priv_data;
1797     const uint8_t *data_end = pkt->data + pkt->size;
1798     char *tracked_method = NULL;
1799     int level = AV_LOG_ERROR;
1800     uint8_t tmpstr[256];
1801     int ret;
1802 
1803     if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1804         return ret;
1805 
1806     if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1807                                 "description", tmpstr, sizeof(tmpstr))) {
1808         if (tracked_method && (!strcmp(tracked_method, "_checkbw")      ||
1809                                !strcmp(tracked_method, "releaseStream") ||
1810                                !strcmp(tracked_method, "FCSubscribe")   ||
1811                                !strcmp(tracked_method, "FCPublish"))) {
1812             /* Gracefully ignore Adobe-specific historical artifact errors. */
1813             level = AV_LOG_WARNING;
1814             ret = 0;
1815         } else if (tracked_method && !strcmp(tracked_method, "getStreamLength")) {
1816             level = rt->live ? AV_LOG_DEBUG : AV_LOG_WARNING;
1817             ret = 0;
1818         } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1819             ret = handle_connect_error(s, tmpstr);
1820             if (!ret) {
1821                 rt->do_reconnect = 1;
1822                 level = AV_LOG_VERBOSE;
1823             }
1824         } else
1825             ret = AVERROR_UNKNOWN;
1826         av_log(s, level, "Server error: %s\n", tmpstr);
1827     }
1828 
1829     av_free(tracked_method);
1830     return ret;
1831 }
1832 
write_begin(URLContext *s)1833 static int write_begin(URLContext *s)
1834 {
1835     RTMPContext *rt = s->priv_data;
1836     PutByteContext pbc;
1837     RTMPPacket spkt = { 0 };
1838     int ret;
1839 
1840     // Send Stream Begin 1
1841     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1842                                      RTMP_PT_USER_CONTROL, 0, 6)) < 0) {
1843         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1844         return ret;
1845     }
1846 
1847     bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1848     bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
1849     bytestream2_put_be32(&pbc, rt->nb_streamid);
1850 
1851     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1852                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1853 
1854     ff_rtmp_packet_destroy(&spkt);
1855 
1856     return ret;
1857 }
1858 
write_status(URLContext *s, RTMPPacket *pkt, const char *status, const char *description, const char *details)1859 static int write_status(URLContext *s, RTMPPacket *pkt,
1860                         const char *status, const char *description, const char *details)
1861 {
1862     RTMPContext *rt = s->priv_data;
1863     RTMPPacket spkt = { 0 };
1864     uint8_t *pp;
1865     int ret;
1866 
1867     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1868                                      RTMP_PT_INVOKE, 0,
1869                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1870         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1871         return ret;
1872     }
1873 
1874     pp = spkt.data;
1875     spkt.extra = pkt->extra;
1876     ff_amf_write_string(&pp, "onStatus");
1877     ff_amf_write_number(&pp, 0);
1878     ff_amf_write_null(&pp);
1879 
1880     ff_amf_write_object_start(&pp);
1881     ff_amf_write_field_name(&pp, "level");
1882     ff_amf_write_string(&pp, "status");
1883     ff_amf_write_field_name(&pp, "code");
1884     ff_amf_write_string(&pp, status);
1885     ff_amf_write_field_name(&pp, "description");
1886     ff_amf_write_string(&pp, description);
1887     if (details) {
1888         ff_amf_write_field_name(&pp, "details");
1889         ff_amf_write_string(&pp, details);
1890     }
1891     ff_amf_write_object_end(&pp);
1892 
1893     spkt.size = pp - spkt.data;
1894     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1895                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1896     ff_rtmp_packet_destroy(&spkt);
1897 
1898     return ret;
1899 }
1900 
send_invoke_response(URLContext *s, RTMPPacket *pkt)1901 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1902 {
1903     RTMPContext *rt = s->priv_data;
1904     double seqnum;
1905     char filename[128];
1906     char command[64];
1907     int stringlen;
1908     char *pchar;
1909     const uint8_t *p = pkt->data;
1910     uint8_t *pp      = NULL;
1911     RTMPPacket spkt  = { 0 };
1912     GetByteContext gbc;
1913     int ret;
1914 
1915     bytestream2_init(&gbc, p, pkt->size);
1916     if (ff_amf_read_string(&gbc, command, sizeof(command),
1917                            &stringlen)) {
1918         av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1919         return AVERROR_INVALIDDATA;
1920     }
1921 
1922     ret = ff_amf_read_number(&gbc, &seqnum);
1923     if (ret)
1924         return ret;
1925     ret = ff_amf_read_null(&gbc);
1926     if (ret)
1927         return ret;
1928     if (!strcmp(command, "FCPublish") ||
1929         !strcmp(command, "publish")) {
1930         ret = ff_amf_read_string(&gbc, filename,
1931                                  sizeof(filename), &stringlen);
1932         if (ret) {
1933             if (ret == AVERROR(EINVAL))
1934                 av_log(s, AV_LOG_ERROR, "Unable to parse stream name - name too long?\n");
1935             else
1936                 av_log(s, AV_LOG_ERROR, "Unable to parse stream name\n");
1937             return ret;
1938         }
1939         // check with url
1940         if (s->filename) {
1941             pchar = strrchr(s->filename, '/');
1942             if (!pchar) {
1943                 av_log(s, AV_LOG_WARNING,
1944                        "Unable to find / in url %s, bad format\n",
1945                        s->filename);
1946                 pchar = s->filename;
1947             }
1948             pchar++;
1949             if (strcmp(pchar, filename))
1950                 av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1951                        " %s\n", filename, pchar);
1952         }
1953         rt->state = STATE_RECEIVING;
1954     }
1955 
1956     if (!strcmp(command, "FCPublish")) {
1957         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1958                                          RTMP_PT_INVOKE, 0,
1959                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1960             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1961             return ret;
1962         }
1963         pp = spkt.data;
1964         ff_amf_write_string(&pp, "onFCPublish");
1965     } else if (!strcmp(command, "publish")) {
1966         char statusmsg[128];
1967         snprintf(statusmsg, sizeof(statusmsg), "%s is now published", filename);
1968         ret = write_begin(s);
1969         if (ret < 0)
1970             return ret;
1971 
1972         // Send onStatus(NetStream.Publish.Start)
1973         return write_status(s, pkt, "NetStream.Publish.Start",
1974                             statusmsg, filename);
1975     } else if (!strcmp(command, "play")) {
1976         ret = write_begin(s);
1977         if (ret < 0)
1978             return ret;
1979         rt->state = STATE_SENDING;
1980         return write_status(s, pkt, "NetStream.Play.Start",
1981                             "playing stream", NULL);
1982     } else {
1983         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1984                                          RTMP_PT_INVOKE, 0,
1985                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1986             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1987             return ret;
1988         }
1989         pp = spkt.data;
1990         ff_amf_write_string(&pp, "_result");
1991         ff_amf_write_number(&pp, seqnum);
1992         ff_amf_write_null(&pp);
1993         if (!strcmp(command, "createStream")) {
1994             rt->nb_streamid++;
1995             if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1996                 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1997             ff_amf_write_number(&pp, rt->nb_streamid);
1998             /* By now we don't control which streams are removed in
1999              * deleteStream. There is no stream creation control
2000              * if a client creates more than 2^32 - 2 streams. */
2001         }
2002     }
2003     spkt.size = pp - spkt.data;
2004     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
2005                                &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
2006     ff_rtmp_packet_destroy(&spkt);
2007     return ret;
2008 }
2009 
2010 /**
2011  * Read the AMF_NUMBER response ("_result") to a function call
2012  * (e.g. createStream()). This response should be made up of the AMF_STRING
2013  * "result", a NULL object and then the response encoded as AMF_NUMBER. On a
2014  * successful response, we will return set the value to number (otherwise number
2015  * will not be changed).
2016  *
2017  * @return 0 if reading the value succeeds, negative value otherwise
2018  */
read_number_result(RTMPPacket *pkt, double *number)2019 static int read_number_result(RTMPPacket *pkt, double *number)
2020 {
2021     // We only need to fit "_result" in this.
2022     uint8_t strbuffer[8];
2023     int stringlen;
2024     double numbuffer;
2025     GetByteContext gbc;
2026 
2027     bytestream2_init(&gbc, pkt->data, pkt->size);
2028 
2029     // Value 1/4: "_result" as AMF_STRING
2030     if (ff_amf_read_string(&gbc, strbuffer, sizeof(strbuffer), &stringlen))
2031         return AVERROR_INVALIDDATA;
2032     if (strcmp(strbuffer, "_result"))
2033         return AVERROR_INVALIDDATA;
2034     // Value 2/4: The callee reference number
2035     if (ff_amf_read_number(&gbc, &numbuffer))
2036         return AVERROR_INVALIDDATA;
2037     // Value 3/4: Null
2038     if (ff_amf_read_null(&gbc))
2039         return AVERROR_INVALIDDATA;
2040     // Value 4/4: The response as AMF_NUMBER
2041     if (ff_amf_read_number(&gbc, &numbuffer))
2042         return AVERROR_INVALIDDATA;
2043     else
2044         *number = numbuffer;
2045 
2046     return 0;
2047 }
2048 
handle_invoke_result(URLContext *s, RTMPPacket *pkt)2049 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
2050 {
2051     RTMPContext *rt = s->priv_data;
2052     char *tracked_method = NULL;
2053     int ret = 0;
2054 
2055     if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
2056         return ret;
2057 
2058     if (!tracked_method) {
2059         /* Ignore this reply when the current method is not tracked. */
2060         return ret;
2061     }
2062 
2063     if (!strcmp(tracked_method, "connect")) {
2064         if (!rt->is_input) {
2065             if ((ret = gen_release_stream(s, rt)) < 0)
2066                 goto fail;
2067 
2068             if ((ret = gen_fcpublish_stream(s, rt)) < 0)
2069                 goto fail;
2070         } else {
2071             if ((ret = gen_window_ack_size(s, rt)) < 0)
2072                 goto fail;
2073         }
2074 
2075         if ((ret = gen_create_stream(s, rt)) < 0)
2076             goto fail;
2077 
2078         if (rt->is_input) {
2079             /* Send the FCSubscribe command when the name of live
2080              * stream is defined by the user or if it's a live stream. */
2081             if (rt->subscribe) {
2082                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
2083                     goto fail;
2084             } else if (rt->live == -1) {
2085                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
2086                     goto fail;
2087             }
2088         }
2089     } else if (!strcmp(tracked_method, "createStream")) {
2090         double stream_id;
2091         if (read_number_result(pkt, &stream_id)) {
2092             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
2093         } else {
2094             rt->stream_id = stream_id;
2095         }
2096 
2097         if (!rt->is_input) {
2098             if ((ret = gen_publish(s, rt)) < 0)
2099                 goto fail;
2100         } else {
2101             if (rt->live != -1) {
2102                 if ((ret = gen_get_stream_length(s, rt)) < 0)
2103                     goto fail;
2104             }
2105             if ((ret = gen_play(s, rt)) < 0)
2106                 goto fail;
2107             if ((ret = gen_buffer_time(s, rt)) < 0)
2108                 goto fail;
2109         }
2110     } else if (!strcmp(tracked_method, "getStreamLength")) {
2111         if (read_number_result(pkt, &rt->duration)) {
2112             av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()\n");
2113         }
2114     }
2115 
2116 fail:
2117     av_free(tracked_method);
2118     return ret;
2119 }
2120 
handle_invoke_status(URLContext *s, RTMPPacket *pkt)2121 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
2122 {
2123     RTMPContext *rt = s->priv_data;
2124     const uint8_t *data_end = pkt->data + pkt->size;
2125     const uint8_t *ptr = pkt->data + RTMP_HEADER;
2126     uint8_t tmpstr[256];
2127     int i, t;
2128 
2129     for (i = 0; i < 2; i++) {
2130         t = ff_amf_tag_size(ptr, data_end);
2131         if (t < 0)
2132             return 1;
2133         ptr += t;
2134     }
2135 
2136     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2137     if (!t && !strcmp(tmpstr, "error")) {
2138         t = ff_amf_get_field_value(ptr, data_end,
2139                                    "description", tmpstr, sizeof(tmpstr));
2140         if (t || !tmpstr[0])
2141             t = ff_amf_get_field_value(ptr, data_end, "code",
2142                                        tmpstr, sizeof(tmpstr));
2143         if (!t)
2144             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2145         return -1;
2146     }
2147 
2148     t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2149     if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2150     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2151     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2152     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2153     if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2154 
2155     return 0;
2156 }
2157 
handle_invoke(URLContext *s, RTMPPacket *pkt)2158 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
2159 {
2160     RTMPContext *rt = s->priv_data;
2161     int ret = 0;
2162 
2163     //TODO: check for the messages sent for wrong state?
2164     if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2165         if ((ret = handle_invoke_error(s, pkt)) < 0)
2166             return ret;
2167     } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2168         if ((ret = handle_invoke_result(s, pkt)) < 0)
2169             return ret;
2170     } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2171         if ((ret = handle_invoke_status(s, pkt)) < 0)
2172             return ret;
2173     } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2174         if ((ret = gen_check_bw(s, rt)) < 0)
2175             return ret;
2176     } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2177                ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
2178                ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
2179                ff_amf_match_string(pkt->data, pkt->size, "play")          ||
2180                ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
2181                ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2182         if ((ret = send_invoke_response(s, pkt)) < 0)
2183             return ret;
2184     }
2185 
2186     return ret;
2187 }
2188 
update_offset(RTMPContext *rt, int size)2189 static int update_offset(RTMPContext *rt, int size)
2190 {
2191     int old_flv_size;
2192 
2193     // generate packet header and put data into buffer for FLV demuxer
2194     if (rt->flv_off < rt->flv_size) {
2195         // There is old unread data in the buffer, thus append at the end
2196         old_flv_size  = rt->flv_size;
2197         rt->flv_size += size;
2198     } else {
2199         // All data has been read, write the new data at the start of the buffer
2200         old_flv_size = 0;
2201         rt->flv_size = size;
2202         rt->flv_off  = 0;
2203     }
2204 
2205     return old_flv_size;
2206 }
2207 
append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)2208 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2209 {
2210     int old_flv_size, ret;
2211     PutByteContext pbc;
2212     const uint8_t *data = pkt->data + skip;
2213     const int size      = pkt->size - skip;
2214     uint32_t ts         = pkt->timestamp;
2215 
2216     if (pkt->type == RTMP_PT_AUDIO) {
2217         rt->has_audio = 1;
2218     } else if (pkt->type == RTMP_PT_VIDEO) {
2219         rt->has_video = 1;
2220     }
2221 
2222     old_flv_size = update_offset(rt, size + 15);
2223 
2224     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2225         rt->flv_size = rt->flv_off = 0;
2226         return ret;
2227     }
2228     bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2229     bytestream2_skip_p(&pbc, old_flv_size);
2230     bytestream2_put_byte(&pbc, pkt->type);
2231     bytestream2_put_be24(&pbc, size);
2232     bytestream2_put_be24(&pbc, ts);
2233     bytestream2_put_byte(&pbc, ts >> 24);
2234     bytestream2_put_be24(&pbc, 0);
2235     bytestream2_put_buffer(&pbc, data, size);
2236     bytestream2_put_be32(&pbc, size + RTMP_HEADER);
2237 
2238     return 0;
2239 }
2240 
handle_notify(URLContext *s, RTMPPacket *pkt)2241 static int handle_notify(URLContext *s, RTMPPacket *pkt)
2242 {
2243     RTMPContext *rt  = s->priv_data;
2244     uint8_t commandbuffer[64];
2245     char statusmsg[128];
2246     int stringlen, ret, skip = 0;
2247     GetByteContext gbc;
2248 
2249     bytestream2_init(&gbc, pkt->data, pkt->size);
2250     if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2251                            &stringlen))
2252         return AVERROR_INVALIDDATA;
2253 
2254     if (!strcmp(commandbuffer, "onMetaData")) {
2255         // metadata properties should be stored in a mixed array
2256         if (bytestream2_get_byte(&gbc) == AMF_DATA_TYPE_MIXEDARRAY) {
2257             // We have found a metaData Array so flv can determine the streams
2258             // from this.
2259             rt->received_metadata = 1;
2260             // skip 32-bit max array index
2261             bytestream2_skip(&gbc, 4);
2262             while (bytestream2_get_bytes_left(&gbc) > 3) {
2263                 if (ff_amf_get_string(&gbc, statusmsg, sizeof(statusmsg),
2264                                       &stringlen))
2265                     return AVERROR_INVALIDDATA;
2266                 // We do not care about the content of the property (yet).
2267                 stringlen = ff_amf_tag_size(gbc.buffer, gbc.buffer_end);
2268                 if (stringlen < 0)
2269                     return AVERROR_INVALIDDATA;
2270                 bytestream2_skip(&gbc, stringlen);
2271 
2272                 // The presence of the following properties indicates that the
2273                 // respective streams are present.
2274                 if (!strcmp(statusmsg, "videocodecid")) {
2275                     rt->has_video = 1;
2276                 }
2277                 if (!strcmp(statusmsg, "audiocodecid")) {
2278                     rt->has_audio = 1;
2279                 }
2280             }
2281             if (bytestream2_get_be24(&gbc) != AMF_END_OF_OBJECT)
2282                 return AVERROR_INVALIDDATA;
2283         }
2284     }
2285 
2286     // Skip the @setDataFrame string and validate it is a notification
2287     if (!strcmp(commandbuffer, "@setDataFrame")) {
2288         skip = gbc.buffer - pkt->data;
2289         ret = ff_amf_read_string(&gbc, statusmsg,
2290                                  sizeof(statusmsg), &stringlen);
2291         if (ret < 0)
2292             return AVERROR_INVALIDDATA;
2293     }
2294 
2295     return append_flv_data(rt, pkt, skip);
2296 }
2297 
2298 /**
2299  * Parse received packet and possibly perform some action depending on
2300  * the packet contents.
2301  * @return 0 for no errors, negative values for serious errors which prevent
2302  *         further communications, positive values for uncritical errors
2303  */
rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)2304 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2305 {
2306     int ret;
2307 
2308 #ifdef DEBUG
2309     ff_rtmp_packet_dump(s, pkt);
2310 #endif
2311 
2312     switch (pkt->type) {
2313     case RTMP_PT_BYTES_READ:
2314         av_log(s, AV_LOG_TRACE, "received bytes read report\n");
2315         break;
2316     case RTMP_PT_CHUNK_SIZE:
2317         if ((ret = handle_chunk_size(s, pkt)) < 0)
2318             return ret;
2319         break;
2320     case RTMP_PT_USER_CONTROL:
2321         if ((ret = handle_user_control(s, pkt)) < 0)
2322             return ret;
2323         break;
2324     case RTMP_PT_SET_PEER_BW:
2325         if ((ret = handle_set_peer_bw(s, pkt)) < 0)
2326             return ret;
2327         break;
2328     case RTMP_PT_WINDOW_ACK_SIZE:
2329         if ((ret = handle_window_ack_size(s, pkt)) < 0)
2330             return ret;
2331         break;
2332     case RTMP_PT_INVOKE:
2333         if ((ret = handle_invoke(s, pkt)) < 0)
2334             return ret;
2335         break;
2336     case RTMP_PT_VIDEO:
2337     case RTMP_PT_AUDIO:
2338     case RTMP_PT_METADATA:
2339     case RTMP_PT_NOTIFY:
2340         /* Audio, Video and Metadata packets are parsed in get_packet() */
2341         break;
2342     default:
2343         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2344         break;
2345     }
2346     return 0;
2347 }
2348 
handle_metadata(RTMPContext *rt, RTMPPacket *pkt)2349 static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
2350 {
2351     int ret, old_flv_size, type;
2352     const uint8_t *next;
2353     uint8_t *p;
2354     uint32_t size;
2355     uint32_t ts, cts, pts = 0;
2356 
2357     old_flv_size = update_offset(rt, pkt->size);
2358 
2359     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2360         rt->flv_size = rt->flv_off = 0;
2361         return ret;
2362     }
2363 
2364     next = pkt->data;
2365     p    = rt->flv_data + old_flv_size;
2366 
2367     /* copy data while rewriting timestamps */
2368     ts = pkt->timestamp;
2369 
2370     while (next - pkt->data < pkt->size - RTMP_HEADER) {
2371         type = bytestream_get_byte(&next);
2372         size = bytestream_get_be24(&next);
2373         cts  = bytestream_get_be24(&next);
2374         cts |= bytestream_get_byte(&next) << 24;
2375         if (!pts)
2376             pts = cts;
2377         ts += cts - pts;
2378         pts = cts;
2379         if (size + 3 + 4 > pkt->data + pkt->size - next)
2380             break;
2381         bytestream_put_byte(&p, type);
2382         bytestream_put_be24(&p, size);
2383         bytestream_put_be24(&p, ts);
2384         bytestream_put_byte(&p, ts >> 24);
2385         memcpy(p, next, size + 3 + 4);
2386         p    += size + 3;
2387         bytestream_put_be32(&p, size + RTMP_HEADER);
2388         next += size + 3 + 4;
2389     }
2390     if (p != rt->flv_data + rt->flv_size) {
2391         av_log(rt, AV_LOG_WARNING, "Incomplete flv packets in "
2392                                      "RTMP_PT_METADATA packet\n");
2393         rt->flv_size = p - rt->flv_data;
2394     }
2395 
2396     return 0;
2397 }
2398 
2399 /**
2400  * Interact with the server by receiving and sending RTMP packets until
2401  * there is some significant data (media data or expected status notification).
2402  *
2403  * @param s          reading context
2404  * @param for_header non-zero value tells function to work until it
2405  * gets notification from the server that playing has been started,
2406  * otherwise function will work until some media data is received (or
2407  * an error happens)
2408  * @return 0 for successful operation, negative value in case of error
2409  */
get_packet(URLContext *s, int for_header)2410 static int get_packet(URLContext *s, int for_header)
2411 {
2412     RTMPContext *rt = s->priv_data;
2413     int ret;
2414 
2415     if (rt->state == STATE_STOPPED)
2416         return AVERROR_EOF;
2417 
2418     for (;;) {
2419         RTMPPacket rpkt = { 0 };
2420         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2421                                        rt->in_chunk_size, &rt->prev_pkt[0],
2422                                        &rt->nb_prev_pkt[0])) <= 0) {
2423             if (ret == 0) {
2424                 return AVERROR(EAGAIN);
2425             } else {
2426                 return AVERROR(EIO);
2427             }
2428         }
2429 
2430         // Track timestamp for later use
2431         rt->last_timestamp = rpkt.timestamp;
2432 
2433         rt->bytes_read += ret;
2434         if (rt->bytes_read - rt->last_bytes_read > rt->receive_report_size) {
2435             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2436             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0) {
2437                 ff_rtmp_packet_destroy(&rpkt);
2438                 return ret;
2439             }
2440             rt->last_bytes_read = rt->bytes_read;
2441         }
2442 
2443         ret = rtmp_parse_result(s, rt, &rpkt);
2444 
2445         // At this point we must check if we are in the seek state and continue
2446         // with the next packet. handle_invoke will get us out of this state
2447         // when the right message is encountered
2448         if (rt->state == STATE_SEEKING) {
2449             ff_rtmp_packet_destroy(&rpkt);
2450             // We continue, let the natural flow of things happen:
2451             // AVERROR(EAGAIN) or handle_invoke gets us out of here
2452             continue;
2453         }
2454 
2455         if (ret < 0) {//serious error in current packet
2456             ff_rtmp_packet_destroy(&rpkt);
2457             return ret;
2458         }
2459         if (rt->do_reconnect && for_header) {
2460             ff_rtmp_packet_destroy(&rpkt);
2461             return 0;
2462         }
2463         if (rt->state == STATE_STOPPED) {
2464             ff_rtmp_packet_destroy(&rpkt);
2465             return AVERROR_EOF;
2466         }
2467         if (for_header && (rt->state == STATE_PLAYING    ||
2468                            rt->state == STATE_PUBLISHING ||
2469                            rt->state == STATE_SENDING    ||
2470                            rt->state == STATE_RECEIVING)) {
2471             ff_rtmp_packet_destroy(&rpkt);
2472             return 0;
2473         }
2474         if (!rpkt.size || !rt->is_input) {
2475             ff_rtmp_packet_destroy(&rpkt);
2476             continue;
2477         }
2478         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2479             ret = append_flv_data(rt, &rpkt, 0);
2480             ff_rtmp_packet_destroy(&rpkt);
2481             return ret;
2482         } else if (rpkt.type == RTMP_PT_NOTIFY) {
2483             ret = handle_notify(s, &rpkt);
2484             ff_rtmp_packet_destroy(&rpkt);
2485             return ret;
2486         } else if (rpkt.type == RTMP_PT_METADATA) {
2487             ret = handle_metadata(rt, &rpkt);
2488             ff_rtmp_packet_destroy(&rpkt);
2489             return ret;
2490         }
2491         ff_rtmp_packet_destroy(&rpkt);
2492     }
2493 }
2494 
rtmp_close(URLContext *h)2495 static int rtmp_close(URLContext *h)
2496 {
2497     RTMPContext *rt = h->priv_data;
2498     int ret = 0, i, j;
2499 
2500     if (!rt->is_input) {
2501         rt->flv_data = NULL;
2502         if (rt->out_pkt.size)
2503             ff_rtmp_packet_destroy(&rt->out_pkt);
2504         if (rt->state > STATE_FCPUBLISH)
2505             ret = gen_fcunpublish_stream(h, rt);
2506     }
2507     if (rt->state > STATE_HANDSHAKED)
2508         ret = gen_delete_stream(h, rt);
2509     for (i = 0; i < 2; i++) {
2510         for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2511             ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2512         av_freep(&rt->prev_pkt[i]);
2513     }
2514 
2515     free_tracked_methods(rt);
2516     av_freep(&rt->flv_data);
2517     ffurl_closep(&rt->stream);
2518     return ret;
2519 }
2520 
2521 /**
2522  * Insert a fake onMetadata packet into the FLV stream to notify the FLV
2523  * demuxer about the duration of the stream.
2524  *
2525  * This should only be done if there was no real onMetadata packet sent by the
2526  * server at the start of the stream and if we were able to retrieve a valid
2527  * duration via a getStreamLength call.
2528  *
2529  * @return 0 for successful operation, negative value in case of error
2530  */
inject_fake_duration_metadata(RTMPContext *rt)2531 static int inject_fake_duration_metadata(RTMPContext *rt)
2532 {
2533     // We need to insert the metadata packet directly after the FLV
2534     // header, i.e. we need to move all other already read data by the
2535     // size of our fake metadata packet.
2536 
2537     uint8_t* p;
2538     // Keep old flv_data pointer
2539     uint8_t* old_flv_data = rt->flv_data;
2540     // Allocate a new flv_data pointer with enough space for the additional package
2541     if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
2542         rt->flv_data = old_flv_data;
2543         return AVERROR(ENOMEM);
2544     }
2545 
2546     // Copy FLV header
2547     memcpy(rt->flv_data, old_flv_data, 13);
2548     // Copy remaining packets
2549     memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
2550     // Increase the size by the injected packet
2551     rt->flv_size += 55;
2552     // Delete the old FLV data
2553     av_freep(&old_flv_data);
2554 
2555     p = rt->flv_data + 13;
2556     bytestream_put_byte(&p, FLV_TAG_TYPE_META);
2557     bytestream_put_be24(&p, 40); // size of data part (sum of all parts below)
2558     bytestream_put_be24(&p, 0);  // timestamp
2559     bytestream_put_be32(&p, 0);  // reserved
2560 
2561     // first event name as a string
2562     bytestream_put_byte(&p, AMF_DATA_TYPE_STRING);
2563     // "onMetaData" as AMF string
2564     bytestream_put_be16(&p, 10);
2565     bytestream_put_buffer(&p, "onMetaData", 10);
2566 
2567     // mixed array (hash) with size and string/type/data tuples
2568     bytestream_put_byte(&p, AMF_DATA_TYPE_MIXEDARRAY);
2569     bytestream_put_be32(&p, 1); // metadata_count
2570 
2571     // "duration" as AMF string
2572     bytestream_put_be16(&p, 8);
2573     bytestream_put_buffer(&p, "duration", 8);
2574     bytestream_put_byte(&p, AMF_DATA_TYPE_NUMBER);
2575     bytestream_put_be64(&p, av_double2int(rt->duration));
2576 
2577     // Finalise object
2578     bytestream_put_be16(&p, 0); // Empty string
2579     bytestream_put_byte(&p, AMF_END_OF_OBJECT);
2580     bytestream_put_be32(&p, 40 + RTMP_HEADER); // size of data part (sum of all parts above)
2581 
2582     return 0;
2583 }
2584 
2585 /**
2586  * Open RTMP connection and verify that the stream can be played.
2587  *
2588  * URL syntax: rtmp://server[:port][/app][/playpath]
2589  *             where 'app' is first one or two directories in the path
2590  *             (e.g. /ondemand/, /flash/live/, etc.)
2591  *             and 'playpath' is a file name (the rest of the path,
2592  *             may be prefixed with "mp4:")
2593  */
rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)2594 static int rtmp_open(URLContext *s, const char *uri, int flags, AVDictionary **opts)
2595 {
2596     RTMPContext *rt = s->priv_data;
2597     char proto[8], hostname[256], path[1024], auth[100], *fname;
2598     char *old_app, *qmark, *n, fname_buffer[1024];
2599     uint8_t buf[2048];
2600     int port;
2601     int ret;
2602 
2603     if (rt->listen_timeout > 0)
2604         rt->listen = 1;
2605 
2606     rt->is_input = !(flags & AVIO_FLAG_WRITE);
2607 
2608     av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2609                  hostname, sizeof(hostname), &port,
2610                  path, sizeof(path), s->filename);
2611 
2612     n = strchr(path, ' ');
2613     if (n) {
2614         av_log(s, AV_LOG_WARNING,
2615                "Detected librtmp style URL parameters, these aren't supported "
2616                "by the libavformat internal RTMP handler currently enabled. "
2617                "See the documentation for the correct way to pass parameters.\n");
2618         *n = '\0'; // Trim not supported part
2619     }
2620 
2621     if (auth[0]) {
2622         char *ptr = strchr(auth, ':');
2623         if (ptr) {
2624             *ptr = '\0';
2625             av_strlcpy(rt->username, auth, sizeof(rt->username));
2626             av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2627         }
2628     }
2629 
2630     if (rt->listen && strcmp(proto, "rtmp")) {
2631         av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2632                proto);
2633         return AVERROR(EINVAL);
2634     }
2635     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2636         if (!strcmp(proto, "rtmpts"))
2637             av_dict_set(opts, "ffrtmphttp_tls", "1", 1);
2638 
2639         /* open the http tunneling connection */
2640         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2641     } else if (!strcmp(proto, "rtmps")) {
2642         /* open the tls connection */
2643         if (port < 0)
2644             port = RTMPS_DEFAULT_PORT;
2645         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2646     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2647         if (!strcmp(proto, "rtmpte"))
2648             av_dict_set(opts, "ffrtmpcrypt_tunneling", "1", 1);
2649 
2650         /* open the encrypted connection */
2651         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2652         rt->encrypted = 1;
2653     } else {
2654         /* open the tcp connection */
2655         if (port < 0)
2656             port = RTMP_DEFAULT_PORT;
2657         if (rt->listen)
2658             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2659                         "?listen&listen_timeout=%d&tcp_nodelay=%d",
2660                         rt->listen_timeout * 1000, rt->tcp_nodelay);
2661         else
2662             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, "?tcp_nodelay=%d", rt->tcp_nodelay);
2663     }
2664 
2665 reconnect:
2666     if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2667                                     &s->interrupt_callback, opts,
2668                                     s->protocol_whitelist, s->protocol_blacklist, s)) < 0) {
2669         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2670         goto fail;
2671     }
2672 
2673     if (rt->swfverify) {
2674         if ((ret = rtmp_calc_swfhash(s)) < 0)
2675             goto fail;
2676     }
2677 
2678     rt->state = STATE_START;
2679     if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2680         goto fail;
2681     if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2682         goto fail;
2683 
2684     rt->out_chunk_size = 128;
2685     rt->in_chunk_size  = 128; // Probably overwritten later
2686     rt->state = STATE_HANDSHAKED;
2687 
2688     // Keep the application name when it has been defined by the user.
2689     old_app = rt->app;
2690 
2691     rt->app = av_malloc(APP_MAX_LENGTH);
2692     if (!rt->app) {
2693         ret = AVERROR(ENOMEM);
2694         goto fail;
2695     }
2696 
2697     //extract "app" part from path
2698     qmark = strchr(path, '?');
2699     if (qmark && strstr(qmark, "slist=")) {
2700         char* amp;
2701         // After slist we have the playpath, the full path is used as app
2702         av_strlcpy(rt->app, path + 1, APP_MAX_LENGTH);
2703         fname = strstr(path, "slist=") + 6;
2704         // Strip any further query parameters from fname
2705         amp = strchr(fname, '&');
2706         if (amp) {
2707             av_strlcpy(fname_buffer, fname, FFMIN(amp - fname + 1,
2708                                                   sizeof(fname_buffer)));
2709             fname = fname_buffer;
2710         }
2711     } else if (!strncmp(path, "/ondemand/", 10)) {
2712         fname = path + 10;
2713         memcpy(rt->app, "ondemand", 9);
2714     } else {
2715         char *next = *path ? path + 1 : path;
2716         char *p = strchr(next, '/');
2717         if (!p) {
2718             if (old_app) {
2719                 // If name of application has been defined by the user, assume that
2720                 // playpath is provided in the URL
2721                 fname = next;
2722             } else {
2723                 fname = NULL;
2724                 av_strlcpy(rt->app, next, APP_MAX_LENGTH);
2725             }
2726         } else {
2727             // make sure we do not mismatch a playpath for an application instance
2728             char *c = strchr(p + 1, ':');
2729             fname = strchr(p + 1, '/');
2730             if (!fname || (c && c < fname)) {
2731                 fname = p + 1;
2732                 av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2733             } else {
2734                 fname++;
2735                 av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2736             }
2737         }
2738     }
2739 
2740     if (old_app) {
2741         // The name of application has been defined by the user, override it.
2742         if (strlen(old_app) >= APP_MAX_LENGTH) {
2743             ret = AVERROR(EINVAL);
2744             goto fail;
2745         }
2746         av_free(rt->app);
2747         rt->app = old_app;
2748     }
2749 
2750     if (!rt->playpath) {
2751         int max_len = 1;
2752         if (fname)
2753             max_len = strlen(fname) + 5; // add prefix "mp4:"
2754         rt->playpath = av_malloc(max_len);
2755         if (!rt->playpath) {
2756             ret = AVERROR(ENOMEM);
2757             goto fail;
2758         }
2759 
2760         if (fname) {
2761             int len = strlen(fname);
2762             if (!strchr(fname, ':') && len >= 4 &&
2763                 (!strcmp(fname + len - 4, ".f4v") ||
2764                  !strcmp(fname + len - 4, ".mp4"))) {
2765                 memcpy(rt->playpath, "mp4:", 5);
2766             } else {
2767                 if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
2768                     fname[len - 4] = '\0';
2769                 rt->playpath[0] = 0;
2770             }
2771             av_strlcat(rt->playpath, fname, max_len);
2772         } else {
2773             rt->playpath[0] = '\0';
2774         }
2775     }
2776 
2777     if (!rt->tcurl) {
2778         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2779         if (!rt->tcurl) {
2780             ret = AVERROR(ENOMEM);
2781             goto fail;
2782         }
2783         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2784                     port, "/%s", rt->app);
2785     }
2786 
2787     if (!rt->flashver) {
2788         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2789         if (!rt->flashver) {
2790             ret = AVERROR(ENOMEM);
2791             goto fail;
2792         }
2793         if (rt->is_input) {
2794             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2795                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2796                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2797         } else {
2798             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2799                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2800         }
2801     }
2802 
2803     rt->receive_report_size = 1048576;
2804     rt->bytes_read = 0;
2805     rt->has_audio = 0;
2806     rt->has_video = 0;
2807     rt->received_metadata = 0;
2808     rt->last_bytes_read = 0;
2809     rt->max_sent_unacked = 2500000;
2810     rt->duration = 0;
2811 
2812     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2813            proto, path, rt->app, rt->playpath);
2814     if (!rt->listen) {
2815         if ((ret = gen_connect(s, rt)) < 0)
2816             goto fail;
2817     } else {
2818         if ((ret = read_connect(s, s->priv_data)) < 0)
2819             goto fail;
2820     }
2821 
2822     do {
2823         ret = get_packet(s, 1);
2824     } while (ret == AVERROR(EAGAIN));
2825     if (ret < 0)
2826         goto fail;
2827 
2828     if (rt->do_reconnect) {
2829         int i;
2830         ffurl_closep(&rt->stream);
2831         rt->do_reconnect = 0;
2832         rt->nb_invokes   = 0;
2833         for (i = 0; i < 2; i++)
2834             memset(rt->prev_pkt[i], 0,
2835                    sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2836         free_tracked_methods(rt);
2837         goto reconnect;
2838     }
2839 
2840     if (rt->is_input) {
2841         // generate FLV header for demuxer
2842         rt->flv_size = 13;
2843         if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2844             goto fail;
2845         rt->flv_off  = 0;
2846         memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
2847 
2848         // Read packets until we reach the first A/V packet or read metadata.
2849         // If there was a metadata package in front of the A/V packets, we can
2850         // build the FLV header from this. If we do not receive any metadata,
2851         // the FLV decoder will allocate the needed streams when their first
2852         // audio or video packet arrives.
2853         while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
2854             if ((ret = get_packet(s, 0)) < 0)
2855                goto fail;
2856         }
2857 
2858         // Either after we have read the metadata or (if there is none) the
2859         // first packet of an A/V stream, we have a better knowledge about the
2860         // streams, so set the FLV header accordingly.
2861         if (rt->has_audio) {
2862             rt->flv_data[4] |= FLV_HEADER_FLAG_HASAUDIO;
2863         }
2864         if (rt->has_video) {
2865             rt->flv_data[4] |= FLV_HEADER_FLAG_HASVIDEO;
2866         }
2867 
2868         // If we received the first packet of an A/V stream and no metadata but
2869         // the server returned a valid duration, create a fake metadata packet
2870         // to inform the FLV decoder about the duration.
2871         if (!rt->received_metadata && rt->duration > 0) {
2872             if ((ret = inject_fake_duration_metadata(rt)) < 0)
2873                 goto fail;
2874         }
2875     } else {
2876         rt->flv_size = 0;
2877         rt->flv_data = NULL;
2878         rt->flv_off  = 0;
2879         rt->skip_bytes = 13;
2880     }
2881 
2882     s->max_packet_size = rt->stream->max_packet_size;
2883     s->is_streamed     = 1;
2884     return 0;
2885 
2886 fail:
2887     av_freep(&rt->playpath);
2888     av_freep(&rt->tcurl);
2889     av_freep(&rt->flashver);
2890     av_dict_free(opts);
2891     rtmp_close(s);
2892     return ret;
2893 }
2894 
rtmp_read(URLContext *s, uint8_t *buf, int size)2895 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2896 {
2897     RTMPContext *rt = s->priv_data;
2898     int orig_size = size;
2899     int ret;
2900 
2901     while (size > 0) {
2902         int data_left = rt->flv_size - rt->flv_off;
2903 
2904         if (data_left >= size) {
2905             memcpy(buf, rt->flv_data + rt->flv_off, size);
2906             rt->flv_off += size;
2907             return orig_size;
2908         }
2909         if (data_left > 0) {
2910             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2911             buf  += data_left;
2912             size -= data_left;
2913             rt->flv_off = rt->flv_size;
2914             return data_left;
2915         }
2916         if ((ret = get_packet(s, 0)) < 0)
2917            return ret;
2918     }
2919     return orig_size;
2920 }
2921 
rtmp_seek(URLContext *s, int stream_index, int64_t timestamp, int flags)2922 static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2923                          int flags)
2924 {
2925     RTMPContext *rt = s->priv_data;
2926     int ret;
2927     av_log(s, AV_LOG_DEBUG,
2928            "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2929            stream_index, timestamp, flags);
2930     if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2931         av_log(s, AV_LOG_ERROR,
2932                "Unable to send seek command on stream index %d at timestamp "
2933                "%"PRId64" with flags %08x\n",
2934                stream_index, timestamp, flags);
2935         return ret;
2936     }
2937     rt->flv_off = rt->flv_size;
2938     rt->state = STATE_SEEKING;
2939     return timestamp;
2940 }
2941 
rtmp_pause(URLContext *s, int pause)2942 static int rtmp_pause(URLContext *s, int pause)
2943 {
2944     RTMPContext *rt = s->priv_data;
2945     int ret;
2946     av_log(s, AV_LOG_DEBUG, "Pause at timestamp %d\n",
2947            rt->last_timestamp);
2948     if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
2949         av_log(s, AV_LOG_ERROR, "Unable to send pause command at timestamp %d\n",
2950                rt->last_timestamp);
2951         return ret;
2952     }
2953     return 0;
2954 }
2955 
rtmp_write(URLContext *s, const uint8_t *buf, int size)2956 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2957 {
2958     RTMPContext *rt = s->priv_data;
2959     int size_temp = size;
2960     int pktsize, pkttype, copy;
2961     uint32_t ts;
2962     const uint8_t *buf_temp = buf;
2963     uint8_t c;
2964     int ret;
2965 
2966     do {
2967         if (rt->skip_bytes) {
2968             int skip = FFMIN(rt->skip_bytes, size_temp);
2969             buf_temp       += skip;
2970             size_temp      -= skip;
2971             rt->skip_bytes -= skip;
2972             continue;
2973         }
2974 
2975         if (rt->flv_header_bytes < RTMP_HEADER) {
2976             const uint8_t *header = rt->flv_header;
2977             int channel = RTMP_AUDIO_CHANNEL;
2978 
2979             copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2980             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2981             rt->flv_header_bytes += copy;
2982             size_temp            -= copy;
2983             if (rt->flv_header_bytes < RTMP_HEADER)
2984                 break;
2985 
2986             pkttype = bytestream_get_byte(&header);
2987             pktsize = bytestream_get_be24(&header);
2988             ts = bytestream_get_be24(&header);
2989             ts |= bytestream_get_byte(&header) << 24;
2990             bytestream_get_be24(&header);
2991             rt->flv_size = pktsize;
2992 
2993             if (pkttype == RTMP_PT_VIDEO)
2994                 channel = RTMP_VIDEO_CHANNEL;
2995 
2996             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2997                 pkttype == RTMP_PT_NOTIFY) {
2998                 if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
2999                                                      &rt->nb_prev_pkt[1],
3000                                                      channel)) < 0)
3001                     return ret;
3002                 // Force sending a full 12 bytes header by clearing the
3003                 // channel id, to make it not match a potential earlier
3004                 // packet in the same channel.
3005                 rt->prev_pkt[1][channel].channel_id = 0;
3006             }
3007 
3008             //this can be a big packet, it's better to send it right here
3009             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
3010                                              pkttype, ts, pktsize)) < 0)
3011                 return ret;
3012 
3013             rt->out_pkt.extra = rt->stream_id;
3014             rt->flv_data = rt->out_pkt.data;
3015         }
3016 
3017         copy = FFMIN(rt->flv_size - rt->flv_off, size_temp);
3018         bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, copy);
3019         rt->flv_off += copy;
3020         size_temp   -= copy;
3021 
3022         if (rt->flv_off == rt->flv_size) {
3023             rt->skip_bytes = 4;
3024 
3025             if (rt->out_pkt.type == RTMP_PT_NOTIFY) {
3026                 // For onMetaData and |RtmpSampleAccess packets, we want
3027                 // @setDataFrame prepended to the packet before it gets sent.
3028                 // However, not all RTMP_PT_NOTIFY packets (e.g., onTextData
3029                 // and onCuePoint).
3030                 uint8_t commandbuffer[64];
3031                 int stringlen = 0;
3032                 GetByteContext gbc;
3033 
3034                 bytestream2_init(&gbc, rt->flv_data, rt->flv_size);
3035                 if (!ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
3036                                         &stringlen)) {
3037                     if (!strcmp(commandbuffer, "onMetaData") ||
3038                         !strcmp(commandbuffer, "|RtmpSampleAccess")) {
3039                         uint8_t *ptr;
3040                         if ((ret = av_reallocp(&rt->out_pkt.data, rt->out_pkt.size + 16)) < 0) {
3041                             rt->flv_size = rt->flv_off = rt->flv_header_bytes = 0;
3042                             return ret;
3043                         }
3044                         memmove(rt->out_pkt.data + 16, rt->out_pkt.data, rt->out_pkt.size);
3045                         rt->out_pkt.size += 16;
3046                         ptr = rt->out_pkt.data;
3047                         ff_amf_write_string(&ptr, "@setDataFrame");
3048                     }
3049                 }
3050             }
3051 
3052             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
3053                 return ret;
3054             rt->flv_size = 0;
3055             rt->flv_off = 0;
3056             rt->flv_header_bytes = 0;
3057             rt->flv_nb_packets++;
3058         }
3059     } while (buf_temp - buf < size);
3060 
3061     if (rt->flv_nb_packets < rt->flush_interval)
3062         return size;
3063     rt->flv_nb_packets = 0;
3064 
3065     /* set stream into nonblocking mode */
3066     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
3067 
3068     /* try to read one byte from the stream */
3069     ret = ffurl_read(rt->stream, &c, 1);
3070 
3071     /* switch the stream back into blocking mode */
3072     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
3073 
3074     if (ret == AVERROR(EAGAIN)) {
3075         /* no incoming data to handle */
3076         return size;
3077     } else if (ret < 0) {
3078         return ret;
3079     } else if (ret == 1) {
3080         RTMPPacket rpkt = { 0 };
3081 
3082         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
3083                                                 rt->in_chunk_size,
3084                                                 &rt->prev_pkt[0],
3085                                                 &rt->nb_prev_pkt[0], c)) <= 0)
3086              return ret;
3087 
3088         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
3089             return ret;
3090 
3091         ff_rtmp_packet_destroy(&rpkt);
3092     }
3093 
3094     return size;
3095 }
3096 
3097 #define OFFSET(x) offsetof(RTMPContext, x)
3098 #define DEC AV_OPT_FLAG_DECODING_PARAM
3099 #define ENC AV_OPT_FLAG_ENCODING_PARAM
3100 
3101 static const AVOption rtmp_options[] = {
3102     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3103     {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
3104     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3105     {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3106     {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
3107     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
3108     {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
3109     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
3110     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
3111     {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3112     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3113     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3114     {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
3115     {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
3116     {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3117     {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3118     {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3119     {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3120     {"listen",      "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3121     {"tcp_nodelay", "Use TCP_NODELAY to disable Nagle's algorithm", OFFSET(tcp_nodelay), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC|ENC},
3122     {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3123     { NULL },
3124 };
3125 
3126 #define RTMP_PROTOCOL_0(flavor)
3127 #define RTMP_PROTOCOL_1(flavor)                  \
3128 static const AVClass flavor##_class = {          \
3129     .class_name = #flavor,                       \
3130     .item_name  = av_default_item_name,          \
3131     .option     = rtmp_options,                  \
3132     .version    = LIBAVUTIL_VERSION_INT,         \
3133 };                                               \
3134                                                  \
3135 const URLProtocol ff_##flavor##_protocol = {     \
3136     .name           = #flavor,                   \
3137     .url_open2      = rtmp_open,                 \
3138     .url_read       = rtmp_read,                 \
3139     .url_read_seek  = rtmp_seek,                 \
3140     .url_read_pause = rtmp_pause,                \
3141     .url_write      = rtmp_write,                \
3142     .url_close      = rtmp_close,                \
3143     .priv_data_size = sizeof(RTMPContext),       \
3144     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
3145     .priv_data_class= &flavor##_class,           \
3146 };
3147 #define RTMP_PROTOCOL_2(flavor, enabled)         \
3148     RTMP_PROTOCOL_ ## enabled(flavor)
3149 #define RTMP_PROTOCOL_3(flavor, config)          \
3150     RTMP_PROTOCOL_2(flavor, config)
3151 #define RTMP_PROTOCOL(flavor, uppercase)         \
3152     RTMP_PROTOCOL_3(flavor, CONFIG_ ## uppercase ## _PROTOCOL)
3153 
3154 RTMP_PROTOCOL(rtmp,   RTMP)
3155 RTMP_PROTOCOL(rtmpe,  RTMPE)
3156 RTMP_PROTOCOL(rtmps,  RTMPS)
3157 RTMP_PROTOCOL(rtmpt,  RTMPT)
3158 RTMP_PROTOCOL(rtmpte, RTMPTE)
3159 RTMP_PROTOCOL(rtmpts, RTMPTS)
3160