Re: [pulseaudio-discuss] [PATCH v6 16/37] raop: Add the core implementation of RAOP authentication

2016-02-09 Thread Arun Raghavan
On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
> From: Martin Blanchard 
> 
> RAOP authentication (password) is based on BA and DA HTTP authentication
> schemes. This patch adds the RSTP client the ability to specify the caller
> of server response status. Tracking the '401 Unauthorized' status allow
> the RAOP client to respond the server challenge authentication request.
> This patch adds the core implementation but does not introduce the
> authentication scheme in the RAOP connection process yet.
> ---
>  src/modules/raop/raop_client.c  |  245 +-
>  src/modules/raop/raop_client.c.orig | 1495 
> +++

Please remove this file from this commit rather than adding it and
removing it later.

-- Arun

>  src/modules/raop/raop_client.h  |4 +
>  src/modules/rtp/rtsp_client.c   |   83 +-
>  src/modules/rtp/rtsp_client.h   |   26 +-
>  5 files changed, 1810 insertions(+), 43 deletions(-)
>  create mode 100644 src/modules/raop/raop_client.c.orig
> 
> diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
> index a2ec91e..1323cd0 100644
> --- a/src/modules/raop/raop_client.c
> +++ b/src/modules/raop/raop_client.c
> @@ -65,6 +65,9 @@
>  #define VOLUME_MIN -144
>  #define VOLUME_MAX 0
>  
> +#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
> +#define USER_NAME "iTunes"
> +
>  #define DEFAULT_RAOP_PORT 5000
>  #define UDP_DEFAULT_AUDIO_PORT 6000
>  #define UDP_DEFAULT_CONTROL_PORT 6001
> @@ -85,13 +88,15 @@ struct pa_raop_client {
>  pa_core *core;
>  char *host;
>  uint16_t port;
> -char *sid;
>  pa_rtsp_client *rtsp;
> -pa_raop_protocol_t protocol;
> +char *sci, *sid;
> +char *pwd;
>  
>  uint8_t jack_type;
>  uint8_t jack_status;
>  
> +pa_raop_protocol_t protocol;
> +
>  int encryption; /* Enable encryption? */
>  pa_raop_secret *aes;
>  
> @@ -125,6 +130,9 @@ struct pa_raop_client {
>  uint32_t udp_sync_interval;
>  uint32_t udp_sync_count;
>  
> +pa_raop_client_auth_cb_t udp_auth_callback;
> +void *udp_auth_userdata;
> +
>  pa_raop_client_setup_cb_t udp_setup_callback;
>  void *udp_setup_userdata;
>  
> @@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
>  pa_xfree(sdp);
>  }
>  
> -static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
> pa_headerlist* headers, void *userdata) {
> +static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
> pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
>  pa_raop_client* c = userdata;
>  pa_assert(c);
>  pa_assert(rtsp);
> @@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state state, pa_headerlist
>  }
>  }
>  
> -static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
> pa_headerlist *headers, void *userdata) {
> +static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
> pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
>  pa_raop_client *c = userdata;
>  
>  pa_assert(c);
>  pa_assert(rtsp);
>  pa_assert(rtsp == c->rtsp);
> +pa_assert(STATUS_OK == status);
>  
>  switch (state) {
>  case STATE_CONNECT: {
> @@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
> pa_rtsp_state state, pa_headerlist
>  }
>  }
>  
> +static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
> state, pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
> +pa_raop_client *c = userdata;
> +
> +pa_assert(c);
> +pa_assert(rtsp);
> +pa_assert(rtsp == c->rtsp);
> +
> +switch (state) {
> +case STATE_CONNECT: {
> +char *sci = NULL, *sac = NULL;
> +uint16_t rac;
> +struct {
> +uint32_t ci1;
> +uint32_t ci2;
> +} rci;
> +
> +pa_random(, sizeof(rci));
> +/* Generate a random Client-Instance number */
> +sci = pa_sprintf_malloc("%08x%08x",rci.ci1, rci.ci2);
> +pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
> +
> +pa_random(, sizeof(rac));
> +/* Generate a random Apple-Challenge key */
> +pa_raop_base64_encode(, 8*sizeof(rac), );
> +pa_log_debug ("APPLECHALLENGE >> %s | %d", sac, (int) 
> sizeof(rac));
> +rtrimchar(sac, '=');
> +pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
> +
> +pa_rtsp_options(c->rtsp);
> +
> +pa_xfree(sac);
> +pa_xfree(sci);
> +break;
> +}
> +
> +case STATE_OPTIONS: {
> +static bool waiting = false;
> +const char *current = NULL;
> +char space[] = " ";
> +char *token,*ath = NULL;
> +char *publ, *wath, *mth, *val;
> +char *realm = NULL, *nonce = NULL, *response = NULL;
> +char comma[] = ",";
> +
> +

Re: [pulseaudio-discuss] [PATCH v6 16/37] raop: Add the core implementation of RAOP authentication

2016-02-09 Thread Hajime Fujita
Arun Raghavan wrote:
> On Sun, 2016-01-31 at 22:16 -0600, Hajime Fujita wrote:
>> From: Martin Blanchard 
>>
>> RAOP authentication (password) is based on BA and DA HTTP authentication
>> schemes. This patch adds the RSTP client the ability to specify the caller
>> of server response status. Tracking the '401 Unauthorized' status allow
>> the RAOP client to respond the server challenge authentication request.
>> This patch adds the core implementation but does not introduce the
>> authentication scheme in the RAOP connection process yet.
>> ---
>>  src/modules/raop/raop_client.c  |  245 +-
>>  src/modules/raop/raop_client.c.orig | 1495 
>> +++
> 
> Please remove this file from this commit rather than adding it and
> removing it later.

Oops. Good catch.


Thank you,
Hajime

> 
> -- Arun
> 
>>  src/modules/raop/raop_client.h  |4 +
>>  src/modules/rtp/rtsp_client.c   |   83 +-
>>  src/modules/rtp/rtsp_client.h   |   26 +-
>>  5 files changed, 1810 insertions(+), 43 deletions(-)
>>  create mode 100644 src/modules/raop/raop_client.c.orig
>>
>> diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
>> index a2ec91e..1323cd0 100644
>> --- a/src/modules/raop/raop_client.c
>> +++ b/src/modules/raop/raop_client.c
>> @@ -65,6 +65,9 @@
>>  #define VOLUME_MIN -144
>>  #define VOLUME_MAX 0
>>  
>> +#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
>> +#define USER_NAME "iTunes"
>> +
>>  #define DEFAULT_RAOP_PORT 5000
>>  #define UDP_DEFAULT_AUDIO_PORT 6000
>>  #define UDP_DEFAULT_CONTROL_PORT 6001
>> @@ -85,13 +88,15 @@ struct pa_raop_client {
>>  pa_core *core;
>>  char *host;
>>  uint16_t port;
>> -char *sid;
>>  pa_rtsp_client *rtsp;
>> -pa_raop_protocol_t protocol;
>> +char *sci, *sid;
>> +char *pwd;
>>  
>>  uint8_t jack_type;
>>  uint8_t jack_status;
>>  
>> +pa_raop_protocol_t protocol;
>> +
>>  int encryption; /* Enable encryption? */
>>  pa_raop_secret *aes;
>>  
>> @@ -125,6 +130,9 @@ struct pa_raop_client {
>>  uint32_t udp_sync_interval;
>>  uint32_t udp_sync_count;
>>  
>> +pa_raop_client_auth_cb_t udp_auth_callback;
>> +void *udp_auth_userdata;
>> +
>>  pa_raop_client_setup_cb_t udp_setup_callback;
>>  void *udp_setup_userdata;
>>  
>> @@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
>>  pa_xfree(sdp);
>>  }
>>  
>> -static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_headerlist* headers, void *userdata) {
>> +static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
>>  pa_raop_client* c = userdata;
>>  pa_assert(c);
>>  pa_assert(rtsp);
>> @@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
>> pa_rtsp_state state, pa_headerlist
>>  }
>>  }
>>  
>> -static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_headerlist *headers, void *userdata) {
>> +static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
>> pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
>>  pa_raop_client *c = userdata;
>>  
>>  pa_assert(c);
>>  pa_assert(rtsp);
>>  pa_assert(rtsp == c->rtsp);
>> +pa_assert(STATUS_OK == status);
>>  
>>  switch (state) {
>>  case STATE_CONNECT: {
>> @@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
>> pa_rtsp_state state, pa_headerlist
>>  }
>>  }
>>  
>> +static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state 
>> state, pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
>> +pa_raop_client *c = userdata;
>> +
>> +pa_assert(c);
>> +pa_assert(rtsp);
>> +pa_assert(rtsp == c->rtsp);
>> +
>> +switch (state) {
>> +case STATE_CONNECT: {
>> +char *sci = NULL, *sac = NULL;
>> +uint16_t rac;
>> +struct {
>> +uint32_t ci1;
>> +uint32_t ci2;
>> +} rci;
>> +
>> +pa_random(, sizeof(rci));
>> +/* Generate a random Client-Instance number */
>> +sci = pa_sprintf_malloc("%08x%08x",rci.ci1, rci.ci2);
>> +pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
>> +
>> +pa_random(, sizeof(rac));
>> +/* Generate a random Apple-Challenge key */
>> +pa_raop_base64_encode(, 8*sizeof(rac), );
>> +pa_log_debug ("APPLECHALLENGE >> %s | %d", sac, (int) 
>> sizeof(rac));
>> +rtrimchar(sac, '=');
>> +pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
>> +
>> +pa_rtsp_options(c->rtsp);
>> +
>> +pa_xfree(sac);
>> +pa_xfree(sci);
>> +break;
>> +}
>> +
>> +case STATE_OPTIONS: {
>> +static bool waiting = false;
>> +const char *current = NULL;
>> +char space[] = " ";
>> 

[pulseaudio-discuss] [PATCH v6 16/37] raop: Add the core implementation of RAOP authentication

2016-01-31 Thread Hajime Fujita
From: Martin Blanchard 

RAOP authentication (password) is based on BA and DA HTTP authentication
schemes. This patch adds the RSTP client the ability to specify the caller
of server response status. Tracking the '401 Unauthorized' status allow
the RAOP client to respond the server challenge authentication request.
This patch adds the core implementation but does not introduce the
authentication scheme in the RAOP connection process yet.
---
 src/modules/raop/raop_client.c  |  245 +-
 src/modules/raop/raop_client.c.orig | 1495 +++
 src/modules/raop/raop_client.h  |4 +
 src/modules/rtp/rtsp_client.c   |   83 +-
 src/modules/rtp/rtsp_client.h   |   26 +-
 5 files changed, 1810 insertions(+), 43 deletions(-)
 create mode 100644 src/modules/raop/raop_client.c.orig

diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
index a2ec91e..1323cd0 100644
--- a/src/modules/raop/raop_client.c
+++ b/src/modules/raop/raop_client.c
@@ -65,6 +65,9 @@
 #define VOLUME_MIN -144
 #define VOLUME_MAX 0
 
+#define USER_AGENT "iTunes/11.0.4 (Windows; N)"
+#define USER_NAME "iTunes"
+
 #define DEFAULT_RAOP_PORT 5000
 #define UDP_DEFAULT_AUDIO_PORT 6000
 #define UDP_DEFAULT_CONTROL_PORT 6001
@@ -85,13 +88,15 @@ struct pa_raop_client {
 pa_core *core;
 char *host;
 uint16_t port;
-char *sid;
 pa_rtsp_client *rtsp;
-pa_raop_protocol_t protocol;
+char *sci, *sid;
+char *pwd;
 
 uint8_t jack_type;
 uint8_t jack_status;
 
+pa_raop_protocol_t protocol;
+
 int encryption; /* Enable encryption? */
 pa_raop_secret *aes;
 
@@ -125,6 +130,9 @@ struct pa_raop_client {
 uint32_t udp_sync_interval;
 uint32_t udp_sync_count;
 
+pa_raop_client_auth_cb_t udp_auth_callback;
+void *udp_auth_userdata;
+
 pa_raop_client_setup_cb_t udp_setup_callback;
 void *udp_setup_userdata;
 
@@ -576,7 +584,7 @@ static void do_rtsp_announce(pa_raop_client *c) {
 pa_xfree(sdp);
 }
 
-static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist* headers, void *userdata) {
+static void tcp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist* headers, void *userdata) {
 pa_raop_client* c = userdata;
 pa_assert(c);
 pa_assert(rtsp);
@@ -675,12 +683,13 @@ static void tcp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
-static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_headerlist *headers, void *userdata) {
+static void udp_rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
 pa_raop_client *c = userdata;
 
 pa_assert(c);
 pa_assert(rtsp);
 pa_assert(rtsp == c->rtsp);
+pa_assert(STATUS_OK == status);
 
 switch (state) {
 case STATE_CONNECT: {
@@ -982,6 +991,178 @@ static void udp_rtsp_cb(pa_rtsp_client *rtsp, 
pa_rtsp_state state, pa_headerlist
 }
 }
 
+static void rtsp_authentication_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, 
pa_rtsp_status status, pa_headerlist *headers, void *userdata) {
+pa_raop_client *c = userdata;
+
+pa_assert(c);
+pa_assert(rtsp);
+pa_assert(rtsp == c->rtsp);
+
+switch (state) {
+case STATE_CONNECT: {
+char *sci = NULL, *sac = NULL;
+uint16_t rac;
+struct {
+uint32_t ci1;
+uint32_t ci2;
+} rci;
+
+pa_random(, sizeof(rci));
+/* Generate a random Client-Instance number */
+sci = pa_sprintf_malloc("%08x%08x",rci.ci1, rci.ci2);
+pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
+
+pa_random(, sizeof(rac));
+/* Generate a random Apple-Challenge key */
+pa_raop_base64_encode(, 8*sizeof(rac), );
+pa_log_debug ("APPLECHALLENGE >> %s | %d", sac, (int) sizeof(rac));
+rtrimchar(sac, '=');
+pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
+
+pa_rtsp_options(c->rtsp);
+
+pa_xfree(sac);
+pa_xfree(sci);
+break;
+}
+
+case STATE_OPTIONS: {
+static bool waiting = false;
+const char *current = NULL;
+char space[] = " ";
+char *token,*ath = NULL;
+char *publ, *wath, *mth, *val;
+char *realm = NULL, *nonce = NULL, *response = NULL;
+char comma[] = ",";
+
+pa_log_debug("RAOP: OPTIONS");
+/* We do not consider the Apple-Response */
+pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
+
+if (STATUS_UNAUTHORIZED == status) {
+wath = pa_xstrdup(pa_headerlist_gets(headers, 
"WWW-Authenticate"));
+if (true == waiting) {
+pa_xfree(wath);
+goto failure;
+}
+
+