mirror of
https://github.com/owntone/owntone-server.git
synced 2025-04-01 02:03:45 -04:00
[httpd] Fix for password-based auth for Apple Music
Adds handling of the username from Apple Music that contain colon. Example: iTunes_Music/1.4.5 (Macintosh; OS X 14.5) AppleWebKit/618.2.12.11.6 build/36 (dt:1):password Closes #1778
This commit is contained in:
parent
59bba5e261
commit
cab0204d29
54
src/httpd.c
54
src/httpd.c
@ -207,6 +207,40 @@ content_type_from_profile(enum transcode_profile profile)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
basic_auth_cred_extract(char **user, char **pwd, const char *auth)
|
||||||
|
{
|
||||||
|
char *decoded = NULL;
|
||||||
|
regex_t preg = { 0 };
|
||||||
|
regmatch_t matchptr[3]; // Room for entire string, username substring and password substring
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
decoded = (char *)b64_decode(NULL, auth);
|
||||||
|
if (!decoded)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Apple Music gives is "(dt:1):password", which we need to support even if it
|
||||||
|
// isn't according to the basic auth RFC that says the username cannot include
|
||||||
|
// a colon
|
||||||
|
ret = regcomp(&preg, "(\\(.*?\\)|[^:]*):(.*)", REG_EXTENDED);
|
||||||
|
if (ret != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
ret = regexec(&preg, decoded, ARRAY_SIZE(matchptr), matchptr, 0);
|
||||||
|
if (ret != 0 || matchptr[1].rm_so == -1 || matchptr[2].rm_so == -1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
*user = strndup(decoded + matchptr[1].rm_so, matchptr[1].rm_eo - matchptr[1].rm_so);
|
||||||
|
*pwd = strndup(decoded + matchptr[2].rm_so, matchptr[2].rm_eo - matchptr[2].rm_so);
|
||||||
|
|
||||||
|
free(decoded);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
free(decoded);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------- MODULES INTERFACE ---------------------------- */
|
/* --------------------------- MODULES INTERFACE ---------------------------- */
|
||||||
|
|
||||||
@ -1432,26 +1466,14 @@ httpd_basic_auth(struct httpd_request *hreq, const char *user, const char *passw
|
|||||||
|
|
||||||
auth += strlen("Basic ");
|
auth += strlen("Basic ");
|
||||||
|
|
||||||
authuser = (char *)b64_decode(NULL, auth);
|
ret = basic_auth_cred_extract(&authuser, &authpwd, auth);
|
||||||
if (!authuser)
|
if (ret < 0)
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_HTTPD, "Could not decode Authentication header\n");
|
|
||||||
|
|
||||||
goto need_auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
authpwd = strchr(authuser, ':');
|
|
||||||
if (!authpwd)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_HTTPD, "Malformed Authentication header\n");
|
DPRINTF(E_LOG, L_HTTPD, "Malformed Authentication header\n");
|
||||||
|
|
||||||
free(authuser);
|
|
||||||
goto need_auth;
|
goto need_auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
*authpwd = '\0';
|
|
||||||
authpwd++;
|
|
||||||
|
|
||||||
if (user)
|
if (user)
|
||||||
{
|
{
|
||||||
if (strcmp(user, authuser) != 0)
|
if (strcmp(user, authuser) != 0)
|
||||||
@ -1459,6 +1481,7 @@ httpd_basic_auth(struct httpd_request *hreq, const char *user, const char *passw
|
|||||||
DPRINTF(E_LOG, L_HTTPD, "Username mismatch\n");
|
DPRINTF(E_LOG, L_HTTPD, "Username mismatch\n");
|
||||||
|
|
||||||
free(authuser);
|
free(authuser);
|
||||||
|
free(authpwd);
|
||||||
goto need_auth;
|
goto need_auth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1468,11 +1491,12 @@ httpd_basic_auth(struct httpd_request *hreq, const char *user, const char *passw
|
|||||||
DPRINTF(E_LOG, L_HTTPD, "Bad password\n");
|
DPRINTF(E_LOG, L_HTTPD, "Bad password\n");
|
||||||
|
|
||||||
free(authuser);
|
free(authuser);
|
||||||
|
free(authpwd);
|
||||||
goto need_auth;
|
goto need_auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(authuser);
|
free(authuser);
|
||||||
|
free(authpwd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
need_auth:
|
need_auth:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user