added --sonic-insecure authentication mode, now reports *sonic server errors
This commit is contained in:
parent
ac3cea80d4
commit
05776305cb
|
@ -58,10 +58,14 @@ HTTPDirFS options:
|
|||
for HTTP range requests
|
||||
|
||||
For mounting a Airsonic / Subsonic server:
|
||||
|
||||
--sonic-username The username for your Airsonic / Subsonic server
|
||||
--sonic-password The username for your Airsonic / Subsonic server
|
||||
--sonic-password The password for your Airsonic / Subsonic server
|
||||
--sonic-id3 Enable ID3 mode - this present the server content in
|
||||
Artist/Album/Song layout
|
||||
--sonic-insecure Authenticate against your Airsonic / Subsonic server
|
||||
using the insecure username / hex encoded password
|
||||
scheme
|
||||
|
||||
FUSE options:
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
|
|||
{"sonic-password", required_argument, NULL, 'L'}, /* 16 */
|
||||
{"sonic-id3", no_argument, NULL, 'L'}, /* 17 */
|
||||
{"no-range-check", no_argument, NULL, 'L'}, /* 18 */
|
||||
{"sonic-insecure", no_argument, NULL, 'L'}, /* 19 */
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
while ((c =
|
||||
|
@ -232,6 +233,9 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
|
|||
case 18:
|
||||
CONFIG.no_range_check = 1;
|
||||
break;
|
||||
case 19:
|
||||
CONFIG.sonic_insecure = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "see httpdirfs -h for usage\n");
|
||||
return 1;
|
||||
|
@ -312,5 +316,8 @@ HTTPDirFS options:\n\
|
|||
--sonic-password The username for your Airsonic / Subsonic server\n\
|
||||
--sonic-id3 Enable ID3 mode - this present the server content in\n\
|
||||
Artist/Album/Song layout \n\
|
||||
--sonic-insecure Authenticate against your Airsonic / Subsonic server\n\
|
||||
using the insecure username / hex encoded password\n\
|
||||
scheme\n\
|
||||
\n");
|
||||
}
|
||||
|
|
82
src/sonic.c
82
src/sonic.c
|
@ -36,11 +36,19 @@ void sonic_config_init(const char *server, const char *username,
|
|||
SONIC_CONFIG.username = strndup(username, MAX_FILENAME_LEN);
|
||||
SONIC_CONFIG.password = strndup(password, MAX_FILENAME_LEN);
|
||||
SONIC_CONFIG.client = DEFAULT_USER_AGENT;
|
||||
/*
|
||||
* API 1.13.0 is the minimum version that supports
|
||||
* salt authentication scheme
|
||||
*/
|
||||
SONIC_CONFIG.api_version = "1.13.0";
|
||||
|
||||
if (!CONFIG.sonic_insecure) {
|
||||
/*
|
||||
* API 1.13.0 is the minimum version that supports
|
||||
* salt authentication scheme
|
||||
*/
|
||||
SONIC_CONFIG.api_version = "1.13.0";
|
||||
} else {
|
||||
/*
|
||||
* API 1.8.0 is the minimum version that supports ID3 mode
|
||||
*/
|
||||
SONIC_CONFIG.api_version = "1.8.0";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,21 +56,32 @@ void sonic_config_init(const char *server, const char *username,
|
|||
*/
|
||||
static char *sonic_gen_auth_str(void)
|
||||
{
|
||||
char *salt = generate_salt();
|
||||
size_t password_len = strnlen(SONIC_CONFIG.password, MAX_FILENAME_LEN);
|
||||
size_t password_salt_len = password_len + strnlen(salt, MAX_FILENAME_LEN);
|
||||
char *password_salt = CALLOC(password_salt_len + 1, sizeof(char));
|
||||
strncat(password_salt, SONIC_CONFIG.password, MAX_FILENAME_LEN);
|
||||
strncat(password_salt + password_len, salt, MAX_FILENAME_LEN);
|
||||
char *token = generate_md5sum(password_salt);
|
||||
char *auth_str = CALLOC(MAX_PATH_LEN + 1, sizeof(char));
|
||||
snprintf(auth_str, MAX_PATH_LEN,
|
||||
".view?u=%s&t=%s&s=%s&v=%s&c=%s",
|
||||
SONIC_CONFIG.username, token, salt,
|
||||
SONIC_CONFIG.api_version, SONIC_CONFIG.client);
|
||||
free(salt);
|
||||
free(token);
|
||||
return auth_str;
|
||||
if (!CONFIG.sonic_insecure) {
|
||||
char *salt = generate_salt();
|
||||
size_t pwd_len = strnlen(SONIC_CONFIG.password, MAX_FILENAME_LEN);
|
||||
size_t pwd_salt_len = pwd_len + strnlen(salt, MAX_FILENAME_LEN);
|
||||
char *pwd_salt = CALLOC(pwd_salt_len + 1, sizeof(char));
|
||||
strncat(pwd_salt, SONIC_CONFIG.password, MAX_FILENAME_LEN);
|
||||
strncat(pwd_salt + pwd_len, salt, MAX_FILENAME_LEN);
|
||||
char *token = generate_md5sum(pwd_salt);
|
||||
char *auth_str = CALLOC(MAX_PATH_LEN + 1, sizeof(char));
|
||||
snprintf(auth_str, MAX_PATH_LEN,
|
||||
".view?u=%s&t=%s&s=%s&v=%s&c=%s",
|
||||
SONIC_CONFIG.username, token, salt,
|
||||
SONIC_CONFIG.api_version, SONIC_CONFIG.client);
|
||||
free(salt);
|
||||
free(token);
|
||||
return auth_str;
|
||||
} else {
|
||||
char *pwd_hex = str_to_hex(SONIC_CONFIG.password);
|
||||
char *auth_str = CALLOC(MAX_PATH_LEN + 1, sizeof(char));
|
||||
snprintf(auth_str, MAX_PATH_LEN,
|
||||
".view?u=%s&p=enc:%s&v=%s&c=%s",
|
||||
SONIC_CONFIG.username, pwd_hex, SONIC_CONFIG.api_version,
|
||||
SONIC_CONFIG.client);
|
||||
free(pwd_hex);
|
||||
return auth_str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,6 +163,13 @@ static char *sonic_stream_link(const int id)
|
|||
static void XMLCALL XML_parser_index(void *data, const char *elem,
|
||||
const char **attr)
|
||||
{
|
||||
if (!strcmp(elem, "error")) {
|
||||
fprintf(stderr, "XML_parser_index() error:\n");
|
||||
for (int i = 0; attr[i]; i += 2) {
|
||||
fprintf(stderr, "%s: %s\n", attr[i], attr[i+1]);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
LinkTable *linktbl = (LinkTable *) data;
|
||||
Link *link;
|
||||
if (!strcmp(elem, "child") || !strcmp(elem, "artist")) {
|
||||
|
@ -283,6 +309,14 @@ LinkTable *sonic_LinkTable_new_index(const int id)
|
|||
static void XMLCALL XML_parser_id3_root(void *data, const char *elem,
|
||||
const char **attr)
|
||||
{
|
||||
if (!strcmp(elem, "error")) {
|
||||
fprintf(stderr, "XML_parser_id3_root() error:\n");
|
||||
for (int i = 0; attr[i]; i += 2) {
|
||||
fprintf(stderr, "%s: %s\n", attr[i], attr[i+1]);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
LinkTable *root_linktbl = (LinkTable *) data;
|
||||
LinkTable *this_linktbl = NULL;
|
||||
|
||||
|
@ -347,6 +381,14 @@ static void XMLCALL XML_parser_id3_root(void *data, const char *elem,
|
|||
static void XMLCALL XML_parser_id3(void *data, const char *elem,
|
||||
const char **attr)
|
||||
{
|
||||
if (!strcmp(elem, "error")) {
|
||||
fprintf(stderr, "XML_parser_id3() error:\n");
|
||||
for (int i = 0; attr[i]; i += 2) {
|
||||
fprintf(stderr, "%s: %s\n", attr[i], attr[i+1]);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
LinkTable *linktbl = (LinkTable *) data;
|
||||
Link *link;
|
||||
|
||||
|
|
10
src/util.c
10
src/util.c
|
@ -91,6 +91,8 @@ void Config_init(void)
|
|||
CONFIG.sonic_password = NULL;
|
||||
|
||||
CONFIG.sonic_id3 = 0;
|
||||
|
||||
CONFIG.sonic_insecure = 0;
|
||||
}
|
||||
|
||||
char *path_append(const char *path, const char *filename)
|
||||
|
@ -204,3 +206,11 @@ void *CALLOC(size_t nmemb, size_t size)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
char *str_to_hex(char *s)
|
||||
{
|
||||
char *hex = CALLOC(strlen(s) * 2 + 1, sizeof(char));
|
||||
for (char *c = s, *h = hex; *c; c++, h+=2) {
|
||||
sprintf(h, "%x", *c);
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
|
|
@ -71,8 +71,10 @@ typedef struct {
|
|||
char *sonic_username;
|
||||
/** \brief The Sonic server password */
|
||||
char *sonic_password;
|
||||
/** \brief Whether we are using Sonic mode ID3 extension */
|
||||
/** \brief Whether we are using sonic mode ID3 extension */
|
||||
int sonic_id3;
|
||||
/** \brief Whether we use the legacy sonic authentication mode */
|
||||
int sonic_insecure;
|
||||
} ConfigStruct;
|
||||
|
||||
/**
|
||||
|
@ -132,6 +134,11 @@ char *generate_md5sum(const char *str);
|
|||
*/
|
||||
void *CALLOC(size_t nmemb, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Convert a string to hex
|
||||
*/
|
||||
char *str_to_hex(char *s);
|
||||
|
||||
/**
|
||||
* \brief initialise the configuration data structure
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue