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->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->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.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.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.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.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.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.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->size < 6) {
749  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
750  ppkt->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->size < 4) {
1425  av_log(s, AV_LOG_ERROR,
1426  "Too short chunk size change packet (%d)\n",
1427  pkt->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->size < 2) {
1458  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1459  pkt->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->size < 4) {
1484  av_log(s, AV_LOG_ERROR,
1485  "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1486  pkt->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->size < 4) {
1508  av_log(s, AV_LOG_ERROR,
1509  "Too short server bandwidth report packet (%d)\n",
1510  pkt->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->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->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.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.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 (!strcmp(tracked_method, "connect")) {
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 (!strcmp(tracked_method, "createStream")) {
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->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 (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
1979  if ((ret = handle_invoke_error(s, pkt)) < 0)
1980  return ret;
1981  } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
1982  if ((ret = handle_invoke_result(s, pkt)) < 0)
1983  return ret;
1984  } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
1985  if ((ret = handle_invoke_status(s, pkt)) < 0)
1986  return ret;
1987  } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
1988  if ((ret = gen_check_bw(s, rt)) < 0)
1989  return ret;
1990  } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
1991  ff_amf_match_string(pkt->data, pkt->size, "FCPublish") ||
1992  ff_amf_match_string(pkt->data, pkt->size, "publish") ||
1993  ff_amf_match_string(pkt->data, pkt->size, "_checkbw") ||
1994  ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
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->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 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.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 &&
2180  ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) {
2181  ts = rpkt.timestamp;
2182 
2183  // generate packet header and put data into buffer for FLV demuxer
2184  rt->flv_off = 0;
2185  rt->flv_size = rpkt.size + 15;
2186  rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
2187  bytestream_put_byte(&p, rpkt.type);
2188  bytestream_put_be24(&p, rpkt.size);
2189  bytestream_put_be24(&p, ts);
2190  bytestream_put_byte(&p, ts >> 24);
2191  bytestream_put_be24(&p, 0);
2192  bytestream_put_buffer(&p, rpkt.data, rpkt.size);
2193  bytestream_put_be32(&p, 0);
2194  ff_rtmp_packet_destroy(&rpkt);
2195  return 0;
2196  } else if (rpkt.type == RTMP_PT_NOTIFY) {
2197  ret = handle_notify(s, &rpkt);
2198  ff_rtmp_packet_destroy(&rpkt);
2199  if (ret) {
2200  av_log(s, AV_LOG_ERROR, "Handle notify error\n");
2201  return ret;
2202  }
2203  return 0;
2204  } else if (rpkt.type == RTMP_PT_METADATA) {
2205  // we got raw FLV data, make it available for FLV demuxer
2206  rt->flv_off = 0;
2207  rt->flv_size = rpkt.size;
2208  rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2209  /* rewrite timestamps */
2210  next = rpkt.data;
2211  ts = rpkt.timestamp;
2212  while (next - rpkt.data < rpkt.size - 11) {
2213  next++;
2214  size = bytestream_get_be24(&next);
2215  p=next;
2216  cts = bytestream_get_be24(&next);
2217  cts |= bytestream_get_byte(&next) << 24;
2218  if (pts==0)
2219  pts=cts;
2220  ts += cts - pts;
2221  pts = cts;
2222  bytestream_put_be24(&p, ts);
2223  bytestream_put_byte(&p, ts >> 24);
2224  next += size + 3 + 4;
2225  }
2226  memcpy(rt->flv_data, rpkt.data, rpkt.size);
2227  ff_rtmp_packet_destroy(&rpkt);
2228  return 0;
2229  }
2230  ff_rtmp_packet_destroy(&rpkt);
2231  }
2232 }
2233 
2234 static int rtmp_close(URLContext *h)
2235 {
2236  RTMPContext *rt = h->priv_data;
2237  int ret = 0;
2238 
2239  if (!rt->is_input) {
2240  rt->flv_data = NULL;
2241  if (rt->out_pkt.size)
2243  if (rt->state > STATE_FCPUBLISH)
2244  ret = gen_fcunpublish_stream(h, rt);
2245  }
2246  if (rt->state > STATE_HANDSHAKED)
2247  ret = gen_delete_stream(h, rt);
2248 
2250  av_freep(&rt->flv_data);
2251  ffurl_close(rt->stream);
2252  return ret;
2253 }
2254 
2264 static int rtmp_open(URLContext *s, const char *uri, int flags)
2265 {
2266  RTMPContext *rt = s->priv_data;
2267  char proto[8], hostname[256], path[1024], auth[100], *fname;
2268  char *old_app;
2269  uint8_t buf[2048];
2270  int port;
2271  AVDictionary *opts = NULL;
2272  int ret;
2273 
2274  if (rt->listen_timeout > 0)
2275  rt->listen = 1;
2276 
2277  rt->is_input = !(flags & AVIO_FLAG_WRITE);
2278 
2279  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2280  hostname, sizeof(hostname), &port,
2281  path, sizeof(path), s->filename);
2282 
2283  if (auth[0]) {
2284  char *ptr = strchr(auth, ':');
2285  if (ptr) {
2286  *ptr = '\0';
2287  av_strlcpy(rt->username, auth, sizeof(rt->username));
2288  av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2289  }
2290  }
2291 
2292  if (rt->listen && strcmp(proto, "rtmp")) {
2293  av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2294  proto);
2295  return AVERROR(EINVAL);
2296  }
2297  if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2298  if (!strcmp(proto, "rtmpts"))
2299  av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2300 
2301  /* open the http tunneling connection */
2302  ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2303  } else if (!strcmp(proto, "rtmps")) {
2304  /* open the tls connection */
2305  if (port < 0)
2306  port = RTMPS_DEFAULT_PORT;
2307  ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2308  } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2309  if (!strcmp(proto, "rtmpte"))
2310  av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2311 
2312  /* open the encrypted connection */
2313  ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2314  rt->encrypted = 1;
2315  } else {
2316  /* open the tcp connection */
2317  if (port < 0)
2318  port = RTMP_DEFAULT_PORT;
2319  if (rt->listen)
2320  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2321  "?listen&listen_timeout=%d",
2322  rt->listen_timeout * 1000);
2323  else
2324  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2325  }
2326 
2327 reconnect:
2328  if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2329  &s->interrupt_callback, &opts)) < 0) {
2330  av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2331  goto fail;
2332  }
2333 
2334  if (rt->swfverify) {
2335  if ((ret = rtmp_calc_swfhash(s)) < 0)
2336  goto fail;
2337  }
2338 
2339  rt->state = STATE_START;
2340  if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2341  goto fail;
2342  if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2343  goto fail;
2344 
2345  rt->out_chunk_size = 128;
2346  rt->in_chunk_size = 128; // Probably overwritten later
2347  rt->state = STATE_HANDSHAKED;
2348 
2349  // Keep the application name when it has been defined by the user.
2350  old_app = rt->app;
2351 
2352  rt->app = av_malloc(APP_MAX_LENGTH);
2353  if (!rt->app) {
2354  ret = AVERROR(ENOMEM);
2355  goto fail;
2356  }
2357 
2358  //extract "app" part from path
2359  if (!strncmp(path, "/ondemand/", 10)) {
2360  fname = path + 10;
2361  memcpy(rt->app, "ondemand", 9);
2362  } else {
2363  char *next = *path ? path + 1 : path;
2364  char *p = strchr(next, '/');
2365  if (!p) {
2366  fname = next;
2367  rt->app[0] = '\0';
2368  } else {
2369  // make sure we do not mismatch a playpath for an application instance
2370  char *c = strchr(p + 1, ':');
2371  fname = strchr(p + 1, '/');
2372  if (!fname || (c && c < fname)) {
2373  fname = p + 1;
2374  av_strlcpy(rt->app, path + 1, p - path);
2375  } else {
2376  fname++;
2377  av_strlcpy(rt->app, path + 1, fname - path - 1);
2378  }
2379  }
2380  }
2381 
2382  if (old_app) {
2383  // The name of application has been defined by the user, override it.
2384  av_free(rt->app);
2385  rt->app = old_app;
2386  }
2387 
2388  if (!rt->playpath) {
2389  int len = strlen(fname);
2390 
2392  if (!rt->playpath) {
2393  ret = AVERROR(ENOMEM);
2394  goto fail;
2395  }
2396 
2397  if (!strchr(fname, ':') && len >= 4 &&
2398  (!strcmp(fname + len - 4, ".f4v") ||
2399  !strcmp(fname + len - 4, ".mp4"))) {
2400  memcpy(rt->playpath, "mp4:", 5);
2401  } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
2402  fname[len - 4] = '\0';
2403  } else {
2404  rt->playpath[0] = 0;
2405  }
2407  }
2408 
2409  if (!rt->tcurl) {
2411  if (!rt->tcurl) {
2412  ret = AVERROR(ENOMEM);
2413  goto fail;
2414  }
2415  ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2416  port, "/%s", rt->app);
2417  }
2418 
2419  if (!rt->flashver) {
2421  if (!rt->flashver) {
2422  ret = AVERROR(ENOMEM);
2423  goto fail;
2424  }
2425  if (rt->is_input) {
2426  snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2429  } else {
2430  snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2431  "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2432  }
2433  }
2434 
2435  rt->client_report_size = 1048576;
2436  rt->bytes_read = 0;
2437  rt->last_bytes_read = 0;
2438  rt->server_bw = 2500000;
2439 
2440  av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2441  proto, path, rt->app, rt->playpath);
2442  if (!rt->listen) {
2443  if ((ret = gen_connect(s, rt)) < 0)
2444  goto fail;
2445  } else {
2446  if ((ret = read_connect(s, s->priv_data)) < 0)
2447  goto fail;
2448  rt->is_input = 1;
2449  }
2450 
2451  do {
2452  ret = get_packet(s, 1);
2453  } while (ret == EAGAIN);
2454  if (ret < 0)
2455  goto fail;
2456 
2457  if (rt->do_reconnect) {
2458  ffurl_close(rt->stream);
2459  rt->stream = NULL;
2460  rt->do_reconnect = 0;
2461  rt->nb_invokes = 0;
2462  memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
2464  goto reconnect;
2465  }
2466 
2467  if (rt->is_input) {
2468  // generate FLV header for demuxer
2469  rt->flv_size = 13;
2470  rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2471  rt->flv_off = 0;
2472  memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2473  } else {
2474  rt->flv_size = 0;
2475  rt->flv_data = NULL;
2476  rt->flv_off = 0;
2477  rt->skip_bytes = 13;
2478  }
2479 
2481  s->is_streamed = 1;
2482  return 0;
2483 
2484 fail:
2485  av_dict_free(&opts);
2486  rtmp_close(s);
2487  return ret;
2488 }
2489 
2490 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2491 {
2492  RTMPContext *rt = s->priv_data;
2493  int orig_size = size;
2494  int ret;
2495 
2496  while (size > 0) {
2497  int data_left = rt->flv_size - rt->flv_off;
2498 
2499  if (data_left >= size) {
2500  memcpy(buf, rt->flv_data + rt->flv_off, size);
2501  rt->flv_off += size;
2502  return orig_size;
2503  }
2504  if (data_left > 0) {
2505  memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2506  buf += data_left;
2507  size -= data_left;
2508  rt->flv_off = rt->flv_size;
2509  return data_left;
2510  }
2511  if ((ret = get_packet(s, 0)) < 0)
2512  return ret;
2513  }
2514  return orig_size;
2515 }
2516 
2517 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2518 {
2519  RTMPContext *rt = s->priv_data;
2520  int size_temp = size;
2521  int pktsize, pkttype;
2522  uint32_t ts;
2523  const uint8_t *buf_temp = buf;
2524  uint8_t c;
2525  int ret;
2526 
2527  do {
2528  if (rt->skip_bytes) {
2529  int skip = FFMIN(rt->skip_bytes, size_temp);
2530  buf_temp += skip;
2531  size_temp -= skip;
2532  rt->skip_bytes -= skip;
2533  continue;
2534  }
2535 
2536  if (rt->flv_header_bytes < 11) {
2537  const uint8_t *header = rt->flv_header;
2538  int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
2539  bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2540  rt->flv_header_bytes += copy;
2541  size_temp -= copy;
2542  if (rt->flv_header_bytes < 11)
2543  break;
2544 
2545  pkttype = bytestream_get_byte(&header);
2546  pktsize = bytestream_get_be24(&header);
2547  ts = bytestream_get_be24(&header);
2548  ts |= bytestream_get_byte(&header) << 24;
2549  bytestream_get_be24(&header);
2550  rt->flv_size = pktsize;
2551 
2552  //force 12bytes header
2553  if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2554  pkttype == RTMP_PT_NOTIFY) {
2555  if (pkttype == RTMP_PT_NOTIFY)
2556  pktsize += 16;
2558  }
2559 
2560  //this can be a big packet, it's better to send it right here
2562  pkttype, ts, pktsize)) < 0)
2563  return ret;
2564 
2565  rt->out_pkt.extra = rt->main_channel_id;
2566  rt->flv_data = rt->out_pkt.data;
2567 
2568  if (pkttype == RTMP_PT_NOTIFY)
2569  ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2570  }
2571 
2572  if (rt->flv_size - rt->flv_off > size_temp) {
2573  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2574  rt->flv_off += size_temp;
2575  size_temp = 0;
2576  } else {
2577  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2578  size_temp -= rt->flv_size - rt->flv_off;
2579  rt->flv_off += rt->flv_size - rt->flv_off;
2580  }
2581 
2582  if (rt->flv_off == rt->flv_size) {
2583  rt->skip_bytes = 4;
2584 
2585  if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2586  return ret;
2587  rt->flv_size = 0;
2588  rt->flv_off = 0;
2589  rt->flv_header_bytes = 0;
2590  rt->flv_nb_packets++;
2591  }
2592  } while (buf_temp - buf < size);
2593 
2594  if (rt->flv_nb_packets < rt->flush_interval)
2595  return size;
2596  rt->flv_nb_packets = 0;
2597 
2598  /* set stream into nonblocking mode */
2600 
2601  /* try to read one byte from the stream */
2602  ret = ffurl_read(rt->stream, &c, 1);
2603 
2604  /* switch the stream back into blocking mode */
2605  rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2606 
2607  if (ret == AVERROR(EAGAIN)) {
2608  /* no incoming data to handle */
2609  return size;
2610  } else if (ret < 0) {
2611  return ret;
2612  } else if (ret == 1) {
2613  RTMPPacket rpkt = { 0 };
2614 
2615  if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2616  rt->in_chunk_size,
2617  rt->prev_pkt[0], c)) <= 0)
2618  return ret;
2619 
2620  if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2621  return ret;
2622 
2623  ff_rtmp_packet_destroy(&rpkt);
2624  }
2625 
2626  return size;
2627 }
2628 
2629 #define OFFSET(x) offsetof(RTMPContext, x)
2630 #define DEC AV_OPT_FLAG_DECODING_PARAM
2631 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2632 
2633 static const AVOption rtmp_options[] = {
2634  {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2635  {"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},
2636  {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2637  {"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},
2638  {"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},
2639  {"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"},
2640  {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2641  {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2642  {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2643  {"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},
2644  {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2645  {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2646  {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2647  {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2648  {"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},
2649  {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2650  {"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},
2651  {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2652  {"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" },
2653  { NULL },
2654 };
2655 
2656 #define RTMP_PROTOCOL(flavor) \
2657 static const AVClass flavor##_class = { \
2658  .class_name = #flavor, \
2659  .item_name = av_default_item_name, \
2660  .option = rtmp_options, \
2661  .version = LIBAVUTIL_VERSION_INT, \
2662 }; \
2663  \
2664 URLProtocol ff_##flavor##_protocol = { \
2665  .name = #flavor, \
2666  .url_open = rtmp_open, \
2667  .url_read = rtmp_read, \
2668  .url_write = rtmp_write, \
2669  .url_close = rtmp_close, \
2670  .priv_data_size = sizeof(RTMPContext), \
2671  .flags = URL_PROTOCOL_FLAG_NETWORK, \
2672  .priv_data_class= &flavor##_class, \
2673 };
2674 
2675 
2676 RTMP_PROTOCOL(rtmp)
2677 RTMP_PROTOCOL(rtmpe)
2678 RTMP_PROTOCOL(rtmps)
2679 RTMP_PROTOCOL(rtmpt)
2680 RTMP_PROTOCOL(rtmpte)
2681 RTMP_PROTOCOL(rtmpts)