[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:
ejurgensen 2024-08-02 16:34:57 +02:00
parent 59bba5e261
commit cab0204d29
1 changed files with 39 additions and 15 deletions

View File

@ -207,6 +207,40 @@ content_type_from_profile(enum transcode_profile profile)
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 ---------------------------- */
@ -1432,26 +1466,14 @@ httpd_basic_auth(struct httpd_request *hreq, const char *user, const char *passw
auth += strlen("Basic ");
authuser = (char *)b64_decode(NULL, auth);
if (!authuser)
{
DPRINTF(E_LOG, L_HTTPD, "Could not decode Authentication header\n");
goto need_auth;
}
authpwd = strchr(authuser, ':');
if (!authpwd)
ret = basic_auth_cred_extract(&authuser, &authpwd, auth);
if (ret < 0)
{
DPRINTF(E_LOG, L_HTTPD, "Malformed Authentication header\n");
free(authuser);
goto need_auth;
}
*authpwd = '\0';
authpwd++;
if (user)
{
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");
free(authuser);
free(authpwd);
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");
free(authuser);
free(authpwd);
goto need_auth;
}
free(authuser);
free(authpwd);
return 0;
need_auth: