mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-14 16:25:03 -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 encrypt;
|
||||||
bool wants_metadata;
|
bool wants_metadata;
|
||||||
|
bool supports_auth_setup;
|
||||||
char *pk;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct raop_session
|
struct raop_session
|
||||||
@ -175,6 +174,7 @@ struct raop_session
|
|||||||
bool auth_quirk_itunes;
|
bool auth_quirk_itunes;
|
||||||
bool wants_metadata;
|
bool wants_metadata;
|
||||||
bool supports_post;
|
bool supports_post;
|
||||||
|
bool supports_auth_setup;
|
||||||
|
|
||||||
bool only_probe;
|
bool only_probe;
|
||||||
|
|
||||||
@ -188,7 +188,6 @@ struct raop_session
|
|||||||
char *realm;
|
char *realm;
|
||||||
char *nonce;
|
char *nonce;
|
||||||
const char *password;
|
const char *password;
|
||||||
const char *pk;
|
|
||||||
|
|
||||||
char *devname;
|
char *devname;
|
||||||
char *address;
|
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->password = rd->password;
|
||||||
|
|
||||||
rs->pk = re->pk;
|
rs->supports_auth_setup = re->supports_auth_setup;
|
||||||
rs->wants_metadata = re->wants_metadata;
|
rs->wants_metadata = re->wants_metadata;
|
||||||
|
|
||||||
switch (re->devtype)
|
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
|
// We're not going further with this session
|
||||||
raop_session_cleanup(rs);
|
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
|
// 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");
|
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;
|
const char *p;
|
||||||
char *at_name;
|
char *at_name;
|
||||||
char *password;
|
char *password;
|
||||||
|
char *et;
|
||||||
|
char *token;
|
||||||
|
char *ptr;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
uint64_t sf;
|
uint64_t sf;
|
||||||
int ret;
|
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);
|
ret = safe_hextou64(name, &id);
|
||||||
if (ret < 0)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -4577,13 +4579,13 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
at_name = strchr(name, '@');
|
at_name = strchr(name, '@');
|
||||||
if (!at_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;
|
return;
|
||||||
}
|
}
|
||||||
at_name++;
|
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);
|
airplay = cfg_gettsec(cfg, "airplay", at_name);
|
||||||
if (airplay && cfg_getbool(airplay, "exclude"))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rd = calloc(1, sizeof(struct output_device));
|
CHECK_NULL(L_RAOP, rd = calloc(1, sizeof(struct output_device)));
|
||||||
if (!rd)
|
CHECK_NULL(L_RAOP, re = calloc(1, sizeof(struct raop_extra)));
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
rd->id = id;
|
rd->id = id;
|
||||||
rd->name = strdup(at_name);
|
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");
|
p = keyval_get(txt, "tp");
|
||||||
if (!p)
|
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;
|
goto free_rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*p == '\0')
|
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;
|
goto free_rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strstr(p, "UDP"))
|
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;
|
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");
|
p = keyval_get(txt, "pw");
|
||||||
if (!p)
|
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;
|
rd->has_password = 0;
|
||||||
}
|
}
|
||||||
else if (*p == '\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;
|
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)
|
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);
|
airplay = cfg_gettsec(cfg, "airplay", at_name);
|
||||||
if (airplay)
|
if (airplay)
|
||||||
password = cfg_getstr(airplay, "password");
|
password = cfg_getstr(airplay, "password");
|
||||||
|
|
||||||
if (!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;
|
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)
|
else if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0)
|
||||||
re->devtype = RAOP_DEV_APPLETV;
|
re->devtype = RAOP_DEV_APPLETV;
|
||||||
else if (*p == '\0')
|
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 */
|
/* Encrypt stream */
|
||||||
p = keyval_get(txt, "ek");
|
p = keyval_get(txt, "ek");
|
||||||
@ -4735,9 +4721,21 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
else
|
else
|
||||||
re->wants_metadata = 0;
|
re->wants_metadata = 0;
|
||||||
|
|
||||||
p = keyval_get(txt, "pk");
|
p = keyval_get(txt, "et");
|
||||||
if (p)
|
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;
|
rd->advertised = 1;
|
||||||
|
|
||||||
@ -4746,19 +4744,19 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
case AF_INET:
|
case AF_INET:
|
||||||
rd->v4_address = strdup(address);
|
rd->v4_address = strdup(address);
|
||||||
rd->v4_port = port;
|
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",
|
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",
|
||||||
name, rd->has_password, rd->requires_auth, re->encrypt, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
at_name, rd->has_password, rd->requires_auth, re->encrypt, re->supports_auth_setup, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
rd->v6_address = strdup(address);
|
rd->v6_address = strdup(address);
|
||||||
rd->v6_port = port;
|
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",
|
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",
|
||||||
name, rd->has_password, rd->requires_auth, re->encrypt, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
at_name, rd->has_password, rd->requires_auth, re->encrypt, re->supports_auth_setup, re->wants_metadata, raop_devtype[re->devtype], address, port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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;
|
goto free_rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4856,7 +4854,6 @@ raop_device_free_extra(struct output_device *device)
|
|||||||
{
|
{
|
||||||
struct raop_extra *re = device->extra_device_info;
|
struct raop_extra *re = device->extra_device_info;
|
||||||
|
|
||||||
free(re->pk);
|
|
||||||
free(re);
|
free(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user