[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