[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