rtmpproto.c
Go to the documentation of this file.
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Kostya Shishkov
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/base64.h"
30 #include "libavutil/intfloat.h"
31 #include "libavutil/lfg.h"
32 #include "libavutil/md5.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/random_seed.h"
35 #include "libavutil/sha.h"
36 #include "avformat.h"
37 #include "internal.h"
38 
39 #include "network.h"
40 
41 #include "flv.h"
42 #include "rtmp.h"
43 #include "rtmpcrypt.h"
44 #include "rtmppkt.h"
45 #include "url.h"
46 
47 #if CONFIG_ZLIB
48 #include <zlib.h>
49 #endif
50 
51 //#define DEBUG
52 
53 #define APP_MAX_LENGTH 128
54 #define PLAYPATH_MAX_LENGTH 256
55 #define TCURL_MAX_LENGTH 512
56 #define FLASHVER_MAX_LENGTH 64
57 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
58 
60 typedef enum {
68 } ClientState;
69 
70 typedef struct TrackedMethod {
71  char *name;
72  int id;
74 
76 typedef struct RTMPContext {
77  const AVClass *class;
82  int is_input;
83  char *playpath;
84  int live;
85  char *app;
86  char *conn;
90  int flv_size;
91  int flv_off;
94  uint32_t client_report_size;
95  uint32_t bytes_read;
96  uint32_t last_bytes_read;
97  int skip_bytes;
101  char* tcurl;
102  char* flashver;
103  char* swfhash;
105  int swfsize;
106  char* swfurl;
107  char* swfverify;
108  char swfverification[42];
109  char* pageurl;
110  char* subscribe;
111  int server_bw;
114  int encrypted;
118  int listen;
121  char username[50];
122  char password[50];
123  char auth_params[500];
126 } RTMPContext;
127 
128 #define PLAYER_KEY_OPEN_PART_LEN 30
129 
130 static const uint8_t rtmp_player_key[] = {
131  'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
132  'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
133 
134  0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
135  0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
136  0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
137 };
138 
139 #define SERVER_KEY_OPEN_PART_LEN 36
140 
141 static const uint8_t rtmp_server_key[] = {
142  'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
143  'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
144  'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
145 
146  0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
147  0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
148  0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
149 };
150 
151 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
152 {
153  void *ptr;
154 
155  if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
156  rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
157  ptr = av_realloc(rt->tracked_methods,
158  rt->tracked_methods_size * sizeof(*rt->tracked_methods));
159  if (!ptr)
160  return AVERROR(ENOMEM);
161  rt->tracked_methods = ptr;
162  }
163 
166  return AVERROR(ENOMEM);
168  rt->nb_tracked_methods++;
169 
170  return 0;
171 }
172 
173 static void del_tracked_method(RTMPContext *rt, int index)
174 {
175  memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
176  sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
177  rt->nb_tracked_methods--;
178 }
179 
180 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
181  char **tracked_method)
182 {
183  RTMPContext *rt = s->priv_data;
184  GetByteContext gbc;
185  double pkt_id;
186  int ret;
187  int i;
188 
189  bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
190  if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
191  return ret;
192 
193  for (i = 0; i < rt->nb_tracked_methods; i++) {
194  if (rt->tracked_methods[i].id != pkt_id)
195  continue;
196 
197  *tracked_method = rt->tracked_methods[i].name;
198  del_tracked_method(rt, i);
199  break;
200  }
201 
202  return 0;
203 }
204 
206 {
207  int i;
208 
209  for (i = 0; i < rt->nb_tracked_methods; i ++)
210  av_free(rt->tracked_methods[i].name);
212  rt->tracked_methods = NULL;
213  rt->tracked_methods_size = 0;
214  rt->nb_tracked_methods = 0;
215 }
216 
217 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
218 {
219  int ret;
220 
221  if (pkt->type == RTMP_PT_INVOKE && track) {
222  GetByteContext gbc;
223  char name[128];
224  double pkt_id;
225  int len;
226 
227  bytestream2_init(&gbc, pkt->data, pkt->data_size);
228  if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
229  goto fail;
230 
231  if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
232  goto fail;
233 
234  if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
235  goto fail;
236  }
237 
238  ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
239  rt->prev_pkt[1]);
240 fail:
242  return ret;
243 }
244 
245 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
246 {
247  char *field, *value;
248  char type;
249 
250  /* The type must be B for Boolean, N for number, S for string, O for
251  * object, or Z for null. For Booleans the data must be either 0 or 1 for
252  * FALSE or TRUE, respectively. Likewise for Objects the data must be
253  * 0 or 1 to end or begin an object, respectively. Data items in subobjects
254  * may be named, by prefixing the type with 'N' and specifying the name
255  * before the value (ie. NB:myFlag:1). This option may be used multiple times
256  * to construct arbitrary AMF sequences. */
257  if (param[0] && param[1] == ':') {
258  type = param[0];
259  value = param + 2;
260  } else if (param[0] == 'N' && param[1] && param[2] == ':') {
261  type = param[1];
262  field = param + 3;
263  value = strchr(field, ':');
264  if (!value)
265  goto fail;
266  *value = '\0';
267  value++;
268 
269  if (!field || !value)
270  goto fail;
271 
272  ff_amf_write_field_name(p, field);
273  } else {
274  goto fail;
275  }
276 
277  switch (type) {
278  case 'B':
279  ff_amf_write_bool(p, value[0] != '0');
280  break;
281  case 'S':
282  ff_amf_write_string(p, value);
283  break;
284  case 'N':
285  ff_amf_write_number(p, strtod(value, NULL));
286  break;
287  case 'Z':
289  break;
290  case 'O':
291  if (value[0] != '0')
293  else
295  break;
296  default:
297  goto fail;
298  break;
299  }
300 
301  return 0;
302 
303 fail:
304  av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
305  return AVERROR(EINVAL);
306 }
307 
311 static int gen_connect(URLContext *s, RTMPContext *rt)
312 {
313  RTMPPacket pkt;
314  uint8_t *p;
315  int ret;
316 
318  0, 4096)) < 0)
319  return ret;
320 
321  p = pkt.data;
322 
323  ff_amf_write_string(&p, "connect");
324  ff_amf_write_number(&p, ++rt->nb_invokes);
326  ff_amf_write_field_name(&p, "app");
327  ff_amf_write_string2(&p, rt->app, rt->auth_params);
328 
329  if (!rt->is_input) {
330  ff_amf_write_field_name(&p, "type");
331  ff_amf_write_string(&p, "nonprivate");
332  }
333  ff_amf_write_field_name(&p, "flashVer");
334  ff_amf_write_string(&p, rt->flashver);
335 
336  if (rt->swfurl) {
337  ff_amf_write_field_name(&p, "swfUrl");
338  ff_amf_write_string(&p, rt->swfurl);
339  }
340 
341  ff_amf_write_field_name(&p, "tcUrl");
342  ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
343  if (rt->is_input) {
344  ff_amf_write_field_name(&p, "fpad");
345  ff_amf_write_bool(&p, 0);
346  ff_amf_write_field_name(&p, "capabilities");
347  ff_amf_write_number(&p, 15.0);
348 
349  /* Tell the server we support all the audio codecs except
350  * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
351  * which are unused in the RTMP protocol implementation. */
352  ff_amf_write_field_name(&p, "audioCodecs");
353  ff_amf_write_number(&p, 4071.0);
354  ff_amf_write_field_name(&p, "videoCodecs");
355  ff_amf_write_number(&p, 252.0);
356  ff_amf_write_field_name(&p, "videoFunction");
357  ff_amf_write_number(&p, 1.0);
358 
359  if (rt->pageurl) {
360  ff_amf_write_field_name(&p, "pageUrl");
361  ff_amf_write_string(&p, rt->pageurl);
362  }
363  }
365 
366  if (rt->conn) {
367  char *param = rt->conn;
368 
369  // Write arbitrary AMF data to the Connect message.
370  while (param != NULL) {
371  char *sep;
372  param += strspn(param, " ");
373  if (!*param)
374  break;
375  sep = strchr(param, ' ');
376  if (sep)
377  *sep = '\0';
378  if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
379  // Invalid AMF parameter.
381  return ret;
382  }
383 
384  if (sep)
385  param = sep + 1;
386  else
387  break;
388  }
389  }
390 
391  pkt.data_size = p - pkt.data;
392 
393  return rtmp_send_packet(rt, &pkt, 1);
394 }
395 
397 {
398  RTMPPacket pkt = { 0 };
399  uint8_t *p;
400  const uint8_t *cp;
401  int ret;
402  char command[64];
403  int stringlen;
404  double seqnum;
405  uint8_t tmpstr[256];
406  GetByteContext gbc;
407 
408  if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
409  rt->prev_pkt[1])) < 0)
410  return ret;
411  cp = pkt.data;
412  bytestream2_init(&gbc, cp, pkt.data_size);
413  if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
414  av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
416  return AVERROR_INVALIDDATA;
417  }
418  if (strcmp(command, "connect")) {
419  av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
421  return AVERROR_INVALIDDATA;
422  }
423  ret = ff_amf_read_number(&gbc, &seqnum);
424  if (ret)
425  av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
426  /* Here one could parse an AMF Object with data as flashVers and others. */
427  ret = ff_amf_get_field_value(gbc.buffer,
429  "app", tmpstr, sizeof(tmpstr));
430  if (ret)
431  av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
432  if (!ret && strcmp(tmpstr, rt->app))
433  av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
434  tmpstr, rt->app);
436 
437  // Send Window Acknowledgement Size (as defined in speficication)
439  RTMP_PT_SERVER_BW, 0, 4)) < 0)
440  return ret;
441  p = pkt.data;
442  bytestream_put_be32(&p, rt->server_bw);
443  pkt.data_size = p - pkt.data;
444  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
445  rt->prev_pkt[1]);
447  if (ret < 0)
448  return ret;
449  // Send Peer Bandwidth
451  RTMP_PT_CLIENT_BW, 0, 5)) < 0)
452  return ret;
453  p = pkt.data;
454  bytestream_put_be32(&p, rt->server_bw);
455  bytestream_put_byte(&p, 2); // dynamic
456  pkt.data_size = p - pkt.data;
457  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
458  rt->prev_pkt[1]);
460  if (ret < 0)
461  return ret;
462 
463  // Ping request
465  RTMP_PT_PING, 0, 6)) < 0)
466  return ret;
467 
468  p = pkt.data;
469  bytestream_put_be16(&p, 0); // 0 -> Stream Begin
470  bytestream_put_be32(&p, 0);
471  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
472  rt->prev_pkt[1]);
474  if (ret < 0)
475  return ret;
476 
477  // Chunk size
479  RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
480  return ret;
481 
482  p = pkt.data;
483  bytestream_put_be32(&p, rt->out_chunk_size);
484  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
485  rt->prev_pkt[1]);
487  if (ret < 0)
488  return ret;
489 
490  // Send result_ NetConnection.Connect.Success to connect
492  RTMP_PT_INVOKE, 0,
494  return ret;
495 
496  p = pkt.data;
497  ff_amf_write_string(&p, "_result");
498  ff_amf_write_number(&p, seqnum);
499 
501  ff_amf_write_field_name(&p, "fmsVer");
502  ff_amf_write_string(&p, "FMS/3,0,1,123");
503  ff_amf_write_field_name(&p, "capabilities");
504  ff_amf_write_number(&p, 31);
506 
508  ff_amf_write_field_name(&p, "level");
509  ff_amf_write_string(&p, "status");
510  ff_amf_write_field_name(&p, "code");
511  ff_amf_write_string(&p, "NetConnection.Connect.Success");
512  ff_amf_write_field_name(&p, "description");
513  ff_amf_write_string(&p, "Connection succeeded.");
514  ff_amf_write_field_name(&p, "objectEncoding");
515  ff_amf_write_number(&p, 0);
517 
518  pkt.data_size = p - pkt.data;
519  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
520  rt->prev_pkt[1]);
522  if (ret < 0)
523  return ret;
524 
526  RTMP_PT_INVOKE, 0, 30)) < 0)
527  return ret;
528  p = pkt.data;
529  ff_amf_write_string(&p, "onBWDone");
530  ff_amf_write_number(&p, 0);
531  ff_amf_write_null(&p);
532  ff_amf_write_number(&p, 8192);
533  pkt.data_size = p - pkt.data;
534  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
535  rt->prev_pkt[1]);
537 
538  return ret;
539 }
540 
546 {
547  RTMPPacket pkt;
548  uint8_t *p;
549  int ret;
550 
552  0, 29 + strlen(rt->playpath))) < 0)
553  return ret;
554 
555  av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
556  p = pkt.data;
557  ff_amf_write_string(&p, "releaseStream");
558  ff_amf_write_number(&p, ++rt->nb_invokes);
559  ff_amf_write_null(&p);
560  ff_amf_write_string(&p, rt->playpath);
561 
562  return rtmp_send_packet(rt, &pkt, 1);
563 }
564 
570 {
571  RTMPPacket pkt;
572  uint8_t *p;
573  int ret;
574 
576  0, 25 + strlen(rt->playpath))) < 0)
577  return ret;
578 
579  av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
580  p = pkt.data;
581  ff_amf_write_string(&p, "FCPublish");
582  ff_amf_write_number(&p, ++rt->nb_invokes);
583  ff_amf_write_null(&p);
584  ff_amf_write_string(&p, rt->playpath);
585 
586  return rtmp_send_packet(rt, &pkt, 1);
587 }
588 
594 {
595  RTMPPacket pkt;
596  uint8_t *p;
597  int ret;
598 
600  0, 27 + strlen(rt->playpath))) < 0)
601  return ret;
602 
603  av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
604  p = pkt.data;
605  ff_amf_write_string(&p, "FCUnpublish");
606  ff_amf_write_number(&p, ++rt->nb_invokes);
607  ff_amf_write_null(&p);
608  ff_amf_write_string(&p, rt->playpath);
609 
610  return rtmp_send_packet(rt, &pkt, 0);
611 }
612 
618 {
619  RTMPPacket pkt;
620  uint8_t *p;
621  int ret;
622 
623  av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
624 
626  0, 25)) < 0)
627  return ret;
628 
629  p = pkt.data;
630  ff_amf_write_string(&p, "createStream");
631  ff_amf_write_number(&p, ++rt->nb_invokes);
632  ff_amf_write_null(&p);
633 
634  return rtmp_send_packet(rt, &pkt, 1);
635 }
636 
637 
643 {
644  RTMPPacket pkt;
645  uint8_t *p;
646  int ret;
647 
648  av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
649 
651  0, 34)) < 0)
652  return ret;
653 
654  p = pkt.data;
655  ff_amf_write_string(&p, "deleteStream");
656  ff_amf_write_number(&p, ++rt->nb_invokes);
657  ff_amf_write_null(&p);
659 
660  return rtmp_send_packet(rt, &pkt, 0);
661 }
662 
667 {
668  RTMPPacket pkt;
669  uint8_t *p;
670  int ret;
671 
673  1, 10)) < 0)
674  return ret;
675 
676  p = pkt.data;
677  bytestream_put_be16(&p, 3);
678  bytestream_put_be32(&p, rt->main_channel_id);
679  bytestream_put_be32(&p, rt->client_buffer_time);
680 
681  return rtmp_send_packet(rt, &pkt, 0);
682 }
683 
688 static int gen_play(URLContext *s, RTMPContext *rt)
689 {
690  RTMPPacket pkt;
691  uint8_t *p;
692  int ret;
693 
694  av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
695 
697  0, 29 + strlen(rt->playpath))) < 0)
698  return ret;
699 
700  pkt.extra = rt->main_channel_id;
701 
702  p = pkt.data;
703  ff_amf_write_string(&p, "play");
704  ff_amf_write_number(&p, ++rt->nb_invokes);
705  ff_amf_write_null(&p);
706  ff_amf_write_string(&p, rt->playpath);
707  ff_amf_write_number(&p, rt->live);
708 
709  return rtmp_send_packet(rt, &pkt, 1);
710 }
711 
715 static int gen_publish(URLContext *s, RTMPContext *rt)
716 {
717  RTMPPacket pkt;
718  uint8_t *p;
719  int ret;
720 
721  av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
722 
724  0, 30 + strlen(rt->playpath))) < 0)
725  return ret;
726 
727  pkt.extra = rt->main_channel_id;
728 
729  p = pkt.data;
730  ff_amf_write_string(&p, "publish");
731  ff_amf_write_number(&p, ++rt->nb_invokes);
732  ff_amf_write_null(&p);
733  ff_amf_write_string(&p, rt->playpath);
734  ff_amf_write_string(&p, "live");
735 
736  return rtmp_send_packet(rt, &pkt, 1);
737 }
738 
742 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
743 {
744  RTMPPacket pkt;
745  uint8_t *p;
746  int ret;
747 
748  if (ppkt->data_size < 6) {
749  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
750  ppkt->data_size);
751  return AVERROR_INVALIDDATA;
752  }
753 
755  ppkt->timestamp + 1, 6)) < 0)
756  return ret;
757 
758  p = pkt.data;
759  bytestream_put_be16(&p, 7);
760  bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
761 
762  return rtmp_send_packet(rt, &pkt, 0);
763 }
764 
769 {
770  RTMPPacket pkt;
771  uint8_t *p;
772  int ret;
773 
774  av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
776  0, 44)) < 0)
777  return ret;
778 
779  p = pkt.data;
780  bytestream_put_be16(&p, 27);
781  memcpy(p, rt->swfverification, 42);
782 
783  return rtmp_send_packet(rt, &pkt, 0);
784 }
785 
790 {
791  RTMPPacket pkt;
792  uint8_t *p;
793  int ret;
794 
796  0, 4)) < 0)
797  return ret;
798 
799  p = pkt.data;
800  bytestream_put_be32(&p, rt->server_bw);
801 
802  return rtmp_send_packet(rt, &pkt, 0);
803 }
804 
809 {
810  RTMPPacket pkt;
811  uint8_t *p;
812  int ret;
813 
815  0, 21)) < 0)
816  return ret;
817 
818  p = pkt.data;
819  ff_amf_write_string(&p, "_checkbw");
820  ff_amf_write_number(&p, ++rt->nb_invokes);
821  ff_amf_write_null(&p);
822 
823  return rtmp_send_packet(rt, &pkt, 1);
824 }
825 
829 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
830 {
831  RTMPPacket pkt;
832  uint8_t *p;
833  int ret;
834 
836  ts, 4)) < 0)
837  return ret;
838 
839  p = pkt.data;
840  bytestream_put_be32(&p, rt->bytes_read);
841 
842  return rtmp_send_packet(rt, &pkt, 0);
843 }
844 
846  const char *subscribe)
847 {
848  RTMPPacket pkt;
849  uint8_t *p;
850  int ret;
851 
853  0, 27 + strlen(subscribe))) < 0)
854  return ret;
855 
856  p = pkt.data;
857  ff_amf_write_string(&p, "FCSubscribe");
858  ff_amf_write_number(&p, ++rt->nb_invokes);
859  ff_amf_write_null(&p);
860  ff_amf_write_string(&p, subscribe);
861 
862  return rtmp_send_packet(rt, &pkt, 1);
863 }
864 
865 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
866  const uint8_t *key, int keylen, uint8_t *dst)
867 {
868  struct AVSHA *sha;
869  uint8_t hmac_buf[64+32] = {0};
870  int i;
871 
872  sha = av_sha_alloc();
873  if (!sha)
874  return AVERROR(ENOMEM);
875 
876  if (keylen < 64) {
877  memcpy(hmac_buf, key, keylen);
878  } else {
879  av_sha_init(sha, 256);
880  av_sha_update(sha,key, keylen);
881  av_sha_final(sha, hmac_buf);
882  }
883  for (i = 0; i < 64; i++)
884  hmac_buf[i] ^= HMAC_IPAD_VAL;
885 
886  av_sha_init(sha, 256);
887  av_sha_update(sha, hmac_buf, 64);
888  if (gap <= 0) {
889  av_sha_update(sha, src, len);
890  } else { //skip 32 bytes used for storing digest
891  av_sha_update(sha, src, gap);
892  av_sha_update(sha, src + gap + 32, len - gap - 32);
893  }
894  av_sha_final(sha, hmac_buf + 64);
895 
896  for (i = 0; i < 64; i++)
897  hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
898  av_sha_init(sha, 256);
899  av_sha_update(sha, hmac_buf, 64+32);
900  av_sha_final(sha, dst);
901 
902  av_free(sha);
903 
904  return 0;
905 }
906 
907 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
908  int add_val)
909 {
910  int i, digest_pos = 0;
911 
912  for (i = 0; i < 4; i++)
913  digest_pos += buf[i + off];
914  digest_pos = digest_pos % mod_val + add_val;
915 
916  return digest_pos;
917 }
918 
927 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
928 {
929  int ret, digest_pos;
930 
931  if (encrypted)
932  digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
933  else
934  digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
935 
936  ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
938  buf + digest_pos);
939  if (ret < 0)
940  return ret;
941 
942  return digest_pos;
943 }
944 
952 static int rtmp_validate_digest(uint8_t *buf, int off)
953 {
954  uint8_t digest[32];
955  int ret, digest_pos;
956 
957  digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
958 
959  ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
961  digest);
962  if (ret < 0)
963  return ret;
964 
965  if (!memcmp(digest, buf + digest_pos, 32))
966  return digest_pos;
967  return 0;
968 }
969 
971  uint8_t *buf)
972 {
973  uint8_t *p;
974  int ret;
975 
976  if (rt->swfhash_len != 32) {
977  av_log(s, AV_LOG_ERROR,
978  "Hash of the decompressed SWF file is not 32 bytes long.\n");
979  return AVERROR(EINVAL);
980  }
981 
982  p = &rt->swfverification[0];
983  bytestream_put_byte(&p, 1);
984  bytestream_put_byte(&p, 1);
985  bytestream_put_be32(&p, rt->swfsize);
986  bytestream_put_be32(&p, rt->swfsize);
987 
988  if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
989  return ret;
990 
991  return 0;
992 }
993 
994 #if CONFIG_ZLIB
995 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
996  uint8_t **out_data, int64_t *out_size)
997 {
998  z_stream zs = { 0 };
999  void *ptr;
1000  int size;
1001  int ret = 0;
1002 
1003  zs.avail_in = in_size;
1004  zs.next_in = in_data;
1005  ret = inflateInit(&zs);
1006  if (ret != Z_OK)
1007  return AVERROR_UNKNOWN;
1008 
1009  do {
1010  uint8_t tmp_buf[16384];
1011 
1012  zs.avail_out = sizeof(tmp_buf);
1013  zs.next_out = tmp_buf;
1014 
1015  ret = inflate(&zs, Z_NO_FLUSH);
1016  if (ret != Z_OK && ret != Z_STREAM_END) {
1017  ret = AVERROR_UNKNOWN;
1018  goto fail;
1019  }
1020 
1021  size = sizeof(tmp_buf) - zs.avail_out;
1022  if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1023  ret = AVERROR(ENOMEM);
1024  goto fail;
1025  }
1026  *out_data = ptr;
1027 
1028  memcpy(*out_data + *out_size, tmp_buf, size);
1029  *out_size += size;
1030  } while (zs.avail_out == 0);
1031 
1032 fail:
1033  inflateEnd(&zs);
1034  return ret;
1035 }
1036 #endif
1037 
1039 {
1040  RTMPContext *rt = s->priv_data;
1041  uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1042  int64_t in_size, out_size;
1043  URLContext *stream;
1044  char swfhash[32];
1045  int swfsize;
1046  int ret = 0;
1047 
1048  /* Get the SWF player file. */
1049  if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1050  &s->interrupt_callback, NULL)) < 0) {
1051  av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1052  goto fail;
1053  }
1054 
1055  if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1056  ret = AVERROR(EIO);
1057  goto fail;
1058  }
1059 
1060  if (!(in_data = av_malloc(in_size))) {
1061  ret = AVERROR(ENOMEM);
1062  goto fail;
1063  }
1064 
1065  if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1066  goto fail;
1067 
1068  if (in_size < 3) {
1069  ret = AVERROR_INVALIDDATA;
1070  goto fail;
1071  }
1072 
1073  if (!memcmp(in_data, "CWS", 3)) {
1074  /* Decompress the SWF player file using Zlib. */
1075  if (!(out_data = av_malloc(8))) {
1076  ret = AVERROR(ENOMEM);
1077  goto fail;
1078  }
1079  *in_data = 'F'; // magic stuff
1080  memcpy(out_data, in_data, 8);
1081  out_size = 8;
1082 
1083 #if CONFIG_ZLIB
1084  if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1085  &out_data, &out_size)) < 0)
1086  goto fail;
1087 #else
1088  av_log(s, AV_LOG_ERROR,
1089  "Zlib is required for decompressing the SWF player file.\n");
1090  ret = AVERROR(EINVAL);
1091  goto fail;
1092 #endif
1093  swfsize = out_size;
1094  swfdata = out_data;
1095  } else {
1096  swfsize = in_size;
1097  swfdata = in_data;
1098  }
1099 
1100  /* Compute the SHA256 hash of the SWF player file. */
1101  if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1102  "Genuine Adobe Flash Player 001", 30,
1103  swfhash)) < 0)
1104  goto fail;
1105 
1106  /* Set SWFVerification parameters. */
1107  av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1108  rt->swfsize = swfsize;
1109 
1110 fail:
1111  av_freep(&in_data);
1112  av_freep(&out_data);
1113  ffurl_close(stream);
1114  return ret;
1115 }
1116 
1124 {
1125  AVLFG rnd;
1126  uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1127  3, // unencrypted data
1128  0, 0, 0, 0, // client uptime
1133  };
1134  uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1135  uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1136  int i;
1137  int server_pos, client_pos;
1138  uint8_t digest[32], signature[32];
1139  int ret, type = 0;
1140 
1141  av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1142 
1143  av_lfg_init(&rnd, 0xDEADC0DE);
1144  // generate handshake packet - 1536 bytes of pseudorandom data
1145  for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1146  tosend[i] = av_lfg_get(&rnd) >> 24;
1147 
1149  /* When the client wants to use RTMPE, we have to change the command
1150  * byte to 0x06 which means to use encrypted data and we have to set
1151  * the flash version to at least 9.0.115.0. */
1152  tosend[0] = 6;
1153  tosend[5] = 128;
1154  tosend[6] = 0;
1155  tosend[7] = 3;
1156  tosend[8] = 2;
1157 
1158  /* Initialize the Diffie-Hellmann context and generate the public key
1159  * to send to the server. */
1160  if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1161  return ret;
1162  }
1163 
1164  client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1165  if (client_pos < 0)
1166  return client_pos;
1167 
1168  if ((ret = ffurl_write(rt->stream, tosend,
1169  RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1170  av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1171  return ret;
1172  }
1173 
1174  if ((ret = ffurl_read_complete(rt->stream, serverdata,
1175  RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1176  av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1177  return ret;
1178  }
1179 
1180  if ((ret = ffurl_read_complete(rt->stream, clientdata,
1182  av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1183  return ret;
1184  }
1185 
1186  av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1187  av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1188  serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1189 
1190  if (rt->is_input && serverdata[5] >= 3) {
1191  server_pos = rtmp_validate_digest(serverdata + 1, 772);
1192  if (server_pos < 0)
1193  return server_pos;
1194 
1195  if (!server_pos) {
1196  type = 1;
1197  server_pos = rtmp_validate_digest(serverdata + 1, 8);
1198  if (server_pos < 0)
1199  return server_pos;
1200 
1201  if (!server_pos) {
1202  av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1203  return AVERROR(EIO);
1204  }
1205  }
1206 
1207  /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1208  * key are the last 32 bytes of the server handshake. */
1209  if (rt->swfsize) {
1210  if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1211  RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1212  return ret;
1213  }
1214 
1215  ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1217  digest);
1218  if (ret < 0)
1219  return ret;
1220 
1221  ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1222  0, digest, 32, signature);
1223  if (ret < 0)
1224  return ret;
1225 
1227  /* Compute the shared secret key sent by the server and initialize
1228  * the RC4 encryption. */
1229  if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1230  tosend + 1, type)) < 0)
1231  return ret;
1232 
1233  /* Encrypt the signature received by the server. */
1234  ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1235  }
1236 
1237  if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1238  av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1239  return AVERROR(EIO);
1240  }
1241 
1242  for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1243  tosend[i] = av_lfg_get(&rnd) >> 24;
1244  ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1246  digest);
1247  if (ret < 0)
1248  return ret;
1249 
1250  ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1251  digest, 32,
1252  tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1253  if (ret < 0)
1254  return ret;
1255 
1257  /* Encrypt the signature to be send to the server. */
1258  ff_rtmpe_encrypt_sig(rt->stream, tosend +
1259  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1260  serverdata[0]);
1261  }
1262 
1263  // write reply back to the server
1264  if ((ret = ffurl_write(rt->stream, tosend,
1265  RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1266  return ret;
1267 
1269  /* Set RC4 keys for encryption and update the keystreams. */
1270  if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1271  return ret;
1272  }
1273  } else {
1275  /* Compute the shared secret key sent by the server and initialize
1276  * the RC4 encryption. */
1277  if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1278  tosend + 1, 1)) < 0)
1279  return ret;
1280 
1281  if (serverdata[0] == 9) {
1282  /* Encrypt the signature received by the server. */
1283  ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1284  serverdata[0]);
1285  }
1286  }
1287 
1288  if ((ret = ffurl_write(rt->stream, serverdata + 1,
1290  return ret;
1291 
1293  /* Set RC4 keys for encryption and update the keystreams. */
1294  if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1295  return ret;
1296  }
1297  }
1298 
1299  return 0;
1300 }
1301 
1302 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1303  uint32_t *second_int, char *arraydata,
1304  int size)
1305 {
1306  int inoutsize;
1307 
1308  inoutsize = ffurl_read_complete(rt->stream, arraydata,
1310  if (inoutsize <= 0)
1311  return AVERROR(EIO);
1312  if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1313  av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1314  " not following standard\n", (int)inoutsize);
1315  return AVERROR(EINVAL);
1316  }
1317 
1318  *first_int = AV_RB32(arraydata);
1319  *second_int = AV_RB32(arraydata + 4);
1320  return 0;
1321 }
1322 
1323 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1324  uint32_t second_int, char *arraydata, int size)
1325 {
1326  int inoutsize;
1327 
1328  AV_WB32(arraydata, first_int);
1329  AV_WB32(arraydata + 4, first_int);
1330  inoutsize = ffurl_write(rt->stream, arraydata,
1332  if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1333  av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1334  return AVERROR(EIO);
1335  }
1336 
1337  return 0;
1338 }
1339 
1344 {
1346  uint32_t hs_epoch;
1347  uint32_t hs_my_epoch;
1350  uint32_t zeroes;
1351  uint32_t temp = 0;
1352  int randomidx = 0;
1353  int inoutsize = 0;
1354  int ret;
1355 
1356  inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // Receive C0
1357  if (inoutsize <= 0) {
1358  av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1359  return AVERROR(EIO);
1360  }
1361  // Check Version
1362  if (buffer[0] != 3) {
1363  av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1364  return AVERROR(EIO);
1365  }
1366  if (ffurl_write(rt->stream, buffer, 1) <= 0) { // Send S0
1367  av_log(s, AV_LOG_ERROR,
1368  "Unable to write answer - RTMP S0\n");
1369  return AVERROR(EIO);
1370  }
1371  /* Receive C1 */
1372  ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1374  if (ret) {
1375  av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1376  return ret;
1377  }
1378  if (zeroes)
1379  av_log(s, AV_LOG_WARNING, "Erroneous C1 Message zero != 0\n");
1380  /* Send S1 */
1381  /* By now same epoch will be sent */
1382  hs_my_epoch = hs_epoch;
1383  /* Generate random */
1384  for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1385  randomidx += 4)
1386  AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1387 
1388  ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1390  if (ret) {
1391  av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1392  return ret;
1393  }
1394  /* Send S2 */
1395  ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1397  if (ret) {
1398  av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1399  return ret;
1400  }
1401  /* Receive C2 */
1402  ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1404  if (ret) {
1405  av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1406  return ret;
1407  }
1408  if (temp != hs_my_epoch)
1410  "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1411  if (memcmp(buffer + 8, hs_s1 + 8,
1414  "Erroneous C2 Message random does not match up\n");
1415 
1416  return 0;
1417 }
1418 
1420 {
1421  RTMPContext *rt = s->priv_data;
1422  int ret;
1423 
1424  if (pkt->data_size < 4) {
1425  av_log(s, AV_LOG_ERROR,
1426  "Too short chunk size change packet (%d)\n",
1427  pkt->data_size);
1428  return AVERROR_INVALIDDATA;
1429  }
1430 
1431  if (!rt->is_input) {
1432  /* Send the same chunk size change packet back to the server,
1433  * setting the outgoing chunk size to the same as the incoming one. */
1434  if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1435  rt->prev_pkt[1])) < 0)
1436  return ret;
1437  rt->out_chunk_size = AV_RB32(pkt->data);
1438  }
1439 
1440  rt->in_chunk_size = AV_RB32(pkt->data);
1441  if (rt->in_chunk_size <= 0) {
1442  av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1443  rt->in_chunk_size);
1444  return AVERROR_INVALIDDATA;
1445  }
1446  av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1447  rt->in_chunk_size);
1448 
1449  return 0;
1450 }
1451 
1452 static int handle_ping(URLContext *s, RTMPPacket *pkt)
1453 {
1454  RTMPContext *rt = s->priv_data;
1455  int t, ret;
1456 
1457  if (pkt->data_size < 2) {
1458  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1459  pkt->data_size);
1460  return AVERROR_INVALIDDATA;
1461  }
1462 
1463  t = AV_RB16(pkt->data);
1464  if (t == 6) {
1465  if ((ret = gen_pong(s, rt, pkt)) < 0)
1466  return ret;
1467  } else if (t == 26) {
1468  if (rt->swfsize) {
1469  if ((ret = gen_swf_verification(s, rt)) < 0)
1470  return ret;
1471  } else {
1472  av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1473  }
1474  }
1475 
1476  return 0;
1477 }
1478 
1480 {
1481  RTMPContext *rt = s->priv_data;
1482 
1483  if (pkt->data_size < 4) {
1484  av_log(s, AV_LOG_ERROR,
1485  "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1486  pkt->data_size);
1487  return AVERROR_INVALIDDATA;
1488  }
1489 
1490  rt->client_report_size = AV_RB32(pkt->data);
1491  if (rt->client_report_size <= 0) {
1492  av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1493  rt->client_report_size);
1494  return AVERROR_INVALIDDATA;
1495 
1496  }
1497  av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1498  rt->client_report_size >>= 1;
1499 
1500  return 0;
1501 }
1502 
1504 {
1505  RTMPContext *rt = s->priv_data;
1506 
1507  if (pkt->data_size < 4) {
1508  av_log(s, AV_LOG_ERROR,
1509  "Too short server bandwidth report packet (%d)\n",
1510  pkt->data_size);
1511  return AVERROR_INVALIDDATA;
1512  }
1513 
1514  rt->server_bw = AV_RB32(pkt->data);
1515  if (rt->server_bw <= 0) {
1516  av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1517  rt->server_bw);
1518  return AVERROR_INVALIDDATA;
1519  }
1520  av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1521 
1522  return 0;
1523 }
1524 
1525 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1526  const char *opaque, const char *challenge)
1527 {
1528  uint8_t hash[16];
1529  char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1530  struct AVMD5 *md5 = av_md5_alloc();
1531  if (!md5)
1532  return AVERROR(ENOMEM);
1533 
1534  snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1535 
1536  av_md5_init(md5);
1537  av_md5_update(md5, user, strlen(user));
1538  av_md5_update(md5, salt, strlen(salt));
1539  av_md5_update(md5, rt->password, strlen(rt->password));
1540  av_md5_final(md5, hash);
1541  av_base64_encode(hashstr, sizeof(hashstr), hash,
1542  sizeof(hash));
1543  av_md5_init(md5);
1544  av_md5_update(md5, hashstr, strlen(hashstr));
1545  if (opaque)
1546  av_md5_update(md5, opaque, strlen(opaque));
1547  else if (challenge)
1548  av_md5_update(md5, challenge, strlen(challenge));
1549  av_md5_update(md5, challenge2, strlen(challenge2));
1550  av_md5_final(md5, hash);
1551  av_base64_encode(hashstr, sizeof(hashstr), hash,
1552  sizeof(hash));
1553  snprintf(rt->auth_params, sizeof(rt->auth_params),
1554  "?authmod=%s&user=%s&challenge=%s&response=%s",
1555  "adobe", user, challenge2, hashstr);
1556  if (opaque)
1557  av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1558  "&opaque=%s", opaque);
1559 
1560  av_free(md5);
1561  return 0;
1562 }
1563 
1564 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1565 {
1566  uint8_t hash[16];
1567  char hashstr1[33], hashstr2[33];
1568  const char *realm = "live";
1569  const char *method = "publish";
1570  const char *qop = "auth";
1571  const char *nc = "00000001";
1572  char cnonce[10];
1573  struct AVMD5 *md5 = av_md5_alloc();
1574  if (!md5)
1575  return AVERROR(ENOMEM);
1576 
1577  snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1578 
1579  av_md5_init(md5);
1580  av_md5_update(md5, user, strlen(user));
1581  av_md5_update(md5, ":", 1);
1582  av_md5_update(md5, realm, strlen(realm));
1583  av_md5_update(md5, ":", 1);
1584  av_md5_update(md5, rt->password, strlen(rt->password));
1585  av_md5_final(md5, hash);
1586  ff_data_to_hex(hashstr1, hash, 16, 1);
1587  hashstr1[32] = '\0';
1588 
1589  av_md5_init(md5);
1590  av_md5_update(md5, method, strlen(method));
1591  av_md5_update(md5, ":/", 2);
1592  av_md5_update(md5, rt->app, strlen(rt->app));
1593  av_md5_final(md5, hash);
1594  ff_data_to_hex(hashstr2, hash, 16, 1);
1595  hashstr2[32] = '\0';
1596 
1597  av_md5_init(md5);
1598  av_md5_update(md5, hashstr1, strlen(hashstr1));
1599  av_md5_update(md5, ":", 1);
1600  if (nonce)
1601  av_md5_update(md5, nonce, strlen(nonce));
1602  av_md5_update(md5, ":", 1);
1603  av_md5_update(md5, nc, strlen(nc));
1604  av_md5_update(md5, ":", 1);
1605  av_md5_update(md5, cnonce, strlen(cnonce));
1606  av_md5_update(md5, ":", 1);
1607  av_md5_update(md5, qop, strlen(qop));
1608  av_md5_update(md5, ":", 1);
1609  av_md5_update(md5, hashstr2, strlen(hashstr2));
1610  av_md5_final(md5, hash);
1611  ff_data_to_hex(hashstr1, hash, 16, 1);
1612 
1613  snprintf(rt->auth_params, sizeof(rt->auth_params),
1614  "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1615  "llnw", user, nonce, cnonce, nc, hashstr1);
1616 
1617  av_free(md5);
1618  return 0;
1619 }
1620 
1621 static int handle_connect_error(URLContext *s, const char *desc)
1622 {
1623  RTMPContext *rt = s->priv_data;
1624  char buf[300], *ptr, authmod[15];
1625  int i = 0, ret = 0;
1626  const char *user = "", *salt = "", *opaque = NULL,
1627  *challenge = NULL, *cptr = NULL, *nonce = NULL;
1628 
1629  if (!(cptr = strstr(desc, "authmod=adobe")) &&
1630  !(cptr = strstr(desc, "authmod=llnw"))) {
1631  av_log(s, AV_LOG_ERROR,
1632  "Unknown connect error (unsupported authentication method?)\n");
1633  return AVERROR_UNKNOWN;
1634  }
1635  cptr += strlen("authmod=");
1636  while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1637  authmod[i++] = *cptr++;
1638  authmod[i] = '\0';
1639 
1640  if (!rt->username[0] || !rt->password[0]) {
1641  av_log(s, AV_LOG_ERROR, "No credentials set\n");
1642  return AVERROR_UNKNOWN;
1643  }
1644 
1645  if (strstr(desc, "?reason=authfailed")) {
1646  av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1647  return AVERROR_UNKNOWN;
1648  } else if (strstr(desc, "?reason=nosuchuser")) {
1649  av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1650  return AVERROR_UNKNOWN;
1651  }
1652 
1653  if (rt->auth_tried) {
1654  av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1655  return AVERROR_UNKNOWN;
1656  }
1657 
1658  rt->auth_params[0] = '\0';
1659 
1660  if (strstr(desc, "code=403 need auth")) {
1661  snprintf(rt->auth_params, sizeof(rt->auth_params),
1662  "?authmod=%s&user=%s", authmod, rt->username);
1663  return 0;
1664  }
1665 
1666  if (!(cptr = strstr(desc, "?reason=needauth"))) {
1667  av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1668  return AVERROR_UNKNOWN;
1669  }
1670 
1671  av_strlcpy(buf, cptr + 1, sizeof(buf));
1672  ptr = buf;
1673 
1674  while (ptr) {
1675  char *next = strchr(ptr, '&');
1676  char *value = strchr(ptr, '=');
1677  if (next)
1678  *next++ = '\0';
1679  if (value)
1680  *value++ = '\0';
1681  if (!strcmp(ptr, "user")) {
1682  user = value;
1683  } else if (!strcmp(ptr, "salt")) {
1684  salt = value;
1685  } else if (!strcmp(ptr, "opaque")) {
1686  opaque = value;
1687  } else if (!strcmp(ptr, "challenge")) {
1688  challenge = value;
1689  } else if (!strcmp(ptr, "nonce")) {
1690  nonce = value;
1691  }
1692  ptr = next;
1693  }
1694 
1695  if (!strcmp(authmod, "adobe")) {
1696  if ((ret = do_adobe_auth(rt, user, salt, challenge, opaque)) < 0)
1697  return ret;
1698  } else {
1699  if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1700  return ret;
1701  }
1702 
1703  rt->auth_tried = 1;
1704  return 0;
1705 }
1706 
1708 {
1709  RTMPContext *rt = s->priv_data;
1710  const uint8_t *data_end = pkt->data + pkt->data_size;
1711  char *tracked_method = NULL;
1712  int level = AV_LOG_ERROR;
1713  uint8_t tmpstr[256];
1714  int ret;
1715 
1716  if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1717  return ret;
1718 
1719  if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1720  "description", tmpstr, sizeof(tmpstr))) {
1721  if (tracked_method && (!strcmp(tracked_method, "_checkbw") ||
1722  !strcmp(tracked_method, "releaseStream") ||
1723  !strcmp(tracked_method, "FCSubscribe") ||
1724  !strcmp(tracked_method, "FCPublish"))) {
1725  /* Gracefully ignore Adobe-specific historical artifact errors. */
1726  level = AV_LOG_WARNING;
1727  ret = 0;
1728  } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1729  ret = handle_connect_error(s, tmpstr);
1730  if (!ret) {
1731  rt->do_reconnect = 1;
1732  level = AV_LOG_VERBOSE;
1733  }
1734  } else
1735  ret = AVERROR_UNKNOWN;
1736  av_log(s, level, "Server error: %s\n", tmpstr);
1737  }
1738 
1739  av_free(tracked_method);
1740  return ret;
1741 }
1742 
1744 {
1745  RTMPContext *rt = s->priv_data;
1746  double seqnum;
1747  char filename[64];
1748  char command[64];
1749  char statusmsg[128];
1750  int stringlen;
1751  char *pchar;
1752  const uint8_t *p = pkt->data;
1753  uint8_t *pp = NULL;
1754  RTMPPacket spkt = { 0 };
1755  GetByteContext gbc;
1756  int ret;
1757 
1758  bytestream2_init(&gbc, p, pkt->data_size);
1759  if (ff_amf_read_string(&gbc, command, sizeof(command),
1760  &stringlen)) {
1761  av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1762  return AVERROR_INVALIDDATA;
1763  }
1764 
1765  ret = ff_amf_read_number(&gbc, &seqnum);
1766  if (ret)
1767  return ret;
1768  ret = ff_amf_read_null(&gbc);
1769  if (ret)
1770  return ret;
1771  if (!strcmp(command, "FCPublish") ||
1772  !strcmp(command, "publish")) {
1773  ret = ff_amf_read_string(&gbc, filename,
1774  sizeof(filename), &stringlen);
1775  // check with url
1776  if (s->filename) {
1777  pchar = strrchr(s->filename, '/');
1778  if (!pchar) {
1780  "Unable to find / in url %s, bad format\n",
1781  s->filename);
1782  pchar = s->filename;
1783  }
1784  pchar++;
1785  if (strcmp(pchar, filename))
1786  av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1787  " %s\n", filename, pchar);
1788  }
1789  rt->state = STATE_RECEIVING;
1790  }
1791 
1792  if (!strcmp(command, "FCPublish")) {
1793  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1794  RTMP_PT_INVOKE, 0,
1795  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1796  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1797  return ret;
1798  }
1799  pp = spkt.data;
1800  ff_amf_write_string(&pp, "onFCPublish");
1801  } else if (!strcmp(command, "publish")) {
1802  PutByteContext pbc;
1803  // Send Stream Begin 1
1804  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1805  RTMP_PT_PING, 0, 6)) < 0) {
1806  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1807  return ret;
1808  }
1809  pp = spkt.data;
1810  bytestream2_init_writer(&pbc, pp, spkt.data_size);
1811  bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
1812  bytestream2_put_be32(&pbc, rt->nb_streamid);
1813  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1814  rt->prev_pkt[1]);
1815  ff_rtmp_packet_destroy(&spkt);
1816  if (ret < 0)
1817  return ret;
1818 
1819  // Send onStatus(NetStream.Publish.Start)
1820  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1821  RTMP_PT_INVOKE, 0,
1822  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1823  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1824  return ret;
1825  }
1826  spkt.extra = pkt->extra;
1827  pp = spkt.data;
1828  ff_amf_write_string(&pp, "onStatus");
1829  ff_amf_write_number(&pp, 0);
1830  ff_amf_write_null(&pp);
1831 
1833  ff_amf_write_field_name(&pp, "level");
1834  ff_amf_write_string(&pp, "status");
1835  ff_amf_write_field_name(&pp, "code");
1836  ff_amf_write_string(&pp, "NetStream.Publish.Start");
1837  ff_amf_write_field_name(&pp, "description");
1838  snprintf(statusmsg, sizeof(statusmsg),
1839  "%s is now published", filename);
1840  ff_amf_write_string(&pp, statusmsg);
1841  ff_amf_write_field_name(&pp, "details");
1842  ff_amf_write_string(&pp, filename);
1843  ff_amf_write_field_name(&pp, "clientid");
1844  snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1845  ff_amf_write_string(&pp, statusmsg);
1847 
1848  } else {
1849  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1850  RTMP_PT_INVOKE, 0,
1851  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1852  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1853  return ret;
1854  }
1855  pp = spkt.data;
1856  ff_amf_write_string(&pp, "_result");
1857  ff_amf_write_number(&pp, seqnum);
1858  ff_amf_write_null(&pp);
1859  if (!strcmp(command, "createStream")) {
1860  rt->nb_streamid++;
1861  if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1862  rt->nb_streamid++; /* Values 0 and 2 are reserved */
1863  ff_amf_write_number(&pp, rt->nb_streamid);
1864  /* By now we don't control which streams are removed in
1865  * deleteStream. There is no stream creation control
1866  * if a client creates more than 2^32 - 2 streams. */
1867  }
1868  }
1869  spkt.data_size = pp - spkt.data;
1870  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1871  rt->prev_pkt[1]);
1872  ff_rtmp_packet_destroy(&spkt);
1873  return ret;
1874 }
1875 
1877 {
1878  RTMPContext *rt = s->priv_data;
1879  char *tracked_method = NULL;
1880  int ret = 0;
1881 
1882  if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1883  return ret;
1884 
1885  if (!tracked_method) {
1886  /* Ignore this reply when the current method is not tracked. */
1887  return ret;
1888  }
1889 
1890  if (!memcmp(tracked_method, "connect", 7)) {
1891  if (!rt->is_input) {
1892  if ((ret = gen_release_stream(s, rt)) < 0)
1893  goto fail;
1894 
1895  if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1896  goto fail;
1897  } else {
1898  if ((ret = gen_server_bw(s, rt)) < 0)
1899  goto fail;
1900  }
1901 
1902  if ((ret = gen_create_stream(s, rt)) < 0)
1903  goto fail;
1904 
1905  if (rt->is_input) {
1906  /* Send the FCSubscribe command when the name of live
1907  * stream is defined by the user or if it's a live stream. */
1908  if (rt->subscribe) {
1909  if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1910  goto fail;
1911  } else if (rt->live == -1) {
1912  if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1913  goto fail;
1914  }
1915  }
1916  } else if (!memcmp(tracked_method, "createStream", 12)) {
1917  //extract a number from the result
1918  if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1919  av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1920  } else {
1921  rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1922  }
1923 
1924  if (!rt->is_input) {
1925  if ((ret = gen_publish(s, rt)) < 0)
1926  goto fail;
1927  } else {
1928  if ((ret = gen_play(s, rt)) < 0)
1929  goto fail;
1930  if ((ret = gen_buffer_time(s, rt)) < 0)
1931  goto fail;
1932  }
1933  }
1934 
1935 fail:
1936  av_free(tracked_method);
1937  return ret;
1938 }
1939 
1941 {
1942  RTMPContext *rt = s->priv_data;
1943  const uint8_t *data_end = pkt->data + pkt->data_size;
1944  const uint8_t *ptr = pkt->data + 11;
1945  uint8_t tmpstr[256];
1946  int i, t;
1947 
1948  for (i = 0; i < 2; i++) {
1949  t = ff_amf_tag_size(ptr, data_end);
1950  if (t < 0)
1951  return 1;
1952  ptr += t;
1953  }
1954 
1955  t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
1956  if (!t && !strcmp(tmpstr, "error")) {
1957  if (!ff_amf_get_field_value(ptr, data_end,
1958  "description", tmpstr, sizeof(tmpstr)))
1959  av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1960  return -1;
1961  }
1962 
1963  t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
1964  if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1965  if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1966  if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1967  if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1968 
1969  return 0;
1970 }
1971 
1973 {
1974  RTMPContext *rt = s->priv_data;
1975  int ret = 0;
1976 
1977  //TODO: check for the messages sent for wrong state?
1978  if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
1979  if ((ret = handle_invoke_error(s, pkt)) < 0)
1980  return ret;
1981  } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
1982  if ((ret = handle_invoke_result(s, pkt)) < 0)
1983  return ret;
1984  } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1985  if ((ret = handle_invoke_status(s, pkt)) < 0)
1986  return ret;
1987  } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1988  if ((ret = gen_check_bw(s, rt)) < 0)
1989  return ret;
1990  } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) ||
1991  !memcmp(pkt->data, "\002\000\011FCPublish", 12) ||
1992  !memcmp(pkt->data, "\002\000\007publish", 10) ||
1993  !memcmp(pkt->data, "\002\000\010_checkbw", 11) ||
1994  !memcmp(pkt->data, "\002\000\014createStream", 15)) {
1995  if (ret = send_invoke_response(s, pkt) < 0)
1996  return ret;
1997  }
1998 
1999  return ret;
2000 }
2001 
2002 static int handle_notify(URLContext *s, RTMPPacket *pkt) {
2003  RTMPContext *rt = s->priv_data;
2004  const uint8_t *p = NULL;
2005  uint8_t *cp = NULL;
2006  uint8_t commandbuffer[64];
2007  char statusmsg[128];
2008  int stringlen;
2009  GetByteContext gbc;
2010  PutByteContext pbc;
2011  uint32_t ts;
2012  int old_flv_size;
2013  const uint8_t *datatowrite;
2014  unsigned datatowritelength;
2015 
2016  p = pkt->data;
2017  bytestream2_init(&gbc, p, pkt->data_size);
2018  if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2019  &stringlen))
2020  return AVERROR_INVALIDDATA;
2021  if (!strcmp(commandbuffer, "@setDataFrame")) {
2022  datatowrite = gbc.buffer;
2023  datatowritelength = bytestream2_get_bytes_left(&gbc);
2024  if (ff_amf_read_string(&gbc, statusmsg,
2025  sizeof(statusmsg), &stringlen))
2026  return AVERROR_INVALIDDATA;
2027  if (strcmp(statusmsg, "onMetaData")) {
2028  av_log(s, AV_LOG_INFO, "Expecting onMetadata but got %s\n",
2029  statusmsg);
2030  return 0;
2031  }
2032 
2033  /* Provide ECMAArray to flv */
2034  ts = pkt->timestamp;
2035 
2036  // generate packet header and put data into buffer for FLV demuxer
2037  if (rt->flv_off < rt->flv_size) {
2038  old_flv_size = rt->flv_size;
2039  rt->flv_size += datatowritelength + 15;
2040  } else {
2041  old_flv_size = 0;
2042  rt->flv_size = datatowritelength + 15;
2043  rt->flv_off = 0;
2044  }
2045 
2046  cp = av_realloc(rt->flv_data, rt->flv_size);
2047  if (!cp)
2048  return AVERROR(ENOMEM);
2049  rt->flv_data = cp;
2050  bytestream2_init_writer(&pbc, cp, rt->flv_size);
2051  bytestream2_skip_p(&pbc, old_flv_size);
2052  bytestream2_put_byte(&pbc, pkt->type);
2053  bytestream2_put_be24(&pbc, datatowritelength);
2054  bytestream2_put_be24(&pbc, ts);
2055  bytestream2_put_byte(&pbc, ts >> 24);
2056  bytestream2_put_be24(&pbc, 0);
2057  bytestream2_put_buffer(&pbc, datatowrite, datatowritelength);
2058  bytestream2_put_be32(&pbc, 0);
2059  }
2060  return 0;
2061 }
2062 
2070 {
2071  int ret;
2072 
2073 #ifdef DEBUG
2074  ff_rtmp_packet_dump(s, pkt);
2075 #endif
2076 
2077  switch (pkt->type) {
2078  case RTMP_PT_BYTES_READ:
2079  av_dlog(s, "received bytes read report\n");
2080  break;
2081  case RTMP_PT_CHUNK_SIZE:
2082  if ((ret = handle_chunk_size(s, pkt)) < 0)
2083  return ret;
2084  break;
2085  case RTMP_PT_PING:
2086  if ((ret = handle_ping(s, pkt)) < 0)
2087  return ret;
2088  break;
2089  case RTMP_PT_CLIENT_BW:
2090  if ((ret = handle_client_bw(s, pkt)) < 0)
2091  return ret;
2092  break;
2093  case RTMP_PT_SERVER_BW:
2094  if ((ret = handle_server_bw(s, pkt)) < 0)
2095  return ret;
2096  break;
2097  case RTMP_PT_INVOKE:
2098  if ((ret = handle_invoke(s, pkt)) < 0)
2099  return ret;
2100  break;
2101  case RTMP_PT_VIDEO:
2102  case RTMP_PT_AUDIO:
2103  case RTMP_PT_METADATA:
2104  case RTMP_PT_NOTIFY:
2105  /* Audio, Video and Metadata packets are parsed in get_packet() */
2106  break;
2107  default:
2108  av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2109  break;
2110  }
2111  return 0;
2112 }
2113 
2125 static int get_packet(URLContext *s, int for_header)
2126 {
2127  RTMPContext *rt = s->priv_data;
2128  int ret;
2129  uint8_t *p;
2130  const uint8_t *next;
2131  uint32_t data_size;
2132  uint32_t ts, cts, pts=0;
2133 
2134  if (rt->state == STATE_STOPPED)
2135  return AVERROR_EOF;
2136 
2137  for (;;) {
2138  RTMPPacket rpkt = { 0 };
2139  if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2140  rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
2141  if (ret == 0) {
2142  return AVERROR(EAGAIN);
2143  } else {
2144  return AVERROR(EIO);
2145  }
2146  }
2147  rt->bytes_read += ret;
2148  if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
2149  av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2150  if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2151  return ret;
2152  rt->last_bytes_read = rt->bytes_read;
2153  }
2154 
2155  ret = rtmp_parse_result(s, rt, &rpkt);
2156  if (ret < 0) {//serious error in current packet
2157  ff_rtmp_packet_destroy(&rpkt);
2158  return ret;
2159  }
2160  if (rt->do_reconnect && for_header) {
2161  ff_rtmp_packet_destroy(&rpkt);
2162  return 0;
2163  }
2164  if (rt->state == STATE_STOPPED) {
2165  ff_rtmp_packet_destroy(&rpkt);
2166  return AVERROR_EOF;
2167  }
2168  if (for_header && (rt->state == STATE_PLAYING ||
2169  rt->state == STATE_PUBLISHING ||
2170  rt->state == STATE_RECEIVING)) {
2171  ff_rtmp_packet_destroy(&rpkt);
2172  return 0;
2173  }
2174  if (!rpkt.data_size || !rt->is_input) {
2175  ff_rtmp_packet_destroy(&rpkt);
2176  continue;
2177  }
2178  if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
2179  (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
2180  ts = rpkt.timestamp;
2181 
2182  // generate packet header and put data into buffer for FLV demuxer
2183  rt->flv_off = 0;
2184  rt->flv_size = rpkt.data_size + 15;
2185  rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
2186  bytestream_put_byte(&p, rpkt.type);
2187  bytestream_put_be24(&p, rpkt.data_size);
2188  bytestream_put_be24(&p, ts);
2189  bytestream_put_byte(&p, ts >> 24);
2190  bytestream_put_be24(&p, 0);
2191  bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
2192  bytestream_put_be32(&p, 0);
2193  ff_rtmp_packet_destroy(&rpkt);
2194  return 0;
2195  } else if (rpkt.type == RTMP_PT_NOTIFY) {
2196  ret = handle_notify(s, &rpkt);
2197  ff_rtmp_packet_destroy(&rpkt);
2198  if (ret) {
2199  av_log(s, AV_LOG_ERROR, "Handle notify error\n");
2200  return ret;
2201  }
2202  return 0;
2203  } else if (rpkt.type == RTMP_PT_METADATA) {
2204  // we got raw FLV data, make it available for FLV demuxer
2205  rt->flv_off = 0;
2206  rt->flv_size = rpkt.data_size;
2207  rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2208  /* rewrite timestamps */
2209  next = rpkt.data;
2210  ts = rpkt.timestamp;
2211  while (next - rpkt.data < rpkt.data_size - 11) {
2212  next++;
2213  data_size = bytestream_get_be24(&next);
2214  p=next;
2215  cts = bytestream_get_be24(&next);
2216  cts |= bytestream_get_byte(&next) << 24;
2217  if (pts==0)
2218  pts=cts;
2219  ts += cts - pts;
2220  pts = cts;
2221  bytestream_put_be24(&p, ts);
2222  bytestream_put_byte(&p, ts >> 24);
2223  next += data_size + 3 + 4;
2224  }
2225  memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
2226  ff_rtmp_packet_destroy(&rpkt);
2227  return 0;
2228  }
2229  ff_rtmp_packet_destroy(&rpkt);
2230  }
2231 }
2232 
2233 static int rtmp_close(URLContext *h)
2234 {
2235  RTMPContext *rt = h->priv_data;
2236  int ret = 0;
2237 
2238  if (!rt->is_input) {
2239  rt->flv_data = NULL;
2240  if (rt->out_pkt.data_size)
2242  if (rt->state > STATE_FCPUBLISH)
2243  ret = gen_fcunpublish_stream(h, rt);
2244  }
2245  if (rt->state > STATE_HANDSHAKED)
2246  ret = gen_delete_stream(h, rt);
2247 
2249  av_freep(&rt->flv_data);
2250  ffurl_close(rt->stream);
2251  return ret;
2252 }
2253 
2263 static int rtmp_open(URLContext *s, const char *uri, int flags)
2264 {
2265  RTMPContext *rt = s->priv_data;
2266  char proto[8], hostname[256], path[1024], auth[100], *fname;
2267  char *old_app;
2268  uint8_t buf[2048];
2269  int port;
2270  AVDictionary *opts = NULL;
2271  int ret;
2272 
2273  if (rt->listen_timeout > 0)
2274  rt->listen = 1;
2275 
2276  rt->is_input = !(flags & AVIO_FLAG_WRITE);
2277 
2278  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2279  hostname, sizeof(hostname), &port,
2280  path, sizeof(path), s->filename);
2281 
2282  if (auth[0]) {
2283  char *ptr = strchr(auth, ':');
2284  if (ptr) {
2285  *ptr = '\0';
2286  av_strlcpy(rt->username, auth, sizeof(rt->username));
2287  av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2288  }
2289  }
2290 
2291  if (rt->listen && strcmp(proto, "rtmp")) {
2292  av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2293  proto);
2294  return AVERROR(EINVAL);
2295  }
2296  if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2297  if (!strcmp(proto, "rtmpts"))
2298  av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2299 
2300  /* open the http tunneling connection */
2301  ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2302  } else if (!strcmp(proto, "rtmps")) {
2303  /* open the tls connection */
2304  if (port < 0)
2305  port = RTMPS_DEFAULT_PORT;
2306  ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2307  } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2308  if (!strcmp(proto, "rtmpte"))
2309  av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2310 
2311  /* open the encrypted connection */
2312  ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2313  rt->encrypted = 1;
2314  } else {
2315  /* open the tcp connection */
2316  if (port < 0)
2317  port = RTMP_DEFAULT_PORT;
2318  if (rt->listen)
2319  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2320  "?listen&listen_timeout=%d",
2321  rt->listen_timeout * 1000);
2322  else
2323  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2324  }
2325 
2326 reconnect:
2327  if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2328  &s->interrupt_callback, &opts)) < 0) {
2329  av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2330  goto fail;
2331  }
2332 
2333  if (rt->swfverify) {
2334  if ((ret = rtmp_calc_swfhash(s)) < 0)
2335  goto fail;
2336  }
2337 
2338  rt->state = STATE_START;
2339  if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2340  goto fail;
2341  if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2342  goto fail;
2343 
2344  rt->out_chunk_size = 128;
2345  rt->in_chunk_size = 128; // Probably overwritten later
2346  rt->state = STATE_HANDSHAKED;
2347 
2348  // Keep the application name when it has been defined by the user.
2349  old_app = rt->app;
2350 
2351  rt->app = av_malloc(APP_MAX_LENGTH);
2352  if (!rt->app) {
2353  ret = AVERROR(ENOMEM);
2354  goto fail;
2355  }
2356 
2357  //extract "app" part from path
2358  if (!strncmp(path, "/ondemand/", 10)) {
2359  fname = path + 10;
2360  memcpy(rt->app, "ondemand", 9);
2361  } else {
2362  char *next = *path ? path + 1 : path;
2363  char *p = strchr(next, '/');
2364  if (!p) {
2365  fname = next;
2366  rt->app[0] = '\0';
2367  } else {
2368  // make sure we do not mismatch a playpath for an application instance
2369  char *c = strchr(p + 1, ':');
2370  fname = strchr(p + 1, '/');
2371  if (!fname || (c && c < fname)) {
2372  fname = p + 1;
2373  av_strlcpy(rt->app, path + 1, p - path);
2374  } else {
2375  fname++;
2376  av_strlcpy(rt->app, path + 1, fname - path - 1);
2377  }
2378  }
2379  }
2380 
2381  if (old_app) {
2382  // The name of application has been defined by the user, override it.
2383  av_free(rt->app);
2384  rt->app = old_app;
2385  }
2386 
2387  if (!rt->playpath) {
2388  int len = strlen(fname);
2389 
2391  if (!rt->playpath) {
2392  ret = AVERROR(ENOMEM);
2393  goto fail;
2394  }
2395 
2396  if (!strchr(fname, ':') && len >= 4 &&
2397  (!strcmp(fname + len - 4, ".f4v") ||
2398  !strcmp(fname + len - 4, ".mp4"))) {
2399  memcpy(rt->playpath, "mp4:", 5);
2400  } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
2401  fname[len - 4] = '\0';
2402  } else {
2403  rt->playpath[0] = 0;
2404  }
2406  }
2407 
2408  if (!rt->tcurl) {
2410  if (!rt->tcurl) {
2411  ret = AVERROR(ENOMEM);
2412  goto fail;
2413  }
2414  ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2415  port, "/%s", rt->app);
2416  }
2417 
2418  if (!rt->flashver) {
2420  if (!rt->flashver) {
2421  ret = AVERROR(ENOMEM);
2422  goto fail;
2423  }
2424  if (rt->is_input) {
2425  snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2428  } else {
2429  snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2430  "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2431  }
2432  }
2433 
2434  rt->client_report_size = 1048576;
2435  rt->bytes_read = 0;
2436  rt->last_bytes_read = 0;
2437  rt->server_bw = 2500000;
2438 
2439  av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2440  proto, path, rt->app, rt->playpath);
2441  if (!rt->listen) {
2442  if ((ret = gen_connect(s, rt)) < 0)
2443  goto fail;
2444  } else {
2445  if (read_connect(s, s->priv_data) < 0)
2446  goto fail;
2447  rt->is_input = 1;
2448  }
2449 
2450  do {
2451  ret = get_packet(s, 1);
2452  } while (ret == EAGAIN);
2453  if (ret < 0)
2454  goto fail;
2455 
2456  if (rt->do_reconnect) {
2457  ffurl_close(rt->stream);
2458  rt->stream = NULL;
2459  rt->do_reconnect = 0;
2460  rt->nb_invokes = 0;
2461  memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
2463  goto reconnect;
2464  }
2465 
2466  if (rt->is_input) {
2467  // generate FLV header for demuxer
2468  rt->flv_size = 13;
2469  rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2470  rt->flv_off = 0;
2471  memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2472  } else {
2473  rt->flv_size = 0;
2474  rt->flv_data = NULL;
2475  rt->flv_off = 0;
2476  rt->skip_bytes = 13;
2477  }
2478 
2480  s->is_streamed = 1;
2481  return 0;
2482 
2483 fail:
2484  av_dict_free(&opts);
2485  rtmp_close(s);
2486  return ret;
2487 }
2488 
2489 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2490 {
2491  RTMPContext *rt = s->priv_data;
2492  int orig_size = size;
2493  int ret;
2494 
2495  while (size > 0) {
2496  int data_left = rt->flv_size - rt->flv_off;
2497 
2498  if (data_left >= size) {
2499  memcpy(buf, rt->flv_data + rt->flv_off, size);
2500  rt->flv_off += size;
2501  return orig_size;
2502  }
2503  if (data_left > 0) {
2504  memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2505  buf += data_left;
2506  size -= data_left;
2507  rt->flv_off = rt->flv_size;
2508  return data_left;
2509  }
2510  if ((ret = get_packet(s, 0)) < 0)
2511  return ret;
2512  }
2513  return orig_size;
2514 }
2515 
2516 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2517 {
2518  RTMPContext *rt = s->priv_data;
2519  int size_temp = size;
2520  int pktsize, pkttype;
2521  uint32_t ts;
2522  const uint8_t *buf_temp = buf;
2523  uint8_t c;
2524  int ret;
2525 
2526  do {
2527  if (rt->skip_bytes) {
2528  int skip = FFMIN(rt->skip_bytes, size_temp);
2529  buf_temp += skip;
2530  size_temp -= skip;
2531  rt->skip_bytes -= skip;
2532  continue;
2533  }
2534 
2535  if (rt->flv_header_bytes < 11) {
2536  const uint8_t *header = rt->flv_header;
2537  int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
2538  bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2539  rt->flv_header_bytes += copy;
2540  size_temp -= copy;
2541  if (rt->flv_header_bytes < 11)
2542  break;
2543 
2544  pkttype = bytestream_get_byte(&header);
2545  pktsize = bytestream_get_be24(&header);
2546  ts = bytestream_get_be24(&header);
2547  ts |= bytestream_get_byte(&header) << 24;
2548  bytestream_get_be24(&header);
2549  rt->flv_size = pktsize;
2550 
2551  //force 12bytes header
2552  if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2553  pkttype == RTMP_PT_NOTIFY) {
2554  if (pkttype == RTMP_PT_NOTIFY)
2555  pktsize += 16;
2557  }
2558 
2559  //this can be a big packet, it's better to send it right here
2561  pkttype, ts, pktsize)) < 0)
2562  return ret;
2563 
2564  rt->out_pkt.extra = rt->main_channel_id;
2565  rt->flv_data = rt->out_pkt.data;
2566 
2567  if (pkttype == RTMP_PT_NOTIFY)
2568  ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2569  }
2570 
2571  if (rt->flv_size - rt->flv_off > size_temp) {
2572  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2573  rt->flv_off += size_temp;
2574  size_temp = 0;
2575  } else {
2576  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2577  size_temp -= rt->flv_size - rt->flv_off;
2578  rt->flv_off += rt->flv_size - rt->flv_off;
2579  }
2580 
2581  if (rt->flv_off == rt->flv_size) {
2582  rt->skip_bytes = 4;
2583 
2584  if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2585  return ret;
2586  rt->flv_size = 0;
2587  rt->flv_off = 0;
2588  rt->flv_header_bytes = 0;
2589  rt->flv_nb_packets++;
2590  }
2591  } while (buf_temp - buf < size);
2592 
2593  if (rt->flv_nb_packets < rt->flush_interval)
2594  return size;
2595  rt->flv_nb_packets = 0;
2596 
2597  /* set stream into nonblocking mode */
2599 
2600  /* try to read one byte from the stream */
2601  ret = ffurl_read(rt->stream, &c, 1);
2602 
2603  /* switch the stream back into blocking mode */
2604  rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2605 
2606  if (ret == AVERROR(EAGAIN)) {
2607  /* no incoming data to handle */
2608  return size;
2609  } else if (ret < 0) {
2610  return ret;
2611  } else if (ret == 1) {
2612  RTMPPacket rpkt = { 0 };
2613 
2614  if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2615  rt->in_chunk_size,
2616  rt->prev_pkt[0], c)) <= 0)
2617  return ret;
2618 
2619  if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2620  return ret;
2621 
2622  ff_rtmp_packet_destroy(&rpkt);
2623  }
2624 
2625  return size;
2626 }
2627 
2628 #define OFFSET(x) offsetof(RTMPContext, x)
2629 #define DEC AV_OPT_FLAG_DECODING_PARAM
2630 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2631 
2632 static const AVOption rtmp_options[] = {
2633  {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2634  {"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},
2635  {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2636  {"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},
2637  {"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},
2638  {"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"},
2639  {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2640  {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2641  {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2642  {"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},
2643  {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2644  {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2645  {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2646  {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2647  {"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},
2648  {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2649  {"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},
2650  {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2651  {"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" },
2652  { NULL },
2653 };
2654 
2655 #define RTMP_PROTOCOL(flavor) \
2656 static const AVClass flavor##_class = { \
2657  .class_name = #flavor, \
2658  .item_name = av_default_item_name, \
2659  .option = rtmp_options, \
2660  .version = LIBAVUTIL_VERSION_INT, \
2661 }; \
2662  \
2663 URLProtocol ff_##flavor##_protocol = { \
2664  .name = #flavor, \
2665  .url_open = rtmp_open, \
2666  .url_read = rtmp_read, \
2667  .url_write = rtmp_write, \
2668  .url_close = rtmp_close, \
2669  .priv_data_size = sizeof(RTMPContext), \
2670  .flags = URL_PROTOCOL_FLAG_NETWORK, \
2671  .priv_data_class= &flavor##_class, \
2672 };
2673 
2674 
2675 RTMP_PROTOCOL(rtmp)
2676 RTMP_PROTOCOL(rtmpe)
2677 RTMP_PROTOCOL(rtmps)
2678 RTMP_PROTOCOL(rtmpt)
2679 RTMP_PROTOCOL(rtmpte)
2680 RTMP_PROTOCOL(rtmpts)