From 5480770f1d3351f942a0f31c4cc1caebaca672e4 Mon Sep 17 00:00:00 2001 From: Davis Davalos-DeLosh Date: Tue, 11 Jan 2022 21:12:19 -0700 Subject: [PATCH] Add auth_setup support --- src/modules/module-raop-discover.c | 2 + src/modules/module-raop-sink.c | 37 +++++++++++++++++-- src/modules/module-raop/rtsp-client.c | 53 ++++++++++++++++++++------- src/modules/module-raop/rtsp-client.h | 6 +++ 4 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/modules/module-raop-discover.c b/src/modules/module-raop-discover.c index 8f7921eb2..f4c6cfdf8 100644 --- a/src/modules/module-raop-discover.c +++ b/src/modules/module-raop-discover.c @@ -218,6 +218,8 @@ static void pw_properties_from_avahi_string(const char *key, const char *value, * 4 = FairPlay SAPv2.5. */ if (str_in_list(value, ",", "1")) value = "RSA"; + else if (str_in_list(value, ",", "4")) + value = "auth_setup"; else value = "none"; pw_properties_set(props, "raop.encryption.type", value); diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index 2ded9c756..c3570054f 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -117,6 +117,7 @@ enum { enum { CRYPTO_NONE, CRYPTO_RSA, + CRYPTO_AUTH_SETUP, }; enum { CODEC_PCM, @@ -369,7 +370,7 @@ static int flush_to_udp_packet(struct impl *impl) memset(dst, 0, len); break; } - if (impl->encryption != CRYPTO_NONE) + if (impl->encryption == CRYPTO_RSA) aes_encrypt(impl, dst, len); impl->rtptime += n_frames; @@ -411,7 +412,7 @@ static int flush_to_tcp_packet(struct impl *impl) memset(dst, 0, len); break; } - if (impl->encryption != CRYPTO_NONE) + if (impl->encryption == CRYPTO_RSA) aes_encrypt(impl, dst, len); pkt[0] |= htonl((uint32_t) len + 12); @@ -1039,6 +1040,31 @@ static int rtsp_do_announce(struct impl *impl) return res; } +static void rtsp_auth_setup_reply(void *data, int status, const struct spa_dict *headers) +{ + struct impl *impl = data; + + pw_log_info("reply %d", status); + + impl->encryption = CRYPTO_NONE; + + rtsp_do_announce(impl); +} + + +static int rtsp_do_auth_setup(struct impl *impl) +{ + int res; + + char output[] = "\x01\x59\x02\xed\xe9\x0d\x4e\xf2\xbd\x4c\xb6\x8a\x63\x30\x03\x82\x07" + "\xa9\x4d\xbd\x50\xd8\xaa\x46\x5b\x5d\x8c\x01\x2a\x0c\x7e\x1d\x4e"; + + res = pw_rtsp_client_url_send(impl->rtsp, "/auth-setup", "POST", &impl->headers->dict, + "application/octet-stream", output, rtsp_auth_setup_reply, impl); + + return res; +} + static const char *find_attr(char **tokens, const char *key) { int i; @@ -1159,7 +1185,10 @@ static void rtsp_options_reply(void *data, int status, const struct spa_dict *he rtsp_do_auth(impl, headers); break; case 200: - rtsp_do_announce(impl); + if (impl->encryption == CRYPTO_AUTH_SETUP) + rtsp_do_auth_setup(impl); + else + rtsp_do_announce(impl); break; } } @@ -1642,6 +1671,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) impl->encryption = CRYPTO_NONE; else if (spa_streq(str, "RSA")) impl->encryption = CRYPTO_RSA; + else if (spa_streq(str, "auth_setup")) + impl->encryption = CRYPTO_AUTH_SETUP; else { pw_log_error( "can't handle encryption type %s", str); goto error; diff --git a/src/modules/module-raop/rtsp-client.c b/src/modules/module-raop/rtsp-client.c index c1740ea5f..beab376ed 100644 --- a/src/modules/module-raop/rtsp-client.c +++ b/src/modules/module-raop/rtsp-client.c @@ -203,7 +203,7 @@ static int read_line(struct pw_rtsp_client *client, char **buf) if (res == 0) return -EPIPE; if (res < 0) { - if (res == EAGAIN) + if (errno == EAGAIN) return 0; return -errno; } @@ -270,21 +270,39 @@ static int process_input(struct pw_rtsp_client *client) int cseq; struct message *msg; const struct spa_dict_item *it; + const char *content_type; + unsigned int content_length; spa_dict_for_each(it, &client->headers->dict) pw_log_info(" %s: %s", it->key, it->value); cseq = pw_properties_get_int32(client->headers, "CSeq", 0); - - if ((msg = find_pending(client, cseq)) != NULL) { - msg->reply(msg->user_data, client->status, &client->headers->dict); - spa_list_remove(&msg->link); - free(msg); - } else { - pw_rtsp_client_emit_message(client, client->status, - &client->headers->dict); - } - client->wait_status = true; + content_type = pw_properties_get(client->headers, "Content-Type"); + if (content_type != NULL && strcmp(content_type, "application/octet-stream") == 0) { + pw_log_info("binary response received"); + content_length = pw_properties_get_uint64(client->headers, "Content-Length", 0); + char content_buf[content_length]; + res = read(client->source->fd, content_buf, content_length); + pw_log_debug("read %d bytes", res); + if (res == 0) { + return -EPIPE; + } else if (res < 0) { + if (errno == EAGAIN) { + return 0; + } + return -errno; + } + pw_properties_set(client->headers, "body", content_buf); + } + if ((msg = find_pending(client, cseq)) != NULL) { + msg->reply(msg->user_data, client->status, &client->headers->dict); + spa_list_remove(&msg->link); + free(msg); + } else { + pw_rtsp_client_emit_message(client, client->status, + &client->headers->dict); + } + client->wait_status = true; } else { char *key, *value; @@ -462,7 +480,7 @@ int pw_rtsp_client_disconnect(struct pw_rtsp_client *client) return 0; } -int pw_rtsp_client_send(struct pw_rtsp_client *client, +int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url, const char *cmd, const struct spa_dict *headers, const char *content_type, const char *content, void (*reply) (void *user_data, int status, const struct spa_dict *headers), @@ -480,7 +498,7 @@ int pw_rtsp_client_send(struct pw_rtsp_client *client, cseq = ++client->cseq; - fprintf(f, "%s %s RTSP/1.0\r\n", cmd, client->url); + fprintf(f, "%s %s RTSP/1.0\r\n", cmd, url); fprintf(f, "CSeq: %d\r\n", cseq); if (headers != NULL) { @@ -514,3 +532,12 @@ int pw_rtsp_client_send(struct pw_rtsp_client *client, } return 0; } + +int pw_rtsp_client_send(struct pw_rtsp_client *client, + const char *cmd, const struct spa_dict *headers, + const char *content_type, const char *content, + void (*reply) (void *user_data, int status, const struct spa_dict *headers), + void *user_data) +{ + return pw_rtsp_client_url_send(client, client->url, cmd, headers, content_type, content, reply, user_data); +} diff --git a/src/modules/module-raop/rtsp-client.h b/src/modules/module-raop/rtsp-client.h index 4588eb830..1ff13ee59 100644 --- a/src/modules/module-raop/rtsp-client.h +++ b/src/modules/module-raop/rtsp-client.h @@ -71,6 +71,12 @@ int pw_rtsp_client_disconnect(struct pw_rtsp_client *client); int pw_rtsp_client_get_local_ip(struct pw_rtsp_client *client, int *version, char *ip, size_t len); +int pw_rtsp_client_url_send(struct pw_rtsp_client *client, const char *url, + const char *cmd, const struct spa_dict *headers, + const char *content_type, const char *content, + void (*reply) (void *user_data, int status, const struct spa_dict *headers), + void *user_data); + int pw_rtsp_client_send(struct pw_rtsp_client *client, const char *cmd, const struct spa_dict *headers, const char *content_type, const char *content, -- GitLab