[Live-devel] RTSPClient::describeURL authentication problems

Igor Bukanov igor at mir2.org
Mon Feb 19 03:54:15 PST 2007


On 19/02/07, Igor Bukanov <igor at mir2.org> wrote:
> Hi!
>
> I think the current implementation of
>
> char* RTSPClient::describeURL(char const* url, Authenticator* authenticator,
>                               Boolean allowKasennaProtocol)
>
> has the following problems:
>
> 1. If authenticator is null and the url contains username:password@
> prefix before the host, then code calls describeWithPassword and
> ignores allowKasennaProtocol parameter.
>
> 2.  If authenticator is not null, then the code does not repeat
> sending the command. This is very inconvenient and forces various
> workarounds in the client to repeat the command after the checking one
> more time that the last failure was due to the access denied problem.
>
> The attaches patch fixes both this problems as with it I can play
> through unpatched vlc 0.8.6 rtsp source requiring authorization.
>
> Regards, Igor

The previous mail got a wrong patch, here is one inline:

Index: live/liveMedia/RTSPClient.cpp
===================================================================
--- live.orig/liveMedia/RTSPClient.cpp	2007-02-13 13:39:08.000000000 +0100
+++ live/liveMedia/RTSPClient.cpp	2007-02-19 11:50:51.000000000 +0100
@@ -201,18 +201,19 @@

 char* RTSPClient::describeURL(char const* url, Authenticator* authenticator,
 			      Boolean allowKasennaProtocol) {
-  char* cmd = NULL;
+  Authenticator authenticator2;
   fDescribeStatusCode = 0;
-  do {
-    // First, check whether "url" contains a username:password to be used:
-    char* username; char* password;
-    if (authenticator == NULL
-	&& parseRTSPURLUsernamePassword(url, username, password)) {
-      char* result = describeWithPassword(url, username, password);
-      delete[] username; delete[] password; // they were dynamically allocated
-      return result;
-    }

+  // First, check whether "url" contains a username:password to be used:
+  char* username; char* password;
+  if (authenticator == NULL
+      && parseRTSPURLUsernamePassword(url, username, password)) {
+    authenticator2.setUsernameAndPassword(username, password);
+    authenticator = &authenticator2;
+  }
+
+  Boolean repeatWhenDenied = True;
+  for (;;) {
     if (!openConnectionFromURL(url, authenticator)) break;

     // Send the DESCRIBE command:
@@ -243,7 +244,7 @@
       + strlen(acceptStr)
       + strlen(authenticatorStr)
       + fUserAgentHeaderStrSize;
-    cmd = new char[cmdSize];
+    char* cmd = new char[cmdSize];
     sprintf(cmd, cmdFmt,
 	    url,
 	    ++fCSeq,
@@ -252,7 +253,10 @@
 	    fUserAgentHeaderStr);
     delete[] authenticatorStr;

-    if (!sendRequest(cmd, "DESCRIBE")) break;
+    Boolean sent = sendRequest(cmd, "DESCRIBE");
+    delete cmd;
+    if (!sent)
+        break;

     // Get the response from the server:
     unsigned bytesRead; unsigned responseCode;
@@ -271,11 +275,23 @@
       wantRedirection = True;
       redirectionURL = new char[fResponseBufferSize]; // ensures enough space
     } else if (responseCode != 200) {
-      checkForAuthenticationFailure(responseCode, nextLineStart,
authenticator);
+      if (repeatWhenDenied) {
+        checkForAuthenticationFailure(responseCode, nextLineStart,
+                                      authenticator);
+        if (authenticator->realm() != NULL) {
+          repeatWhenDenied = False;
+          continue;
+        }
+      }
       envir().setResultMsg("cannot handle DESCRIBE response: ", firstLine);
       break;
     }

+    if (authenticator->realm() != NULL) {
+        // The authenticator worked, so use it in future requests:
+        fCurrentAuthenticator = *authenticator;
+    }
+
     // Skip over subsequent header lines, until we see a blank line.
     // The remaining data is assumed to be the SDP descriptor that we want.
     // While skipping over the header lines, we also check for certain headers
@@ -455,7 +471,6 @@
           char* describeSDP = describeURL(url, authenticator, True);
 	
 	  delete[] currentWord;
-          delete[] cmd;
           return describeSDP;
       }

@@ -489,16 +504,13 @@

       char* result = strDup(sdpBuf);
       delete[] sdpBuf; delete[] currentWord;
-      delete[] cmd;
       return result;
     }
     ////////// END Kasenna BS //////////

-    delete[] cmd;
     return strDup(bodyStart);
-  } while (0);
+  }

-  delete[] cmd;
   if (fDescribeStatusCode == 0) fDescribeStatusCode = 2;
   return NULL;
 }
@@ -508,26 +520,7 @@
 		       char const* username, char const* password) {
   Authenticator authenticator;
   authenticator.setUsernameAndPassword(username, password);
-  char* describeResult = describeURL(url, &authenticator);
-  if (describeResult != NULL) {
-    // We are already authorized
-    return describeResult;
-  }
-
-  // The "realm" field should have been filled in:
-  if (authenticator.realm() == NULL) {
-    // We haven't been given enough information to try again, so fail:
-    return NULL;
-  }
-
-  // Try again:
-  describeResult = describeURL(url, &authenticator);
-  if (describeResult != NULL) {
-    // The authenticator worked, so use it in future requests:
-    fCurrentAuthenticator = authenticator;
-  }
-
-  return describeResult;
+  return describeURL(url, &authenticator);
 }

 char* RTSPClient::sendOptionsCmd(char const* url,


More information about the live-devel mailing list