[vlc-devel] [PATCH 8/8] raop: Implement password authentication

Michael Hanselmann public at hansmi.ch
Sat Jan 10 00:46:53 CET 2009


---
 modules/stream_out/raop.c |   69 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/modules/stream_out/raop.c b/modules/stream_out/raop.c
index 2e18b6b..5089326 100644
--- a/modules/stream_out/raop.c
+++ b/modules/stream_out/raop.c
@@ -42,6 +42,7 @@
 #include <vlc_charset.h>
 #include <vlc_gcrypt.h>
 #include <vlc_es.h>
+#include <vlc_http.h>
 
 #define RAOP_PORT 5000
 #define RAOP_USER_AGENT "VLC " VERSION
@@ -125,6 +126,8 @@ struct sout_stream_sys_t
     int i_audio_latency;
     int i_jack_type;
 
+    http_auth_t auth;
+
     /* Send buffer */
     size_t i_sendbuf_len;
     uint8_t *p_sendbuf;
@@ -838,6 +841,30 @@ error:
     return i_err;
 }
 
+static int ParseAuthenticateHeader( vlc_object_t *p_this,
+                                    vlc_dictionary_t *p_resp_headers )
+{
+    sout_stream_t *p_stream = (sout_stream_t*)p_this;
+    sout_stream_sys_t *p_sys = p_stream->p_sys;
+    char *psz_auth;
+    int i_err = VLC_SUCCESS;
+
+    psz_auth = vlc_dictionary_value_for_key( p_resp_headers,
+                                             "WWW-Authenticate" );
+    if ( psz_auth == NULL )
+    {
+        msg_Err( p_this, "HTTP 401 response missing "
+                         "WWW-Authenticate header" );
+        i_err = VLC_EGENERIC;
+        goto error;
+    }
+
+    http_auth_ParseWwwAuthenticateHeader( p_this, &p_sys->auth, psz_auth );
+
+error:
+    return i_err;
+}
+
 static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
                         const char *psz_content_type, const char *psz_body,
                         vlc_dictionary_t *p_req_headers,
@@ -845,9 +872,11 @@ static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
 {
     sout_stream_t *p_stream = (sout_stream_t*)p_this;
     sout_stream_sys_t *p_sys = p_stream->p_sys;
+    char *psz_authorization = NULL;
     int headers_done;
     int i_err = VLC_SUCCESS;
     int i_status;
+    int i_auth_state;
 
     if ( p_sys->i_control_fd < 0 )
     {
@@ -856,8 +885,29 @@ static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
         goto error;
     }
 
+    i_auth_state = 0;
     while ( 1 )
     {
+        /* Send header only when Digest authentication is used */
+        if ( p_sys->psz_password != NULL && p_sys->auth.psz_nonce != NULL )
+        {
+            FREENULL( psz_authorization );
+
+            psz_authorization =
+                http_auth_FormatAuthorizationHeader( p_this, &p_sys->auth,
+                                                     psz_method,
+                                                     p_sys->psz_url, "",
+                                                     p_sys->psz_password );
+            if ( psz_authorization == NULL )
+            {
+                i_err = VLC_EGENERIC;
+                goto error;
+            }
+
+            vlc_dictionary_insert( p_req_headers, "Authorization",
+                                   psz_authorization );
+        }
+
         /* Send request */
         i_err = SendRequest( p_this, psz_method, psz_content_type, psz_body,
                              p_req_headers);
@@ -886,6 +936,22 @@ static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
         if ( i_status == 200 )
             /* Request successful */
             break;
+        else if ( i_status == 401 )
+        {
+            /* Authorization required */
+            if ( i_auth_state == 1 || p_sys->psz_password == NULL )
+            {
+                msg_Err( p_this, "Access denied, password invalid" );
+                i_err = VLC_EGENERIC;
+                goto error;
+            }
+
+            i_err = ParseAuthenticateHeader( p_this, p_resp_headers );
+            if ( i_err != VLC_SUCCESS )
+                goto error;
+
+            i_auth_state = 1;
+        }
         else
         {
             msg_Err( p_this, "Request failed (%s), status is %d",
@@ -897,6 +963,7 @@ static int ExecRequest( vlc_object_t *p_this, const char *psz_method,
 
 error:
     FREENULL( p_sys->psz_last_status_line );
+    free( psz_authorization );
 
     return i_err;
 }
@@ -1355,6 +1422,8 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_volume = var_GetInteger( p_stream, SOUT_CFG_PREFIX "volume");
     p_sys->i_jack_type = JACK_TYPE_NONE;
 
+    http_auth_Init( &p_sys->auth );
+
     p_sys->psz_host = var_GetNonEmptyString( p_stream,
                                              SOUT_CFG_PREFIX "host" );
     if ( p_sys->psz_host == NULL )
-- 
1.5.6.3




More information about the vlc-devel mailing list