[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