[Live-devel] RTSP server extending

Igor Bukanov igor at mir2.org
Fri Apr 20 04:03:18 PDT 2007


On 10/04/07, Vlad Seryakov <vlad at crystalballinc.com> wrote:
> I may use it in the closed network environment where i do not
> authenticate by user name only but using IP address and/or MAC address
> in addition.

I faced the same problem where the server should reject clients based
on the camera url-ip address. The solution was to patch RTSPServer
class to add to it the following function:

  virtual Boolean checkClientAccess(int clientSocket, char const* urlSuffix);

The default implementation returns true meaning that there is no
restrictions on cleints. A subclass can override it to return false
under some conditions. In that case RTSPServer replies with 401
Unauthorized without setting any digest headers.

Here is the patch in full (its copy is attached as well):

--- .pc/auth.patch/liveMedia/RTSPServer.cpp	2007-04-20 12:29:06.000000000 +0200
+++ liveMedia/RTSPServer.cpp	2007-04-20 12:29:50.922156590 +0200
@@ -75,16 +75,21 @@ void RTSPServer::addServerMediaSession(S
   if (sessionName == NULL) sessionName = "";
   ServerMediaSession* existingSession
     = (ServerMediaSession*)
     (fServerMediaSessions->Add(sessionName,
 			       (void*)serverMediaSession));
   removeServerMediaSession(existingSession); // if any
 }

+Boolean RTSPServer::checkClientAccess(int clientSocket, char const* urlSuffix)
+{
+  return True;
+}
+
 ServerMediaSession* RTSPServer::lookupServerMediaSession(char const*
streamName) {
   return (ServerMediaSession*)(fServerMediaSessions->Lookup(streamName));
 }

 void RTSPServer::removeServerMediaSession(ServerMediaSession*
serverMediaSession) {
   if (serverMediaSession == NULL) return;

   fServerMediaSessions->Remove(serverMediaSession->streamName());
@@ -457,17 +462,18 @@ void RTSPServer::RTSPClientSession::hand
 }

 void RTSPServer::RTSPClientSession
 ::handleCmd_DESCRIBE(char const* cseq, char const* urlSuffix,
 		     char const* fullRequestStr) {
   char* sdpDescription = NULL;
   char* rtspURL = NULL;
   do {
-    if (!authenticationOK("DESCRIBE", cseq, fullRequestStr)) break;
+      if (!authenticationOK("DESCRIBE", cseq, urlSuffix, fullRequestStr))
+          break;

     // We should really check that the request contains an "Accept:" #####
     // for "application/sdp", because that's what we're sending back #####

     // Begin by looking up the "ServerMediaSession" object for the
     // specified "urlSuffix":
     ServerMediaSession* session =
fOurServer.lookupServerMediaSession(urlSuffix);
     if (session == NULL) {
@@ -1126,17 +1132,28 @@ static Boolean parseAuthorizationHeader(
     if (*fields == '\0' || *fields == '\r' || *fields == '\n') break;
   }
   delete[] parameter; delete[] value;
   return True;
 }

 Boolean RTSPServer::RTSPClientSession
 ::authenticationOK(char const* cmdName, char const* cseq,
-		   char const* fullRequestStr) {
+		   char const* urlSuffix, char const* fullRequestStr) {
+
+  if (!fOurServer.checkClientAccess(fClientSocket, urlSuffix)) {
+    snprintf((char*)fResponseBuffer, sizeof fResponseBuffer,
+             "RTSP/1.0 401 Unauthorized\r\n"
+             "CSeq: %s\r\n"
+             "%s"
+             "\r\n",
+             cseq, dateHeader());
+    return False;
+  }
+
   // If we weren't set up with an authentication database, we're OK:
   if (fOurServer.fAuthDB == NULL) return True;

   char const* username = NULL; char const* realm = NULL; char const*
nonce = NULL;
   char const* uri = NULL; char const* response = NULL;
   Boolean success = False;

   do {
--- .pc/auth.patch/liveMedia/include/RTSPServer.hh	2007-04-20
12:29:14.000000000 +0200
+++ liveMedia/include/RTSPServer.hh	2007-04-20 12:29:55.810995282 +0200
@@ -70,16 +70,17 @@ public:
       //     each client will get reclaimed (and the corresponding
RTP stream(s)
       //     torn down) if no RTSP commands - or RTCP "RR" packets - from the
       //     client are received in at least "reclamationTestSeconds" seconds.

   static Boolean lookupByName(UsageEnvironment& env, char const* name,
 			      RTSPServer*& resultServer);

   void addServerMediaSession(ServerMediaSession* serverMediaSession);
+  virtual Boolean checkClientAccess(int clientSocket, char const* urlSuffix);
   virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);
   void removeServerMediaSession(ServerMediaSession* serverMediaSession);
   void removeServerMediaSession(char const* streamName);

   char* rtspURL(ServerMediaSession const* serverMediaSession) const;
       // returns a "rtsp://" URL that could be used to access the
       // specified session (which must already have been added to
       // us using "addServerMediaSession()".
@@ -135,17 +136,18 @@ private:
 			    char const* cseq);
     void handleCmd_PLAY(ServerMediaSubsession* subsession,
 			char const* cseq, char const* fullRequestStr);
     void handleCmd_PAUSE(ServerMediaSubsession* subsession,
 			 char const* cseq);
     void handleCmd_GET_PARAMETER(ServerMediaSubsession* subsession,
 				 char const* cseq, char const* fullRequestStr);
     Boolean authenticationOK(char const* cmdName, char const* cseq,
-			     char const* fullRequestStr);
+                             char const* urlSuffix,
+                             char const* fullRequestStr);
     void noteLiveness();
     Boolean isMulticast() const { return fIsMulticast; }
     static void noteClientLiveness(RTSPClientSession* clientSession);
     static void livenessTimeoutTask(RTSPClientSession* clientSession);

   private:
     RTSPServer& fOurServer;
     unsigned fOurSessionId;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: auth.patch
Type: application/octet-stream
Size: 4778 bytes
Desc: not available
Url : http://lists.live555.com/pipermail/live-devel/attachments/20070420/5d521a23/attachment.obj 


More information about the live-devel mailing list