Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package live555 for openSUSE:Factory checked 
in at 2022-02-17 00:30:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/live555 (Old)
 and      /work/SRC/openSUSE:Factory/.live555.new.1956 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "live555"

Thu Feb 17 00:30:11 2022 rev:30 rq:955058 version:2022.02.07

Changes:
--------
--- /work/SRC/openSUSE:Factory/live555/live555.changes  2021-12-21 
18:40:23.285860724 +0100
+++ /work/SRC/openSUSE:Factory/.live555.new.1956/live555.changes        
2022-02-17 00:30:46.549430763 +0100
@@ -1,0 +2,31 @@
+Tue Feb 15 15:50:24 UTC 2022 - Dominique Leuenberger <dims...@opensuse.org>
+
+- Update to version 2022.02.07:
+  + Updated the SRTP packet sending code in "MultiFramedRTPSink.cp"
+    to not allocate a variable-sized buffer on the stack, because
+    some compilers can't handle this.
+  + Ensure that RTSP servers that serve SRTP do not also support
+    streaming over the TCP connection, because that would add extra
+    overhead for no benefit.
+- Changes from version 2022.01.21:
+  + Fixed a bug in the "groupsock" library that could cause
+    outgoing RTP packets to get duplicated when a RTSP "PLAY"
+    command is sent after a "PAUSE".
+- Changes from version 2022.01.20:
+  + More updates to the code for optional server SRTP streaming.
+- Changes from version 2022.01.17:
+  + More updates to the code in preparation for optional server
+    SRTP streaming.
+- Changes from version 2022.01.11:
+  + Fixed a minor memory leak in "RTSPClient" when receiving a SRTP
+    stream.
+  + Updates to "RTPSink" in preparation for optional server SRTP
+    streaming.
+- Changes from version 2022.01.06:
+  + Made "GenericMediaServer::addServerMediaSubsession()" a virtual
+    function, and redefine it in the subclass "RTSPServer" to call
+    the base function, then set the "ServerMediaSubsession"s
+    "streamingIsEncrypted" flag (if the RTSP server is streaming
+    SRTP).
+
+-------------------------------------------------------------------

Old:
----
  live.2021.12.18.tar.gz

New:
----
  live.2022.02.07.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ live555.spec ++++++
--- /var/tmp/diff_new_pack.7isSKn/_old  2022-02-17 00:30:47.161430658 +0100
+++ /var/tmp/diff_new_pack.7isSKn/_new  2022-02-17 00:30:47.173430656 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package live555
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 # Copyright (c) 2020 Dominique Leuenberger, Ramiswil, Switzerland
 #
 # All modifications and additions to the file contributed by third parties
@@ -17,10 +17,10 @@
 #
 
 
-%define lmdmaj 102
+%define lmdmaj 106
 
 Name:           live555
-Version:        2021.12.18
+Version:        2022.02.07
 Release:        0
 Summary:        LIVE555 Streaming Media
 License:        LGPL-2.1-only

++++++ live.2021.12.18.tar.gz -> live.2022.02.07.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh 
new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh
--- old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh     
2021-12-18 23:29:19.000000000 +0100
+++ new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh     
2022-02-07 11:35:51.000000000 +0100
@@ -14,12 +14,12 @@
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 **********/
 // Version information for the "BasicUsageEnvironment" library
-// Copyright (c) 1996-2021 Live Networks, Inc.  All rights reserved.
+// Copyright (c) 1996-2022 Live Networks, Inc.  All rights reserved.
 
 #ifndef _BASICUSAGEENVIRONMENT_VERSION_HH
 #define _BASICUSAGEENVIRONMENT_VERSION_HH
 
-#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING   "2021.12.18"
-#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT              1639785600
+#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING   "2022.02.07"
+#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT              1644192000
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/live/UsageEnvironment/include/UsageEnvironment_version.hh 
new/live/UsageEnvironment/include/UsageEnvironment_version.hh
--- old/live/UsageEnvironment/include/UsageEnvironment_version.hh       
2021-12-18 23:29:19.000000000 +0100
+++ new/live/UsageEnvironment/include/UsageEnvironment_version.hh       
2022-02-07 11:35:51.000000000 +0100
@@ -14,12 +14,12 @@
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 **********/
 // Version information for the "UsageEnvironment" library
-// Copyright (c) 1996-2021 Live Networks, Inc.  All rights reserved.
+// Copyright (c) 1996-2022 Live Networks, Inc.  All rights reserved.
 
 #ifndef _USAGEENVIRONMENT_VERSION_HH
 #define _USAGEENVIRONMENT_VERSION_HH
 
-#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING        "2021.12.18"
-#define USAGEENVIRONMENT_LIBRARY_VERSION_INT           1639785600
+#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING        "2022.02.07"
+#define USAGEENVIRONMENT_LIBRARY_VERSION_INT           1644192000
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/config.linux-with-shared-libraries 
new/live/config.linux-with-shared-libraries
--- old/live/config.linux-with-shared-libraries 2021-12-18 23:29:30.000000000 
+0100
+++ new/live/config.linux-with-shared-libraries 2022-02-07 11:36:13.000000000 
+0100
@@ -3,8 +3,8 @@
 # At least one interface changes, or is removed => CURRENT += 1; REVISION = 0; 
AGE = 0
 # One or more interfaces were added, but no existing interfaces were changed 
or removed => CURRENT += 1; REVISION = 0; AGE += 1
 
-libliveMedia_VERSION_CURRENT=102
-libliveMedia_VERSION_REVISION=2
+libliveMedia_VERSION_CURRENT=106
+libliveMedia_VERSION_REVISION=1
 libliveMedia_VERSION_AGE=0
 libliveMedia_LIB_SUFFIX=so.$(shell expr $(libliveMedia_VERSION_CURRENT) - 
$(libliveMedia_VERSION_AGE)).$(libliveMedia_VERSION_AGE).$(libliveMedia_VERSION_REVISION)
 
@@ -19,7 +19,7 @@
 libUsageEnvironment_LIB_SUFFIX=so.$(shell expr 
$(libUsageEnvironment_VERSION_CURRENT) - 
$(libUsageEnvironment_VERSION_AGE)).$(libUsageEnvironment_VERSION_AGE).$(libUsageEnvironment_VERSION_REVISION)
 
 libgroupsock_VERSION_CURRENT=30
-libgroupsock_VERSION_REVISION=9
+libgroupsock_VERSION_REVISION=10
 libgroupsock_VERSION_AGE=0
 libgroupsock_LIB_SUFFIX=so.$(shell expr $(libgroupsock_VERSION_CURRENT) - 
$(libgroupsock_VERSION_AGE)).$(libgroupsock_VERSION_AGE).$(libgroupsock_VERSION_REVISION)
 #####
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/groupsock/Groupsock.cpp 
new/live/groupsock/Groupsock.cpp
--- old/live/groupsock/Groupsock.cpp    2021-12-18 23:29:19.000000000 +0100
+++ new/live/groupsock/Groupsock.cpp    2022-02-07 11:35:51.000000000 +0100
@@ -225,7 +225,7 @@
   for (destRecord* dest = fDests; dest != NULL; dest = dest->fNext) {
     if (dest->fSessionId == sessionId &&
        dest->fGroupEId.groupAddress() == addr &&
-       dest->fGroupEId.portNum() == portNum(addr)) {
+       dest->fGroupEId.portNum() == port.num()) {
       return;
     }
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/groupsock/include/groupsock_version.hh 
new/live/groupsock/include/groupsock_version.hh
--- old/live/groupsock/include/groupsock_version.hh     2021-12-18 
23:29:19.000000000 +0100
+++ new/live/groupsock/include/groupsock_version.hh     2022-02-07 
11:35:51.000000000 +0100
@@ -14,12 +14,12 @@
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 **********/
 // Version information for the "groupsock" library
-// Copyright (c) 1996-2021 Live Networks, Inc.  All rights reserved.
+// Copyright (c) 1996-2022 Live Networks, Inc.  All rights reserved.
 
 #ifndef _GROUPSOCK_VERSION_HH
 #define _GROUPSOCK_VERSION_HH
 
-#define GROUPSOCK_LIBRARY_VERSION_STRING       "2021.12.18"
-#define GROUPSOCK_LIBRARY_VERSION_INT          1639785600
+#define GROUPSOCK_LIBRARY_VERSION_STRING       "2022.02.07"
+#define GROUPSOCK_LIBRARY_VERSION_INT          1644192000
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/MIKEY.cpp new/live/liveMedia/MIKEY.cpp
--- old/live/liveMedia/MIKEY.cpp        2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/MIKEY.cpp        2022-02-07 11:35:51.000000000 +0100
@@ -67,10 +67,10 @@
                       HDR = 255
 };
 
-MIKEYState::MIKEYState()
+MIKEYState::MIKEYState(Boolean useEncryption)
   : // Set default encryption/authentication parameters:
-  fEncryptSRTP(True),
-  fEncryptSRTCP(True),
+  fEncryptSRTP(useEncryption),
+  fEncryptSRTCP(useEncryption),
   fMKI(our_random32()),
   fUseAuthentication(True),
 
@@ -106,7 +106,7 @@
   delete fHeaderPayload; // which will delete all the other payloads as well
 }
 
-MIKEYState* MIKEYState::createNew(u_int8_t* messageToParse, unsigned 
messageSize) {
+MIKEYState* MIKEYState::createNew(u_int8_t const* messageToParse, unsigned 
messageSize) {
   Boolean parsedOK;
   MIKEYState* newMIKEYState = new MIKEYState(messageToParse, messageSize, 
parsedOK);
 
@@ -115,7 +115,6 @@
     newMIKEYState = NULL;
   }
 
-  delete[] messageToParse;
   return newMIKEYState;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/Makefile.tail 
new/live/liveMedia/Makefile.tail
--- old/live/liveMedia/Makefile.tail    2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/Makefile.tail    2022-02-07 11:35:51.000000000 +0100
@@ -241,8 +241,8 @@
 include/H265VideoFileSink.hh:   include/H264or5VideoFileSink.hh
 OggFileSink.$(CPP):            include/OggFileSink.hh include/OutputFile.hh 
include/VorbisAudioRTPSource.hh include/MPEG2TransportStreamMultiplexor.hh 
include/FramedSource.hh
 include/OggFileSink.hh:                include/FileSink.hh
-RTPSink.$(CPP):                        include/RTPSink.hh
-include/RTPSink.hh:            include/MediaSink.hh include/RTPInterface.hh
+RTPSink.$(CPP):                        include/RTPSink.hh include/Base64.hh
+include/RTPSink.hh:            include/MediaSink.hh include/RTPInterface.hh 
include/SRTPCryptographicContext.hh
 MultiFramedRTPSink.$(CPP):     include/MultiFramedRTPSink.hh
 include/MultiFramedRTPSink.hh:         include/RTPSink.hh
 AudioRTPSink.$(CPP):           include/AudioRTPSink.hh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/MediaSession.cpp 
new/live/liveMedia/MediaSession.cpp
--- old/live/liveMedia/MediaSession.cpp 2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/MediaSession.cpp 2022-02-07 11:35:51.000000000 +0100
@@ -336,6 +336,7 @@
     if (keyMgmtData_decoded == NULL) break;
 
     resultMIKEYState = MIKEYState::createNew(keyMgmtData_decoded, 
keyMgmtData_decodedSize);
+    delete[] keyMgmtData_decoded;
   } while (0);
 
   delete[] keyMgmtPrtclId;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/MultiFramedRTPSink.cpp 
new/live/liveMedia/MultiFramedRTPSink.cpp
--- old/live/liveMedia/MultiFramedRTPSink.cpp   2021-12-18 23:29:19.000000000 
+0100
+++ new/live/liveMedia/MultiFramedRTPSink.cpp   2022-02-07 11:35:51.000000000 
+0100
@@ -362,15 +362,40 @@
   return fOutBuf->isTooBigForAPacket(numBytes);
 }
 
+#define MAX_UDP_PACKET_SIZE 65536
+
 void MultiFramedRTPSink::sendPacketIfNecessary() {
   if (fNumFramesUsedSoFar > 0) {
     // Send the packet:
 #ifdef TEST_LOSS
     if ((our_random()%10) != 0) // simulate 10% packet loss #####
 #endif
-      if (!fRTPInterface.sendPacket(fOutBuf->packet(), 
fOutBuf->curPacketSize())) {
-       // if failure handler has been specified, call it
-       if (fOnSendErrorFunc != NULL) (*fOnSendErrorFunc)(fOnSendErrorData);
+      if (fCrypto != NULL) { // Encrypt/tag the data before sending it:
+#ifndef NO_OPENSSL
+       // Hack: Because the MKI + authentication tag at the end of the packet 
would
+       // overwrite any following (still to be sent) frame data, we can't 
encrypt/tag
+       // the packet in place.  Instead, we have to make a copy (on the stack) 
of
+       // the packet, before encrypting/tagging/sending it:
+       if (fOutBuf->curPacketSize() + SRTP_MKI_LENGTH + SRTP_AUTH_TAG_LENGTH > 
MAX_UDP_PACKET_SIZE) {
+         fprintf(stderr, "MultiFramedRTPSink::sendPacketIfNecessary(): Fatal 
error: packet size %d is too large for SRTP\n", fOutBuf->curPacketSize());
+         exit(1);
+       }
+       u_int8_t packet[MAX_UDP_PACKET_SIZE];
+       memcpy(packet, fOutBuf->packet(), fOutBuf->curPacketSize());
+       unsigned newPacketSize;
+       
+       if (fCrypto->processOutgoingSRTPPacket(packet, 
fOutBuf->curPacketSize(), newPacketSize)) {
+         if (!fRTPInterface.sendPacket(packet, newPacketSize)) {
+           // if failure handler has been specified, call it
+           if (fOnSendErrorFunc != NULL) (*fOnSendErrorFunc)(fOnSendErrorData);
+         }
+       }
+#endif
+      } else { // unencrypted
+       if (!fRTPInterface.sendPacket(fOutBuf->packet(), 
fOutBuf->curPacketSize())) {
+         // if failure handler has been specified, call it
+         if (fOnSendErrorFunc != NULL) (*fOnSendErrorFunc)(fOnSendErrorData);
+       }
       }
     ++fPacketCount;
     fTotalOctetCount += fOutBuf->curPacketSize();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/OnDemandServerMediaSubsession.cpp 
new/live/liveMedia/OnDemandServerMediaSubsession.cpp
--- old/live/liveMedia/OnDemandServerMediaSubsession.cpp        2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/OnDemandServerMediaSubsession.cpp        2022-02-07 
11:35:51.000000000 +0100
@@ -28,7 +28,8 @@
                                portNumBits initialPortNum,
                                Boolean multiplexRTCPWithRTP)
   : ServerMediaSubsession(env),
-    fSDPLines(NULL), fReuseFirstSource(reuseFirstSource),
+    fSDPLines(NULL), fMIKEYStateMessage(NULL), fMIKEYStateMessageSize(0),
+    fReuseFirstSource(reuseFirstSource),
     fMultiplexRTCPWithRTP(multiplexRTCPWithRTP), fLastStreamToken(NULL),
     fAppHandlerTask(NULL), fAppHandlerClientData(NULL) {
   fDestinationsHashTable = HashTable::create(ONE_WORD_HASH_KEYS);
@@ -43,6 +44,7 @@
 }
 
 OnDemandServerMediaSubsession::~OnDemandServerMediaSubsession() {
+  delete[] fMIKEYStateMessage;
   delete[] fSDPLines;
 
   // Clean out the destinations hash table:
@@ -69,10 +71,16 @@
     Groupsock* dummyGroupsock = createGroupsock(nullAddress(addressFamily), 0);
     unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic
     RTPSink* dummyRTPSink = createNewRTPSink(dummyGroupsock, rtpPayloadType, 
inputSource);
-    if (dummyRTPSink != NULL && dummyRTPSink->estimatedBitrate() > 0) 
estBitrate = dummyRTPSink->estimatedBitrate();
+    if (dummyRTPSink != NULL) {
+      if (fParentSession->streamingUsesSRTP) {
+       fMIKEYStateMessage = 
dummyRTPSink->setupForSRTP(fParentSession->streamingIsEncrypted,
+                                                       fMIKEYStateMessageSize);
+      }
 
-    setSDPLinesFromRTPSink(dummyRTPSink, inputSource, estBitrate);
-    Medium::close(dummyRTPSink);
+      if (dummyRTPSink->estimatedBitrate() > 0) estBitrate = 
dummyRTPSink->estimatedBitrate();
+      setSDPLinesFromRTPSink(dummyRTPSink, inputSource, estBitrate);
+      Medium::close(dummyRTPSink);
+    }
     delete dummyGroupsock;
     closeStreamSource(inputSource);
   }
@@ -167,7 +175,12 @@
        unsigned char rtpPayloadType = 96 + trackNumber()-1; // if dynamic
        rtpSink = mediaSource == NULL ? NULL
          : createNewRTPSink(rtpGroupsock, rtpPayloadType, mediaSource);
-       if (rtpSink != NULL && rtpSink->estimatedBitrate() > 0) streamBitrate = 
rtpSink->estimatedBitrate();
+       if (rtpSink != NULL) {
+         if (fParentSession->streamingUsesSRTP) {
+           rtpSink->setupForSRTP(fMIKEYStateMessage, fMIKEYStateMessageSize);
+         }
+         if (rtpSink->estimatedBitrate() > 0) streamBitrate = 
rtpSink->estimatedBitrate();
+       }
       }
 
       // Turn off the destinations for each groupsock.  They'll get set later
@@ -420,8 +433,6 @@
 
 void OnDemandServerMediaSubsession
 ::setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource, unsigned 
estBitrate) {
-  if (rtpSink == NULL) return;
-
   char const* mediaType = rtpSink->sdpMediaType();
   unsigned char rtpPayloadType = rtpSink->rtpPayloadType();
   struct sockaddr_storage const& addressForSDP = 
rtpSink->groupsockBeingUsed().groupAddress();
@@ -429,25 +440,28 @@
 
   AddressString ipAddressStr(addressForSDP);
   char* rtpmapLine = rtpSink->rtpmapLine();
+  char* keyMgmtLine = rtpSink->keyMgmtLine();
   char const* rtcpmuxLine = fMultiplexRTCPWithRTP ? "a=rtcp-mux\r\n" : "";
   char const* rangeLine = rangeSDPLine();
   char const* auxSDPLine = getAuxSDPLine(rtpSink, inputSource);
   if (auxSDPLine == NULL) auxSDPLine = "";
 
   char const* const sdpFmt =
-    "m=%s %u RTP/AVP %d\r\n"
+    "m=%s %u RTP/%sAVP %d\r\n"
     "c=IN %s %s\r\n"
     "b=AS:%u\r\n"
     "%s"
     "%s"
     "%s"
     "%s"
+    "%s"
     "a=control:%s\r\n";
   unsigned sdpFmtSize = strlen(sdpFmt)
-    + strlen(mediaType) + 5 /* max short len */ + 3 /* max char len */
+    + strlen(mediaType) + 5 /* max short len */ + 1 + 3 /* max char len */
     + 3/*IP4 or IP6*/ + strlen(ipAddressStr.val())
     + 20 /* max int len */
     + strlen(rtpmapLine)
+    + strlen(keyMgmtLine)
     + strlen(rtcpmuxLine)
     + strlen(rangeLine)
     + strlen(auxSDPLine)
@@ -456,15 +470,17 @@
   sprintf(sdpLines, sdpFmt,
          mediaType, // m= <media>
          portNumForSDP, // m= <port>
+         fParentSession->streamingUsesSRTP ? "S" : "",
          rtpPayloadType, // m= <fmt list>
          addressForSDP.ss_family == AF_INET ? "IP4" : "IP6", 
ipAddressStr.val(), // c= address
          estBitrate, // b=AS:<bandwidth>
          rtpmapLine, // a=rtpmap:... (if present)
+         keyMgmtLine, // a=key-mgmt:... (if present)
          rtcpmuxLine, // a=rtcp-mux:... (if present)
          rangeLine, // a=range:... (if present)
          auxSDPLine, // optional extra SDP line
          trackId()); // a=control:<track-id>
-  delete[] (char*)rangeLine; delete[] rtpmapLine;
+  delete[] (char*)rangeLine; delete[] keyMgmtLine; delete[] rtpmapLine;
 
   delete[] fSDPLines; fSDPLines = strDup(sdpLines);
   delete[] sdpLines;
@@ -514,7 +530,7 @@
     // Create (and start) a 'RTCP instance' for this RTP sink:
     fRTCPInstance = fMaster.createRTCP(fRTCPgs, fTotalBW, (unsigned 
char*)fMaster.fCNAME, fRTPSink);
         // Note: This starts RTCP running automatically
-    fRTCPInstance->setAppHandler(fMaster.fAppHandlerTask, 
fMaster.fAppHandlerClientData);
+    if (fRTCPInstance != NULL) 
fRTCPInstance->setAppHandler(fMaster.fAppHandlerTask, 
fMaster.fAppHandlerClientData);
   }
 
   if (dests->isTCP) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/PassiveServerMediaSubsession.cpp 
new/live/liveMedia/PassiveServerMediaSubsession.cpp
--- old/live/liveMedia/PassiveServerMediaSubsession.cpp 2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/PassiveServerMediaSubsession.cpp 2022-02-07 
11:35:51.000000000 +0100
@@ -71,7 +71,12 @@
 PassiveServerMediaSubsession::sdpLines(int /*addressFamily*/) {
   if (fSDPLines == NULL ) {
     // Construct a set of SDP lines that describe this subsession:
-    // Use the components from "rtpSink":
+    // Use the components from "rtpSink".
+    if (fParentSession->streamingUsesSRTP) { // Hack to set up for SRTP/SRTCP
+      fRTPSink.setupForSRTP(fParentSession->streamingIsEncrypted);
+      if (fRTCPInstance != NULL) fRTCPInstance->setupForSRTCP();
+    }
+
     Groupsock const& gs = fRTPSink.groupsockBeingUsed();
     AddressString groupAddressStr(gs.groupAddress());
     unsigned short portNum = ntohs(gs.port().num());
@@ -81,25 +86,28 @@
     unsigned estBitrate
       = fRTCPInstance == NULL ? 50 : fRTCPInstance->totSessionBW();
     char* rtpmapLine = fRTPSink.rtpmapLine();
+    char* keyMgmtLine = fRTPSink.keyMgmtLine();
     char const* rtcpmuxLine = rtcpIsMuxed() ? "a=rtcp-mux\r\n" : "";
     char const* rangeLine = rangeSDPLine();
     char const* auxSDPLine = fRTPSink.auxSDPLine();
     if (auxSDPLine == NULL) auxSDPLine = "";
 
     char const* const sdpFmt =
-      "m=%s %d RTP/AVP %d\r\n"
+      "m=%s %d RTP/%sAVP %d\r\n"
       "c=IN %s %s/%d\r\n"
       "b=AS:%u\r\n"
       "%s"
       "%s"
       "%s"
       "%s"
+      "%s"
       "a=control:%s\r\n";
     unsigned sdpFmtSize = strlen(sdpFmt)
-      + strlen(mediaType) + 5 /* max short len */ + 3 /* max char len */
+      + strlen(mediaType) + 5 /* max short len */ + 1 + 3 /* max char len */
       + 3/*IP4 or IP6*/ + strlen(groupAddressStr.val()) + 3 /* max char len */
       + 20 /* max int len */
       + strlen(rtpmapLine)
+      + strlen(keyMgmtLine)
       + strlen(rtcpmuxLine)
       + strlen(rangeLine)
       + strlen(auxSDPLine)
@@ -108,17 +116,19 @@
     sprintf(sdpLines, sdpFmt,
            mediaType, // m= <media>
            portNum, // m= <port>
+           fParentSession->streamingUsesSRTP ? "S" : "",
            rtpPayloadType, // m= <fmt list>
            gs.groupAddress().ss_family == AF_INET ? "IP4" : "IP6", // c= 
address type
            groupAddressStr.val(), // c= <connection address>
            ttl, // c= TTL
            estBitrate, // b=AS:<bandwidth>
            rtpmapLine, // a=rtpmap:... (if present)
+           keyMgmtLine, // a=key-mgmt:... (if present)
            rtcpmuxLine, // a=rtcp-mux:... (if present)
            rangeLine, // a=range:... (if present)
            auxSDPLine, // optional extra SDP line
            trackId()); // a=control:<track-id>
-    delete[] (char*)rangeLine; delete[] rtpmapLine;
+    delete[] (char*)rangeLine; delete[] keyMgmtLine; delete[] rtpmapLine;
 
     fSDPLines = strDup(sdpLines);
     delete[] sdpLines;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/RTCP.cpp new/live/liveMedia/RTCP.cpp
--- old/live/liveMedia/RTCP.cpp 2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/RTCP.cpp 2022-02-07 11:35:51.000000000 +0100
@@ -141,6 +141,8 @@
 #ifdef DEBUG
   fprintf(stderr, "RTCPInstance[%p]::RTCPInstance()\n", this);
 #endif
+  setupForSRTCP();
+
   if (fTotSessionBW == 0) { // not allowed!
     env << "RTCPInstance::RTCPInstance error: totSessionBW parameter should 
not be zero!\n";
     fTotSessionBW = 1;
@@ -281,6 +283,12 @@
   return fKnownMembers->numMembers();
 }
 
+void RTCPInstance::setupForSRTCP() {
+  if (fCrypto == NULL && fSink != NULL) { // take crypto state (if any) from 
the sink instead:
+    fCrypto = fSink->getCrypto();
+  }
+}
+
 void RTCPInstance::setByeHandler(TaskFunc* handlerTask, void* clientData,
                                 Boolean handleActiveParticipantsOnly) {
   fByeHandlerTask = handlerTask;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/RTPSink.cpp 
new/live/liveMedia/RTPSink.cpp
--- old/live/liveMedia/RTPSink.cpp      2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/RTPSink.cpp      2022-02-07 11:35:51.000000000 +0100
@@ -19,6 +19,7 @@
 // Implementation
 
 #include "RTPSink.hh"
+#include "Base64.hh"
 #include "GroupsockHelper.hh"
 
 ////////// RTPSink //////////
@@ -51,6 +52,7 @@
   : MediaSink(env), fRTPInterface(this, rtpGS),
     fRTPPayloadType(rtpPayloadType),
     fPacketCount(0), fOctetCount(0), fTotalOctetCount(0),
+    fMIKEYState(NULL), fCrypto(NULL),
     fTimestampFrequency(rtpTimestampFrequency), 
fNextTimestampHasBeenPreset(False), fEnableRTCPReports(True),
     fNumChannels(numChannels), fEstimatedBitrate(0) {
   fRTPPayloadFormatName
@@ -69,6 +71,7 @@
 RTPSink::~RTPSink() {
   delete fTransmissionStatsDB;
   delete[] (char*)fRTPPayloadFormatName;
+  delete fCrypto; delete fMIKEYState;
   fRTPInterface.forgetOurGroupsock();
     // so that the "fRTPInterface" destructor doesn't turn off background read 
handling (in case
     // its 'groupsock' is being shared with something else that does 
background read handling).
@@ -128,6 +131,28 @@
   fInitialPresentationTime.tv_usec = fMostRecentPresentationTime.tv_usec = 0;
 }
 
+void RTPSink::setupForSRTP(Boolean useEncryption) {
+  // Set up keying state for streaming via SRTP:
+  delete fCrypto; delete fMIKEYState;
+  fMIKEYState = new MIKEYState(useEncryption);
+  fCrypto = new SRTPCryptographicContext(*fMIKEYState);
+}
+
+u_int8_t* RTPSink::setupForSRTP(Boolean useEncryption, unsigned& 
resultMIKEYStateMessageSize) {
+  // Set up keying state for streaming via SRTP:
+  setupForSRTP(useEncryption);
+
+  u_int8_t* MIKEYStateMessage = 
fMIKEYState->generateMessage(resultMIKEYStateMessageSize);
+  return MIKEYStateMessage;
+}
+
+void RTPSink::setupForSRTP(u_int8_t const* MIKEYStateMessage, unsigned 
MIKEYStateMessageSize) {
+  // Set up keying state for streaming via SRTP:
+  delete fCrypto; delete fMIKEYState;
+  fMIKEYState = MIKEYState::createNew(MIKEYStateMessage, 
MIKEYStateMessageSize);
+  fCrypto = new SRTPCryptographicContext(*fMIKEYState);
+}
+
 char const* RTPSink::sdpMediaType() const {
   return "data";
   // default SDP media (m=) type, unless redefined by subclasses
@@ -143,10 +168,10 @@
       encodingParamsPart = strDup("");
     }
     char const* const rtpmapFmt = "a=rtpmap:%d %s/%d%s\r\n";
-    unsigned rtpmapFmtSize = strlen(rtpmapFmt)
+    unsigned rtpmapLineSize = strlen(rtpmapFmt)
       + 3 /* max char len */ + strlen(rtpPayloadFormatName())
       + 20 /* max int len */ + strlen(encodingParamsPart);
-    char* rtpmapLine = new char[rtpmapFmtSize];
+    char* rtpmapLine = new char[rtpmapLineSize];
     sprintf(rtpmapLine, rtpmapFmt,
            rtpPayloadType(), rtpPayloadFormatName(),
            rtpTimestampFrequency(), encodingParamsPart);
@@ -154,7 +179,27 @@
 
     return rtpmapLine;
   } else {
-    // The payload format is staic, so there's no "a=rtpmap:" line:
+    // The payload format is static, so there's no "a=rtpmap:" line:
+    return strDup("");
+  }
+}
+
+char* RTPSink::keyMgmtLine() {
+  u_int8_t* mikeyMessage;
+  unsigned mikeyMessageSize;
+  if (fMIKEYState != NULL &&
+      (mikeyMessage = fMIKEYState->generateMessage(mikeyMessageSize)) != NULL) 
{
+    char const* const keyMgmtFmt = "a=key-mgmt:mikey %s\r\n";
+    char* base64EncodedData = base64Encode((char*)mikeyMessage, 
mikeyMessageSize);
+    delete[] mikeyMessage;
+    
+    unsigned keyMgmtLineSize = strlen(keyMgmtFmt) + strlen(base64EncodedData);
+    char* keyMgmtLine = new char[keyMgmtLineSize];
+    sprintf(keyMgmtLine, keyMgmtFmt, base64EncodedData);
+    delete[] base64EncodedData;
+
+    return keyMgmtLine;
+  } else { // no "a=key-mgmt:" line
     return strDup("");
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/RTSPClient.cpp 
new/live/liveMedia/RTSPClient.cpp
--- old/live/liveMedia/RTSPClient.cpp   2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/RTSPClient.cpp   2022-02-07 11:35:51.000000000 +0100
@@ -1021,8 +1021,9 @@
   } else {
     char const* keyMgmtFmt = "KeyMgmt: prot=mikey; uri=\"%s\"; 
data=\"%s\"\r\n";
     char* base64EncodedData = base64Encode((char*)mikeyMessage, 
mikeyMessageSize);
-    unsigned keyMgmtSize = strlen(keyMgmtFmt)
-      + strlen(url) + strlen(base64EncodedData);
+    delete[] mikeyMessage;
+    
+    unsigned keyMgmtSize = strlen(keyMgmtFmt) + strlen(url) + 
strlen(base64EncodedData);
     keyMgmtStr = new char[keyMgmtSize];
     sprintf(keyMgmtStr, keyMgmtFmt,
            url, base64EncodedData);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/RTSPServer.cpp 
new/live/liveMedia/RTSPServer.cpp
--- old/live/liveMedia/RTSPServer.cpp   2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/RTSPServer.cpp   2022-02-07 11:35:51.000000000 +0100
@@ -133,10 +133,16 @@
 }
 
 void RTSPServer
-::setTLSState(char const* certFileName, char const* privKeyFileName, Boolean 
weServeSRTP) {
+::setTLSState(char const* certFileName, char const* privKeyFileName,
+             Boolean weServeSRTP, Boolean weEncryptSRTP) {
   setTLSFileNames(certFileName, privKeyFileName);
   fOurConnectionsUseTLS = True;
   fWeServeSRTP = weServeSRTP;
+  fWeEncryptSRTP = weEncryptSRTP;
+
+  if (fWeServeSRTP) disableStreamingRTPOverTCP();
+    // If you want to stream RTP-over-TCP using a secure TCP connection, then 
stream over TLS,
+    // but without SRTP (as that would add extra overhead for no benefit).
 }
 
 char const* RTSPServer::allowedCommandNames() {
@@ -220,6 +226,14 @@
   return True;
 }
 
+void RTSPServer::addServerMediaSession(ServerMediaSession* serverMediaSession) 
{
+  GenericMediaServer::addServerMediaSession(serverMediaSession);
+  if (serverMediaSession != NULL) {
+    serverMediaSession->streamingUsesSRTP = fWeServeSRTP;
+    serverMediaSession->streamingIsEncrypted = fWeEncryptSRTP;
+  }
+}
+
 void RTSPServer::incomingConnectionHandlerHTTPIPv4(void* instance, int 
/*mask*/) {
   RTSPServer* server = (RTSPServer*)instance;
   server->incomingConnectionHandlerHTTPIPv4();
@@ -1564,10 +1578,11 @@
                     "RTSP/1.0 200 OK\r\n"
                     "CSeq: %s\r\n"
                     "%s"
-                    "Transport: 
RTP/AVP;multicast;destination=%s;source=%s;port=%d-%d;ttl=%d\r\n"
+                    "Transport: 
RTP/%s;multicast;destination=%s;source=%s;port=%d-%d;ttl=%d\r\n"
                     "Session: %08X%s\r\n\r\n",
                     fOurClientConnection->fCurrentCSeq,
                     dateHeader(),
+                    fOurRTSPServer.fWeServeSRTP ? "SAVP" : "AVP",
                     destAddrStr.val(), sourceAddrStr.val(), 
ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()), destinationTTL,
                     fOurSessionId, timeoutParameterString);
            break;
@@ -1598,10 +1613,11 @@
                     "RTSP/1.0 200 OK\r\n"
                     "CSeq: %s\r\n"
                     "%s"
-                    "Transport: 
RTP/AVP;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\n"
+                    "Transport: 
RTP/%s;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\n"
                     "Session: %08X%s\r\n\r\n",
                     fOurClientConnection->fCurrentCSeq,
                     dateHeader(),
+                    fOurRTSPServer.fWeServeSRTP ? "SAVP" : "AVP",
                     destAddrStr.val(), sourceAddrStr.val(), 
ntohs(clientRTPPort.num()), ntohs(clientRTCPPort.num()), 
ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()),
                     fOurSessionId, timeoutParameterString);
            break;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/SRTPCryptographicContext.cpp 
new/live/liveMedia/SRTPCryptographicContext.cpp
--- old/live/liveMedia/SRTPCryptographicContext.cpp     2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/SRTPCryptographicContext.cpp     2022-02-07 
11:35:51.000000000 +0100
@@ -33,7 +33,7 @@
 ::SRTPCryptographicContext(MIKEYState const& mikeyState)
 #ifndef NO_OPENSSL
   : fMIKEYState(mikeyState),
-    fHaveReceivedSRTPPackets(False), fSRTCPIndex(0) {
+    fHaveReceivedSRTPPackets(False), fHaveSentSRTPPackets(False), 
fSRTCPIndex(0) {
   // Begin by doing a key derivation, to generate the keying data that we need:
   performKeyDerivation();
 #else
@@ -74,7 +74,7 @@
 
     if (!fHaveReceivedSRTPPackets) {
       // First time:
-      nextROC = thisPacketsROC = fROC = 0;
+      nextROC = thisPacketsROC = fReceptionROC = 0;
       nextHighRTPSeqNum = rtpSeqNum;
     } else {
       // Check whether the sequence number has rolled over, or is out-of-order:
@@ -83,23 +83,23 @@
        // normal case, or out-of-order packet that crosses a rollover:
        if (rtpSeqNum - fPreviousHighRTPSeqNum < SEQ_NUM_THRESHOLD) {
          // normal case:
-         nextROC = thisPacketsROC = fROC;
+         nextROC = thisPacketsROC = fReceptionROC;
          nextHighRTPSeqNum = rtpSeqNum;
        } else {
-         // out-of-order packet that crosses rollover:
-         nextROC = fROC;
-         thisPacketsROC = fROC-1;
+         // out-of-order packet that crosses a rollover:
+         nextROC = fReceptionROC;
+         thisPacketsROC = fReceptionROC-1;
          nextHighRTPSeqNum = fPreviousHighRTPSeqNum;
        }
       } else {
        // rollover, or out-of-order packet that crosses a rollover:
        if (fPreviousHighRTPSeqNum - rtpSeqNum > SEQ_NUM_THRESHOLD) {
          // rollover:
-         nextROC = thisPacketsROC = fROC+1;
+         nextROC = thisPacketsROC = fReceptionROC+1;
          nextHighRTPSeqNum = rtpSeqNum;
        } else {
          // out-of-order packet (that doesn't cross a rollover):
-         nextROC = thisPacketsROC = fROC;
+         nextROC = thisPacketsROC = fReceptionROC;
          nextHighRTPSeqNum = fPreviousHighRTPSeqNum;
        }
       }
@@ -120,7 +120,7 @@
     }
 
     // Now that we've verified the packet, set the 'index values' for next 
time:
-    fROC = nextROC;
+    fReceptionROC = nextROC;
     fPreviousHighRTPSeqNum = nextHighRTPSeqNum;
     fHaveReceivedSRTPPackets = True;
 
@@ -139,7 +139,7 @@
 #endif
          break;
        }
-       u_int16_t hdrExtLength = 
(buffer[rtpHeaderSize+2]<<8)|buffer[rtpHeaderSize+3];
+       u_int16_t const hdrExtLength = 
(buffer[rtpHeaderSize+2]<<8)|buffer[rtpHeaderSize+3];
        rtpHeaderSize += 4 + hdrExtLength*4;
       }
 
@@ -235,6 +235,90 @@
 }
 
 Boolean SRTPCryptographicContext
+::processOutgoingSRTPPacket(u_int8_t* buffer, unsigned inPacketSize,
+                           unsigned& outPacketSize) {
+#ifndef NO_OPENSSL
+  do {
+    unsigned const minRTPHeaderSize = 12;
+    if (inPacketSize < minRTPHeaderSize) { // packet is too small
+      // Hack: Let small, non RTCP packets through w/o encryption; they may be 
used to
+      // punch through NATs
+      outPacketSize = inPacketSize;
+      return True;
+    }
+
+    // Encrypt the appropriate part of the packet.
+    if (weEncryptSRTP()) {
+      // Figure out the RTP header size.  This will tell us which bytes to 
encrypt:
+      unsigned rtpHeaderSize = 12; // at least the basic 12-byte header
+      rtpHeaderSize += (buffer[0]&0x0F)*4; // # CSRC identifiers
+      if ((buffer[0]&0x10) != 0) {
+       // There's a RTP extension header.  Add its size:
+       if (inPacketSize < rtpHeaderSize + 4) {
+#ifdef DEBUG
+         fprintf(stderr, 
"SRTPCryptographicContext::processOutgoingSRTPPacket(): Error: Packet size %d 
is shorter than the minimum specified RTP header size %d!\n", inPacketSize, 
rtpHeaderSize + 4);
+#endif
+         break;
+       }
+       u_int16_t const hdrExtLength = 
(buffer[rtpHeaderSize+2]<<8)|buffer[rtpHeaderSize+3];
+       rtpHeaderSize += 4 + hdrExtLength*4;
+      }
+
+      unsigned const offsetToEncryptedBytes = rtpHeaderSize;
+      if (inPacketSize < offsetToEncryptedBytes) {
+#ifdef DEBUG
+       fprintf(stderr, "SRTPCryptographicContext::processOutgoingSRTPPacket(): 
Error: Packet size %d is too small (should be >= %d)!\n", inPacketSize, 
offsetToEncryptedBytes);
+#endif
+       break;
+      }
+
+      // Figure out this packet's 'index' (ROC|rtpSeqNum):
+      u_int16_t const rtpSeqNum = (buffer[2]<<8)|buffer[3];
+      if (!fHaveSentSRTPPackets) {
+       fSendingROC = 0;
+       fHaveSentSRTPPackets = True; // for the future
+      } else {
+       if (rtpSeqNum == 0) ++fSendingROC; // increment the ROC when the RTP 
seq num rolls over
+      }
+      u_int64_t index = (fSendingROC<<16)|rtpSeqNum;
+
+      unsigned const numEncryptedBytes = inPacketSize - 
offsetToEncryptedBytes; // ASSERT: >= 0
+      u_int32_t const SSRC = 
(buffer[8]<<24)|(buffer[9]<<16)|(buffer[10]<<8)|buffer[11];
+      encryptSRTPPacket(index, SSRC, &buffer[offsetToEncryptedBytes], 
numEncryptedBytes);
+    }
+
+    outPacketSize = inPacketSize; // initially
+    
+    unsigned const mkiPosition = outPacketSize; // where the MKI will go
+    
+    if (weAuthenticate()) {
+      // Append the ROC to the payload, because it's used to generate the 
authentication tag.
+      // (Next, the MKI will take its place.)
+      buffer[outPacketSize++] = fSendingROC>>24;
+      buffer[outPacketSize++] = fSendingROC>>16;
+      buffer[outPacketSize++] = fSendingROC>>8;
+      buffer[outPacketSize++] = fSendingROC;
+
+      // Generate and add an authentication tag over the whole packet, plus 
the ROC:
+      outPacketSize += generateSRTPAuthenticationTag(buffer, outPacketSize,
+                                                    &buffer[outPacketSize]);
+    }
+
+    // Add the MKI:
+    buffer[mkiPosition] = MKI()>>24;
+    buffer[mkiPosition+1] = MKI()>>16;
+    buffer[mkiPosition+2] = MKI()>>8;
+    buffer[mkiPosition+3] = MKI();
+
+    return True;
+  } while (0);
+#endif
+  
+  // An error occurred:
+  return False;
+}
+
+Boolean SRTPCryptographicContext
 ::processOutgoingSRTCPPacket(u_int8_t* buffer, unsigned inPacketSize,
                             unsigned& outPacketSize) {
 #ifndef NO_OPENSSL
@@ -286,6 +370,13 @@
 
 #ifndef NO_OPENSSL
 unsigned SRTPCryptographicContext
+::generateSRTPAuthenticationTag(u_int8_t const* dataToAuthenticate, unsigned 
numBytesToAuthenticate,
+                               u_int8_t* resultAuthenticationTag) {
+  return generateAuthenticationTag(fDerivedKeys.srtp, dataToAuthenticate, 
numBytesToAuthenticate,
+                                  resultAuthenticationTag);
+}
+
+unsigned SRTPCryptographicContext
 ::generateSRTCPAuthenticationTag(u_int8_t const* dataToAuthenticate, unsigned 
numBytesToAuthenticate,
                                 u_int8_t* resultAuthenticationTag) {
   return generateAuthenticationTag(fDerivedKeys.srtcp, dataToAuthenticate, 
numBytesToAuthenticate,
@@ -343,6 +434,11 @@
 }
 
 void SRTPCryptographicContext
+::encryptSRTPPacket(u_int64_t index, u_int32_t ssrc, u_int8_t* data, unsigned 
numDataBytes) {
+  cryptData(fDerivedKeys.srtp, index, ssrc, data, numDataBytes);
+}
+
+void SRTPCryptographicContext
 ::encryptSRTCPPacket(u_int32_t index, u_int32_t ssrc, u_int8_t* data, unsigned 
numDataBytes) {
   cryptData(fDerivedKeys.srtcp, (u_int64_t)index, ssrc, data, numDataBytes);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/ServerMediaSession.cpp 
new/live/liveMedia/ServerMediaSession.cpp
--- old/live/liveMedia/ServerMediaSession.cpp   2021-12-18 23:29:19.000000000 
+0100
+++ new/live/liveMedia/ServerMediaSession.cpp   2022-02-07 11:35:51.000000000 
+0100
@@ -63,7 +63,8 @@
                                       char const* info,
                                       char const* description,
                                       Boolean isSSM, char const* miscSDPLines)
-  : Medium(env), fIsSSM(isSSM), fSubsessionsHead(NULL),
+  : Medium(env), streamingUsesSRTP(False), streamingIsEncrypted(False),
+    fIsSSM(isSSM), fSubsessionsHead(NULL),
     fSubsessionsTail(NULL), fSubsessionCounter(0),
     fReferenceCount(0), fDeleteWhenUnreferenced(False) {
   fStreamName = strDup(streamName == NULL ? "" : streamName);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/GenericMediaServer.hh 
new/live/liveMedia/include/GenericMediaServer.hh
--- old/live/liveMedia/include/GenericMediaServer.hh    2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/include/GenericMediaServer.hh    2022-02-07 
11:35:51.000000000 +0100
@@ -43,7 +43,7 @@
 
 class GenericMediaServer: public Medium {
 public:
-  void addServerMediaSession(ServerMediaSession* serverMediaSession);
+  virtual void addServerMediaSession(ServerMediaSession* serverMediaSession);
 
   virtual void lookupServerMediaSession(char const* streamName,
                                        lookupServerMediaSessionCompletionFunc* 
completionFunc,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/MIKEY.hh 
new/live/liveMedia/include/MIKEY.hh
--- old/live/liveMedia/include/MIKEY.hh 2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/include/MIKEY.hh 2022-02-07 11:35:51.000000000 +0100
@@ -30,14 +30,12 @@
 
 class MIKEYState {
 public:
-  MIKEYState(); // initialize with default parameters
+  MIKEYState(Boolean useEncryption = True); // initialize with default 
parameters
   virtual ~MIKEYState();
 
-  static MIKEYState* createNew(u_int8_t* messageToParse, unsigned messageSize);
+  static MIKEYState* createNew(u_int8_t const* messageToParse, unsigned 
messageSize);
       // (Attempts to) parse a binary MIKEY message, returning a new 
"MIKEYState" if successful
       // (or NULL if unsuccessful).
-      // ("messageToParse" is assumed to have been dynamically allocated;
-      // this function will delete[] it.)
 
   u_int8_t* generateMessage(unsigned& messageSize) const;
       // Returns a binary message representing the current MIKEY state, of 
size "messageSize" bytes.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/live/liveMedia/include/OnDemandServerMediaSubsession.hh 
new/live/liveMedia/include/OnDemandServerMediaSubsession.hh
--- old/live/liveMedia/include/OnDemandServerMediaSubsession.hh 2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/include/OnDemandServerMediaSubsession.hh 2022-02-07 
11:35:51.000000000 +0100
@@ -133,6 +133,8 @@
 
 protected:
   char* fSDPLines;
+  u_int8_t* fMIKEYStateMessage; // used if we're streaming SRTP
+  unsigned fMIKEYStateMessageSize; // ditto
   HashTable* fDestinationsHashTable; // indexed by client session id
 
 private:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/RTCP.hh 
new/live/liveMedia/include/RTCP.hh
--- old/live/liveMedia/include/RTCP.hh  2021-12-18 23:29:19.000000000 +0100
+++ new/live/liveMedia/include/RTCP.hh  2022-02-07 11:35:51.000000000 +0100
@@ -66,6 +66,8 @@
   unsigned numMembers() const;
   unsigned totSessionBW() const { return fTotSessionBW; }
 
+  void setupForSRTCP();
+  
   void setByeHandler(TaskFunc* handlerTask, void* clientData,
                     Boolean handleActiveParticipantsOnly = True);
       // Assigns a handler routine to be called if a "BYE" arrives.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/RTPSink.hh 
new/live/liveMedia/include/RTPSink.hh
--- old/live/liveMedia/include/RTPSink.hh       2021-12-18 23:29:19.000000000 
+0100
+++ new/live/liveMedia/include/RTPSink.hh       2022-02-07 11:35:51.000000000 
+0100
@@ -27,6 +27,9 @@
 #ifndef _RTP_INTERFACE_HH
 #include "RTPInterface.hh"
 #endif
+#ifndef _SRTP_CRYPTOGRAPHIC_CONTEXT_HH
+#include "SRTPCryptographicContext.hh"
+#endif
 
 class RTPTransmissionStatsDB; // forward
 
@@ -48,8 +51,16 @@
 
   unsigned numChannels() const { return fNumChannels; }
 
+  void setupForSRTP(Boolean useEncryption);
+      // sets up keying/encryption state for streaming via SRTP, using default 
values.
+  u_int8_t* setupForSRTP(Boolean useEncryption, unsigned& 
resultMIKEYStateMessageSize);
+      // as above, but returns the binary MIKEY state
+  void setupForSRTP(u_int8_t const* MIKEYStateMessage, unsigned 
MIKEYStateMessageSize);
+      // as above, but takes a MIKEY state message as parameter
+
   virtual char const* sdpMediaType() const; // for use in SDP m= lines
   virtual char* rtpmapLine() const; // returns a string to be delete[]d
+  virtual char* keyMgmtLine(); // returns a string to be delete[]d
   virtual char const* auxSDPLine();
       // optional SDP line (e.g. a=fmtp:...)
 
@@ -89,6 +100,8 @@
   u_int32_t SSRC() const {return fSSRC;}
      // later need a means of changing the SSRC if there's a collision #####
 
+  SRTPCryptographicContext* getCrypto() const { return fCrypto; }
+
 protected:
   RTPSink(UsageEnvironment& env,
          Groupsock* rtpGS, unsigned char rtpPayloadType,
@@ -114,6 +127,10 @@
   u_int32_t fCurrentTimestamp;
   u_int16_t fSeqNo;
 
+  // Optional key management and crypto state; used if we are streaming SRTP
+  MIKEYState* fMIKEYState;
+  SRTPCryptographicContext* fCrypto;
+
 private:
   // redefined virtual functions:
   virtual Boolean isRTPSink() const;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/RTSPServer.hh 
new/live/liveMedia/include/RTSPServer.hh
--- old/live/liveMedia/include/RTSPServer.hh    2021-12-18 23:29:19.000000000 
+0100
+++ new/live/liveMedia/include/RTSPServer.hh    2022-02-07 11:35:51.000000000 
+0100
@@ -110,7 +110,7 @@
   portNumBits httpServerPortNum() const; // in host byte order.  (Returns 0 if 
not present.)
 
   void setTLSState(char const* certFileName, char const* privKeyFileName,
-                  Boolean weServeSRTP = False/*later change to True 
#####@@@@@*/);
+                  Boolean weServeSRTP = True, Boolean weEncryptSRTP = True);
 
 protected:
   RTSPServer(UsageEnvironment& env,
@@ -141,8 +141,9 @@
       // - this time after normal digest authentication has already taken 
place (and would otherwise allow access).
       // (This test can only be used to further restrict access, not to grant 
additional access.)
 
-private: // redefined virtual functions
+public: // redefined virtual functions
   virtual Boolean isRTSPServer() const;
+  virtual void addServerMediaSession(ServerMediaSession* serverMediaSession);
 
 public: // should be protected, but some old compilers complain otherwise
   // The state of a TCP connection used by a RTSP client:
@@ -332,6 +333,7 @@
   Boolean fAllowStreamingRTPOverTCP; // by default, True
   Boolean fOurConnectionsUseTLS; // by default, False
   Boolean fWeServeSRTP; // used only if "fOurConnectionsUseTLS" is True
+  Boolean fWeEncryptSRTP; // used only if "fWeServeSRTP" is True
 };
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/SRTPCryptographicContext.hh 
new/live/liveMedia/include/SRTPCryptographicContext.hh
--- old/live/liveMedia/include/SRTPCryptographicContext.hh      2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/include/SRTPCryptographicContext.hh      2022-02-07 
11:35:51.000000000 +0100
@@ -38,12 +38,14 @@
                                     unsigned& outPacketSize);
 
   // Encrypt (if necessary) and add an authentication tag (if necessary) to an 
outgoing
-  // RTCP packet.
+  // RTP and RTCP packet.
   // Returns True iff the packet is well-formed.
   // ("outPacketSize" will be >= "inPacketSize"; there must be enough space at 
the end of
-  //  "buffer" for the extra SRTCP tags (4+4+10 bytes).)
+  //  "buffer" for the extra (4+10 bytes for SRTP; 4+4+10 bytes for SRTCP).)
+  Boolean processOutgoingSRTPPacket(u_int8_t* buffer, unsigned inPacketSize,
+                                   unsigned& outPacketSize);
   Boolean processOutgoingSRTCPPacket(u_int8_t* buffer, unsigned inPacketSize,
-                                     unsigned& outPacketSize);
+                                    unsigned& outPacketSize);
 
 #ifndef NO_OPENSSL
 private:
@@ -75,6 +77,9 @@
                label_srtcp_salt       = 0x05
   } SRTPKeyDerivationLabel;
 
+  unsigned generateSRTPAuthenticationTag(u_int8_t const* dataToAuthenticate, 
unsigned numBytesToAuthenticate,
+                                        u_int8_t* resultAuthenticationTag);
+      // returns the size of the resulting authentication tag
   unsigned generateSRTCPAuthenticationTag(u_int8_t const* dataToAuthenticate, 
unsigned numBytesToAuthenticate,
                                          u_int8_t* resultAuthenticationTag);
       // returns the size of the resulting authentication tag
@@ -87,6 +92,7 @@
   void decryptSRTPPacket(u_int64_t index, u_int32_t ssrc, u_int8_t* data, 
unsigned numDataBytes);
   void decryptSRTCPPacket(u_int32_t index, u_int32_t ssrc, u_int8_t* data, 
unsigned numDataBytes);
 
+  void encryptSRTPPacket(u_int64_t index, u_int32_t ssrc, u_int8_t* data, 
unsigned numDataBytes);
   void encryptSRTCPPacket(u_int32_t index, u_int32_t ssrc, u_int8_t* data, 
unsigned numDataBytes);
 
   unsigned generateAuthenticationTag(derivedKeys& keysToUse,
@@ -132,7 +138,11 @@
   // State used for handling the reception of SRTP packets:
   Boolean fHaveReceivedSRTPPackets;
   u_int16_t fPreviousHighRTPSeqNum;
-  u_int32_t fROC; // rollover counter
+  u_int32_t fReceptionROC; // rollover counter
+
+  // State used for handling the sending of SRTP packets:
+  Boolean fHaveSentSRTPPackets;
+  u_int32_t fSendingROC;
 
   // State used for handling the sending of SRTCP packets:
   u_int32_t fSRTCPIndex;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/ServerMediaSession.hh 
new/live/liveMedia/include/ServerMediaSession.hh
--- old/live/liveMedia/include/ServerMediaSession.hh    2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/include/ServerMediaSession.hh    2022-02-07 
11:35:51.000000000 +0100
@@ -73,6 +73,9 @@
     //   you must first close any client connections that use it,
     //   by calling 
"RTSPServer::closeAllClientSessionsForServerMediaSession()".
 
+  Boolean streamingUsesSRTP; // by default, False
+  Boolean streamingIsEncrypted; // by default, False
+
 protected:
   ServerMediaSession(UsageEnvironment& env, char const* streamName,
                     char const* info, char const* description,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/liveMedia/include/liveMedia_version.hh 
new/live/liveMedia/include/liveMedia_version.hh
--- old/live/liveMedia/include/liveMedia_version.hh     2021-12-18 
23:29:19.000000000 +0100
+++ new/live/liveMedia/include/liveMedia_version.hh     2022-02-07 
11:35:51.000000000 +0100
@@ -14,12 +14,12 @@
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 **********/
 // Version information for the "liveMedia" library
-// Copyright (c) 1996-2021 Live Networks, Inc.  All rights reserved.
+// Copyright (c) 1996-2022 Live Networks, Inc.  All rights reserved.
 
 #ifndef _LIVEMEDIA_VERSION_HH
 #define _LIVEMEDIA_VERSION_HH
 
-#define LIVEMEDIA_LIBRARY_VERSION_STRING       "2021.12.18"
-#define LIVEMEDIA_LIBRARY_VERSION_INT          1639785600
+#define LIVEMEDIA_LIBRARY_VERSION_STRING       "2022.02.07"
+#define LIVEMEDIA_LIBRARY_VERSION_INT          1644192000
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/live/testProgs/announceURL.cpp 
new/live/testProgs/announceURL.cpp
--- old/live/testProgs/announceURL.cpp  2021-12-18 23:29:19.000000000 +0100
+++ new/live/testProgs/announceURL.cpp  2022-02-07 11:35:51.000000000 +0100
@@ -22,7 +22,7 @@
 #include <GroupsockHelper.hh> // for "weHaveAnIPv*Address()"
 
 void announceURL(RTSPServer* rtspServer, ServerMediaSession* sms) {
-  if (rtspServer == NULL || sms == NULL) return; // sanuty check
+  if (rtspServer == NULL || sms == NULL) return; // sanity check
 
   UsageEnvironment& env = rtspServer->envir();
 

Reply via email to