mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-15 08:45:54 -04:00
RAOP auth quirk for old (802.11g) AirPort Express
This commit is contained in:
parent
cc4e271de1
commit
50a9a3690f
@ -2893,6 +2893,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
uint64_t id;
|
uint64_t id;
|
||||||
int has_password;
|
int has_password;
|
||||||
int encrypt;
|
int encrypt;
|
||||||
|
int auth_quirk_itunes;
|
||||||
int last_active;
|
int last_active;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -3047,11 +3048,15 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
encrypt = 1;
|
encrypt = 1;
|
||||||
|
auth_quirk_itunes = 0;
|
||||||
p = keyval_get(txt, "am");
|
p = keyval_get(txt, "am");
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no am field in TXT record!\n", name);
|
DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no am field in TXT record!\n", name);
|
||||||
|
|
||||||
|
/* Old AirPort Express */
|
||||||
|
auth_quirk_itunes = 1;
|
||||||
|
|
||||||
goto no_am;
|
goto no_am;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3140,6 +3145,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
|||||||
rd->name = strdup(at_name);
|
rd->name = strdup(at_name);
|
||||||
|
|
||||||
rd->encrypt = encrypt;
|
rd->encrypt = encrypt;
|
||||||
|
rd->auth_quirk_itunes = auth_quirk_itunes;
|
||||||
|
|
||||||
rd->has_password = has_password;
|
rd->has_password = has_password;
|
||||||
rd->password = password;
|
rd->password = password;
|
||||||
|
28
src/raop.c
28
src/raop.c
@ -87,6 +87,7 @@ struct raop_session
|
|||||||
unsigned req_in_flight:1;
|
unsigned req_in_flight:1;
|
||||||
unsigned req_has_auth:1;
|
unsigned req_has_auth:1;
|
||||||
unsigned encrypt:1;
|
unsigned encrypt:1;
|
||||||
|
unsigned auth_quirk_itunes:1;
|
||||||
|
|
||||||
int cseq;
|
int cseq;
|
||||||
char *session;
|
char *session;
|
||||||
@ -671,6 +672,8 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
char ha2[33];
|
char ha2[33];
|
||||||
char ebuf[64];
|
char ebuf[64];
|
||||||
char auth[256];
|
char auth[256];
|
||||||
|
const char *hash_fmt;
|
||||||
|
const char *username;
|
||||||
uint8_t *hash_bytes;
|
uint8_t *hash_bytes;
|
||||||
size_t hashlen;
|
size_t hashlen;
|
||||||
gcry_md_hd_t hd;
|
gcry_md_hd_t hd;
|
||||||
@ -690,6 +693,17 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rs->auth_quirk_itunes)
|
||||||
|
{
|
||||||
|
hash_fmt = "%02X"; /* Uppercase hex */
|
||||||
|
username = "iTunes";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hash_fmt = "%02x";
|
||||||
|
username = ""; /* No username */
|
||||||
|
}
|
||||||
|
|
||||||
gc_err = gcry_md_open(&hd, GCRY_MD_MD5, 0);
|
gc_err = gcry_md_open(&hd, GCRY_MD_MD5, 0);
|
||||||
if (gc_err != GPG_ERR_NO_ERROR)
|
if (gc_err != GPG_ERR_NO_ERROR)
|
||||||
{
|
{
|
||||||
@ -704,7 +718,8 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
hashlen = gcry_md_get_algo_dlen(GCRY_MD_MD5);
|
hashlen = gcry_md_get_algo_dlen(GCRY_MD_MD5);
|
||||||
|
|
||||||
/* HA 1 */
|
/* HA 1 */
|
||||||
/* No username */
|
|
||||||
|
gcry_md_write(hd, username, strlen(username));
|
||||||
gcry_md_write(hd, ":", 1);
|
gcry_md_write(hd, ":", 1);
|
||||||
gcry_md_write(hd, rs->realm, strlen(rs->realm));
|
gcry_md_write(hd, rs->realm, strlen(rs->realm));
|
||||||
gcry_md_write(hd, ":", 1);
|
gcry_md_write(hd, ":", 1);
|
||||||
@ -719,7 +734,7 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < hashlen; i++)
|
for (i = 0; i < hashlen; i++)
|
||||||
sprintf(ha1 + (2 * i), "%02x", hash_bytes[i]);
|
sprintf(ha1 + (2 * i), hash_fmt, hash_bytes[i]);
|
||||||
|
|
||||||
/* RESET */
|
/* RESET */
|
||||||
gcry_md_reset(hd);
|
gcry_md_reset(hd);
|
||||||
@ -738,7 +753,7 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < hashlen; i++)
|
for (i = 0; i < hashlen; i++)
|
||||||
sprintf(ha2 + (2 * i), "%02x", hash_bytes[i]);
|
sprintf(ha2 + (2 * i), hash_fmt, hash_bytes[i]);
|
||||||
|
|
||||||
/* RESET */
|
/* RESET */
|
||||||
gcry_md_reset(hd);
|
gcry_md_reset(hd);
|
||||||
@ -759,13 +774,13 @@ raop_add_auth(struct raop_session *rs, struct evrtsp_request *req, const char *m
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < hashlen; i++)
|
for (i = 0; i < hashlen; i++)
|
||||||
sprintf(ha1 + (2 * i), "%02x", hash_bytes[i]);
|
sprintf(ha1 + (2 * i), hash_fmt, hash_bytes[i]);
|
||||||
|
|
||||||
gcry_md_close(hd);
|
gcry_md_close(hd);
|
||||||
|
|
||||||
/* Build header */
|
/* Build header */
|
||||||
ret = snprintf(auth, sizeof(auth), "Digest username=\"\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
|
ret = snprintf(auth, sizeof(auth), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\"",
|
||||||
rs->realm, rs->nonce, uri, ha1);
|
username, rs->realm, rs->nonce, uri, ha1);
|
||||||
if ((ret < 0) || (ret >= sizeof(auth)))
|
if ((ret < 0) || (ret >= sizeof(auth)))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_RAOP, "Authorization value header exceeds buffer size\n");
|
DPRINTF(E_LOG, L_RAOP, "Authorization value header exceeds buffer size\n");
|
||||||
@ -1456,6 +1471,7 @@ raop_session_make(struct raop_device *rd, int family, raop_status_cb cb)
|
|||||||
rs->server_fd = -1;
|
rs->server_fd = -1;
|
||||||
|
|
||||||
rs->encrypt = rd->encrypt;
|
rs->encrypt = rd->encrypt;
|
||||||
|
rs->auth_quirk_itunes = rd->auth_quirk_itunes;
|
||||||
|
|
||||||
rs->password = rd->password;
|
rs->password = rd->password;
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ struct raop_device
|
|||||||
unsigned selected:1;
|
unsigned selected:1;
|
||||||
unsigned advertised:1;
|
unsigned advertised:1;
|
||||||
unsigned encrypt:1;
|
unsigned encrypt:1;
|
||||||
|
unsigned auth_quirk_itunes:1;
|
||||||
|
|
||||||
unsigned has_password:1;
|
unsigned has_password:1;
|
||||||
const char *password;
|
const char *password;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user