mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-14 08:15:02 -05:00
[raop] Use et=4 to determine support for auth_setup (issue #557)
This commit is contained in:
parent
41126d7be4
commit
830d8594aa
@ -161,8 +161,7 @@ struct raop_extra
|
||||
|
||||
bool encrypt;
|
||||
bool wants_metadata;
|
||||
|
||||
char *pk;
|
||||
bool supports_auth_setup;
|
||||
};
|
||||
|
||||
struct raop_session
|
||||
@ -175,6 +174,7 @@ struct raop_session
|
||||
bool auth_quirk_itunes;
|
||||
bool wants_metadata;
|
||||
bool supports_post;
|
||||
bool supports_auth_setup;
|
||||
|
||||
bool only_probe;
|
||||
|
||||
@ -188,7 +188,6 @@ struct raop_session
|
||||
char *realm;
|
||||
char *nonce;
|
||||
const char *password;
|
||||
const char *pk;
|
||||
|
||||
char *devname;
|
||||
char *address;
|
||||
@ -2046,7 +2045,7 @@ raop_session_make(struct output_device *rd, int family, output_status_cb cb, boo
|
||||
|
||||
rs->password = rd->password;
|
||||
|
||||
rs->pk = re->pk;
|
||||
rs->supports_auth_setup = re->supports_auth_setup;
|
||||
rs->wants_metadata = re->wants_metadata;
|
||||
|
||||
switch (re->devtype)
|
||||
@ -4105,7 +4104,7 @@ raop_cb_startup_options(struct evrtsp_request *req, void *arg)
|
||||
// We're not going further with this session
|
||||
raop_session_cleanup(rs);
|
||||
}
|
||||
else if (rs->supports_post && rs->pk)
|
||||
else if (rs->supports_post && rs->supports_auth_setup)
|
||||
{
|
||||
// AirPlay 2 devices require this step or the ANNOUNCE will get a 403
|
||||
ret = raop_send_req_auth_setup(rs, raop_cb_startup_auth_setup, "startup_options");
|
||||
@ -4562,6 +4561,9 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
const char *p;
|
||||
char *at_name;
|
||||
char *password;
|
||||
char *et;
|
||||
char *token;
|
||||
char *ptr;
|
||||
uint64_t id;
|
||||
uint64_t sf;
|
||||
int ret;
|
||||
@ -4569,7 +4571,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
ret = safe_hextou64(name, &id);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "Could not extract AirPlay device ID (%s)\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "Could not extract AirPlay device ID ('%s')\n", name);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -4577,13 +4579,13 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
at_name = strchr(name, '@');
|
||||
if (!at_name)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "Could not extract AirPlay device name (%s)\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "Could not extract AirPlay device name ('%s')\n", name);
|
||||
|
||||
return;
|
||||
}
|
||||
at_name++;
|
||||
|
||||
DPRINTF(E_DBG, L_RAOP, "Event for AirPlay device %s (port %d, id %" PRIx64 ")\n", at_name, port, id);
|
||||
DPRINTF(E_DBG, L_RAOP, "Event for AirPlay device '%s' (port %d, id %" PRIx64 ")\n", at_name, port, id);
|
||||
|
||||
airplay = cfg_gettsec(cfg, "airplay", at_name);
|
||||
if (airplay && cfg_getbool(airplay, "exclude"))
|
||||
@ -4593,22 +4595,8 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
return;
|
||||
}
|
||||
|
||||
rd = calloc(1, sizeof(struct output_device));
|
||||
if (!rd)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "Out of memory (rd)\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
re = calloc(1, sizeof(struct raop_extra));
|
||||
if (!re)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "Out of memory (re)\n");
|
||||
free(rd);
|
||||
|
||||
return;
|
||||
}
|
||||
CHECK_NULL(L_RAOP, rd = calloc(1, sizeof(struct output_device)));
|
||||
CHECK_NULL(L_RAOP, re = calloc(1, sizeof(struct raop_extra)));
|
||||
|
||||
rd->id = id;
|
||||
rd->name = strdup(at_name);
|
||||
@ -4641,21 +4629,21 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
p = keyval_get(txt, "tp");
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay %s: no tp field in TXT record!\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay '%s': no tp field in TXT record!\n", at_name);
|
||||
|
||||
goto free_rd;
|
||||
}
|
||||
|
||||
if (*p == '\0')
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay %s: tp has no value\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay '%s': tp has no value\n", at_name);
|
||||
|
||||
goto free_rd;
|
||||
}
|
||||
|
||||
if (!strstr(p, "UDP"))
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay %s: device does not support AirTunes v2 (tp=%s), discarding\n", name, p);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay '%s': device does not support AirTunes v2 (tp=%s), discarding\n", at_name, p);
|
||||
|
||||
goto free_rd;
|
||||
}
|
||||
@ -4665,13 +4653,11 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
p = keyval_get(txt, "pw");
|
||||
if (!p)
|
||||
{
|
||||
DPRINTF(E_INFO, L_RAOP, "AirPlay %s: no pw field in TXT record, assuming no password protection\n", name);
|
||||
|
||||
rd->has_password = 0;
|
||||
}
|
||||
else if (*p == '\0')
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay %s: pw has no value\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay '%s': pw has no value\n", at_name);
|
||||
|
||||
goto free_rd;
|
||||
}
|
||||
@ -4682,14 +4668,14 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
|
||||
if (rd->has_password)
|
||||
{
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay device %s is password-protected\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay device '%s' is password-protected\n", at_name);
|
||||
|
||||
airplay = cfg_gettsec(cfg, "airplay", at_name);
|
||||
if (airplay)
|
||||
password = cfg_getstr(airplay, "password");
|
||||
|
||||
if (!password)
|
||||
DPRINTF(E_LOG, L_RAOP, "No password given in config for AirPlay device %s\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "No password given in config for AirPlay device '%s'\n", at_name);
|
||||
}
|
||||
|
||||
rd->password = password;
|
||||
@ -4719,7 +4705,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
else if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0)
|
||||
re->devtype = RAOP_DEV_APPLETV;
|
||||
else if (*p == '\0')
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay %s: am has no value\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "AirPlay device '%s': am has no value\n", at_name);
|
||||
|
||||
/* Encrypt stream */
|
||||
p = keyval_get(txt, "ek");
|
||||
@ -4735,9 +4721,21 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
else
|
||||
re->wants_metadata = 0;
|
||||
|
||||
p = keyval_get(txt, "pk");
|
||||
p = keyval_get(txt, "et");
|
||||
if (p)
|
||||
re->pk = strdup(p);
|
||||
{
|
||||
et = strdup(p);
|
||||
token = strtok_r(et, ",", &ptr);
|
||||
while (token)
|
||||
{
|
||||
// Value of 4 seems to indicate support (!= requirement) for auth-setup
|
||||
if (strcmp(token, "4") == 0)
|
||||
re->supports_auth_setup = 1;
|
||||
|
||||
token = strtok_r(NULL, ",", &ptr);
|
||||
}
|
||||
free(et);
|
||||
}
|
||||
|
||||
rd->advertised = 1;
|
||||
|
||||
@ -4746,19 +4744,19 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||
case AF_INET:
|
||||
rd->v4_address = strdup(address);
|
||||
rd->v4_port = port;
|
||||
DPRINTF(E_INFO, L_RAOP, "Adding AirPlay device %s: password: %u, verification: %u, encrypt: %u, metadata: %u, type %s, address %s:%d\n",
|
||||
name, rd->has_password, rd->requires_auth, re->encrypt, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||
DPRINTF(E_INFO, L_RAOP, "Adding AirPlay device '%s': password: %u, verification: %u, encrypt: %u, authsetup: %u, metadata: %u, type %s, address %s:%d\n",
|
||||
at_name, rd->has_password, rd->requires_auth, re->encrypt, re->supports_auth_setup, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
rd->v6_address = strdup(address);
|
||||
rd->v6_port = port;
|
||||
DPRINTF(E_INFO, L_RAOP, "Adding AirPlay device %s: password: %u, verification: %u, encrypt: %u, metadata: %u, type %s, address [%s]:%d\n",
|
||||
name, rd->has_password, rd->requires_auth, re->encrypt, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||
DPRINTF(E_INFO, L_RAOP, "Adding AirPlay device '%s': password: %u, verification: %u, encrypt: %u, authsetup: %u, metadata: %u, type %s, address [%s]:%d\n",
|
||||
at_name, rd->has_password, rd->requires_auth, re->encrypt, re->supports_auth_setup, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF(E_LOG, L_RAOP, "Error: AirPlay device %s has neither ipv4 og ipv6 address\n", name);
|
||||
DPRINTF(E_LOG, L_RAOP, "Error: AirPlay device '%s' has neither ipv4 og ipv6 address\n", at_name);
|
||||
goto free_rd;
|
||||
}
|
||||
|
||||
@ -4856,7 +4854,6 @@ raop_device_free_extra(struct output_device *device)
|
||||
{
|
||||
struct raop_extra *re = device->extra_device_info;
|
||||
|
||||
free(re->pk);
|
||||
free(re);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user