[vlc] Re: RTSP authentication regression in 0.8.6.a?
Igor Bukanov
igor at mir2.org
Tue Feb 20 11:26:36 CET 2007
On 19/02/07, I wrote:
> It turned out to be live555 problem. It can be workarounded in vlc
> source, but that is rather ugly and it is easier to patch the library,
> see http://lists.live555.com/pipermail/live-devel/2007-February/006197.html
At the end this is caused by a problematic iteration with both vlc and
live555. The patch bellow fixes that through vlc-only changes. The
patch changes Connect( demux_t *p_demux ) from modules/demux/live555.c
to send username/password only when DESCRIBE failes with
authentication failure and the server asked to supply the credentials.
The patch also makes sure that username:password@ prefix is stripped
from the URL and is only used for authentication later. In this way
VLC only RTSP-correct URLs and username/password is not exposed
through a clear text with the digest authentication.
With the patch applied, vlc authenticates and shows the video stream.
Regards, Igor
Index: vlc-trunk/modules/demux/live555.cpp
===================================================================
--- vlc-trunk.orig/modules/demux/live555.cpp 2007-02-20 09:28:24.000000000 +0100
+++ vlc-trunk/modules/demux/live555.cpp 2007-02-20 11:15:10.000000000 +0100
@@ -28,6 +28,7 @@
#include <vlc/vlc.h>
#include <stdlib.h> /* malloc(), free() */
#include <string.h>
+#include <assert.h>
#include <vlc_demux.h>
#include <vlc_interface.h>
@@ -700,13 +701,14 @@
demux_sys_t *p_sys = p_demux->p_sys;
Authenticator authenticator;
- char *psz_user = NULL;
- char *psz_pwd = NULL;
+ char *psz_host = NULL;
char *psz_url = NULL;
char *psz_options = NULL;
char *p_sdp = NULL;
int i_http_port = 0;
int i_ret = VLC_SUCCESS;
+ vlc_bool_t b_kasenna;
+ vlc_bool_t b_repeat_describe;
createnew:
if( var_CreateGetBool( p_demux, "rtsp-http" ) )
@@ -724,53 +726,109 @@
p_sys->env->getResultMsg() );
return VLC_EGENERIC;
}
- psz_url = (char*)malloc( strlen( p_sys->psz_path ) + 8 );
- sprintf( psz_url, "rtsp://%s", p_sys->psz_path );
+
+ // Allow to supply username/password via username:password@ prefix.
+ // It must be stripped from the url that is sent to the server.
+ psz_host = p_sys->psz_path;
+ for( ; ; )
+ {
+ if( *psz_host == '\0' )
+ {
+ psz_host = p_sys->psz_path;
+ break;
+ }
+ else if( *psz_host == '@' )
+ {
+ ++psz_host;
+ break;
+ }
+ ++psz_host;
+ }
+ psz_url = (char*)malloc( strlen( psz_host ) + 8 );
+ sprintf( psz_url, "rtsp://%s", psz_host );
psz_options = p_sys->rtsp->sendOptionsCmd( psz_url );
if( psz_options ) delete [] psz_options;
- psz_user = var_CreateGetString( p_demux, "rtsp-user" );
- psz_pwd = var_CreateGetString( p_demux, "rtsp-pwd" );
+ b_kasenna = var_CreateGetBool( p_demux, "rtsp-kasenna" );
-describe:
- authenticator.setUsernameAndPassword( (const char*)psz_user,
(const char*)psz_pwd );
- p_sdp = p_sys->rtsp->describeURL( psz_url,
- &authenticator, var_CreateGetBool( p_demux, "rtsp-kasenna" ) );
+ b_repeat_describe = True;
+ for (;;)
+ {
+ p_sdp = p_sys->rtsp->describeURL( psz_url, &authenticator, b_kasenna );
+ if( p_sdp || authenticator.realm() == NULL || !b_repeat_describe)
+ break;
- if( psz_user ) free( psz_user );
- if( psz_pwd ) free( psz_pwd );
-
+ msg_Dbg( p_demux, "DESCRIBE asked to supply username/password");
+ b_repeat_describe = False;
+
+ char *psz_user;
+ char *psz_pwd;
+ if( psz_host != p_sys->psz_path)
+ {
+ // Parse p_sys->psz_path until psz_host as username:password@
+ assert( psz_host[-1] == '@' );
+ const char* psz_user_end;
+
+ psz_user_end = p_sys->psz_path;
+ while( *psz_user_end != ':' && *psz_user_end != '@' )
+ ++psz_user_end;
+
+ psz_user = (char *)malloc( psz_user_end - p_sys->psz_path + 1);
+ memcpy( psz_user, p_sys->psz_path,
+ psz_user_end - p_sys->psz_path);
+ psz_user[psz_user_end - p_sys->psz_path] = '\0';
+ if( *psz_user_end == '@' )
+ {
+ psz_pwd = strdup("");
+ }
+ else
+ {
+ psz_pwd = (char *)malloc( psz_host - psz_user_end - 1 );
+ memcpy( psz_pwd, psz_user_end + 1,
+ psz_host - psz_user_end - 2 );
+ psz_pwd[psz_host - psz_user_end - 2] = '\0';
+ }
+ }
+ else
+ {
+ psz_user = var_CreateGetString( p_demux, "rtsp-user" );
+ psz_pwd = var_CreateGetString( p_demux, "rtsp-pwd" );
+ if( !psz_user || !psz_pwd )
+ {
+ free( psz_user );
+ psz_user = NULL;
+ free( psz_pwd );
+ psz_pwd = NULL;
+
+ i_ret = intf_UserLoginPassword(
+ p_demux, _("RTSP authentication"),
+ _("Please enter a valid login name and a password."),
+ &psz_user, &psz_pwd );
+ if( i_ret != DIALOG_OK_YES )
+ {
+ free(psz_user);
+ free(psz_pwd);
+ break;
+ }
+ }
+ }
+
+ msg_Dbg( p_demux, "retrying DESCRIBE with user=%s, pwd=%s",
+ psz_user, psz_pwd );
+ authenticator.setUsernameAndPassword( (const char*)psz_user,
(const char*)psz_pwd );
+ free(psz_user);
+ free(psz_pwd);
+ }
+
if( p_sdp == NULL )
{
/* failure occurred */
- int i_code = 0;
const char *psz_error = p_sys->env->getResultMsg();
- msg_Dbg( p_demux, "DESCRIBE failed with %d: %s", i_code, psz_error );
- sscanf( psz_error, "%*sRTSP/%*s%3u", &i_code );
+ msg_Dbg( p_demux, "DESCRIBE failed: %s", psz_error );
- if( i_code == 401 )
- {
- char *psz_login = NULL; char *psz_password = NULL;
- msg_Dbg( p_demux, "authentication failed" );
-
- i_ret = intf_UserLoginPassword( p_demux, _("RTSP authentication"),
- _("Please enter a valid login name and a
password."),
- &psz_login, &psz_password );
- if( i_ret == DIALOG_OK_YES )
- {
- msg_Dbg( p_demux, "retrying with user=%s, pwd=%s",
- psz_login, psz_password );
-
- if( psz_login ) psz_user = psz_login;
- if( psz_password ) psz_pwd = psz_password;
- goto describe;
- }
- if( psz_login ) free( psz_login );
- if( psz_password ) free( psz_password );
- }
- else if( !var_CreateGetBool( p_demux, "rtsp-http" ) )
+ if( !var_CreateGetBool( p_demux, "rtsp-http" ) )
{
/* Perhaps a firewall is being annoying. Try HTTP tunneling mode */
vlc_value_t val;
--
This is the vlc mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://www.videolan.org/support/lists.html
More information about the vlc
mailing list