mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-01 01:53:23 -05:00
[mpd] password command
This commit is contained in:
parent
c908ceff4e
commit
c48b819170
66
src/mpd.c
66
src/mpd.c
@ -143,6 +143,11 @@ static const char * const ffmpeg_mime_types[] = { "application/flv", "applicatio
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Provide for connection specfic authentication. */
|
||||||
|
struct mpd_cmd_ctx {
|
||||||
|
int authenticated;
|
||||||
|
};
|
||||||
|
|
||||||
struct output
|
struct output
|
||||||
{
|
{
|
||||||
unsigned short shortid;
|
unsigned short shortid;
|
||||||
@ -3197,6 +3202,38 @@ mpd_command_rescan(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
mpd_command_password(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
|
||||||
|
{
|
||||||
|
char *required_password;
|
||||||
|
char *supplied_password = "";
|
||||||
|
int unrequired;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
supplied_password = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
required_password = cfg_getstr(cfg_getsec(cfg, "library"), "password");
|
||||||
|
unrequired = !required_password || required_password[0] == '\0';
|
||||||
|
|
||||||
|
if (unrequired || strcmp(supplied_password, required_password) == 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_DBG, L_MPD,
|
||||||
|
"Authentication succeeded with supplied password: %s%s\n",
|
||||||
|
supplied_password,
|
||||||
|
unrequired ? " although no password is required" : "");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_LOG, L_MPD,
|
||||||
|
"Authentication failed with supplied password: %s"
|
||||||
|
" for required password: %s\n",
|
||||||
|
supplied_password, required_password);
|
||||||
|
*errmsg = safe_asprintf("Wrong password. Authentication failed.");
|
||||||
|
return ACK_ERROR_PASSWORD;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback function for the 'player_speaker_enumerate' function.
|
* Callback function for the 'player_speaker_enumerate' function.
|
||||||
* Adds a new struct output to the given struct outputs in *arg for the given speaker (id, name, etc.).
|
* Adds a new struct output to the given struct outputs in *arg for the given speaker (id, name, etc.).
|
||||||
@ -4213,11 +4250,11 @@ static struct mpd_command mpd_handlers[] =
|
|||||||
.mpdcommand = "kill",
|
.mpdcommand = "kill",
|
||||||
.handler = mpd_command_kill
|
.handler = mpd_command_kill
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
.mpdcommand = "password",
|
.mpdcommand = "password",
|
||||||
.handler = mpd_command_password
|
.handler = mpd_command_password
|
||||||
},
|
},
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
.mpdcommand = "ping",
|
.mpdcommand = "ping",
|
||||||
.handler = mpd_command_ignore
|
.handler = mpd_command_ignore
|
||||||
@ -4357,7 +4394,7 @@ mpd_command_commands(struct evbuffer *evbuf, int argc, char **argv, char **errms
|
|||||||
* (see mpd_input_filter function).
|
* (see mpd_input_filter function).
|
||||||
*
|
*
|
||||||
* @param bev the buffer event
|
* @param bev the buffer event
|
||||||
* @param ctx (not used)
|
* @param ctx used for authentication
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
mpd_read_cb(struct bufferevent *bev, void *ctx)
|
mpd_read_cb(struct bufferevent *bev, void *ctx)
|
||||||
@ -4374,6 +4411,7 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
|||||||
int close_cmd;
|
int close_cmd;
|
||||||
char *argv[COMMAND_ARGV_MAX];
|
char *argv[COMMAND_ARGV_MAX];
|
||||||
int argc;
|
int argc;
|
||||||
|
struct mpd_cmd_ctx *cmd_ctx = (struct mpd_cmd_ctx *)ctx;
|
||||||
|
|
||||||
/* Get the input evbuffer, contains the command sequence received from the client */
|
/* Get the input evbuffer, contains the command sequence received from the client */
|
||||||
input = bufferevent_get_input(bev);
|
input = bufferevent_get_input(bev);
|
||||||
@ -4444,6 +4482,16 @@ mpd_read_cb(struct bufferevent *bev, void *ctx)
|
|||||||
errmsg = safe_asprintf("Unsupported command '%s'", argv[0]);
|
errmsg = safe_asprintf("Unsupported command '%s'", argv[0]);
|
||||||
ret = ACK_ERROR_UNKNOWN;
|
ret = ACK_ERROR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(command->mpdcommand, "password") == 0)
|
||||||
|
{
|
||||||
|
ret = command->handler(output, argc, argv, &errmsg);
|
||||||
|
cmd_ctx->authenticated = ret == 0;
|
||||||
|
}
|
||||||
|
else if (!cmd_ctx->authenticated)
|
||||||
|
{
|
||||||
|
errmsg = safe_asprintf("Not authenticated");
|
||||||
|
ret = ACK_ERROR_PERMISSION;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ret = command->handler(output, argc, argv, &errmsg);
|
ret = command->handler(output, argc, argv, &errmsg);
|
||||||
|
|
||||||
@ -4583,9 +4631,19 @@ mpd_accept_conn_cb(struct evconnlistener *listener,
|
|||||||
*/
|
*/
|
||||||
struct event_base *base = evconnlistener_get_base(listener);
|
struct event_base *base = evconnlistener_get_base(listener);
|
||||||
struct bufferevent *bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
|
struct bufferevent *bev = bufferevent_socket_new(base, sock, BEV_OPT_CLOSE_ON_FREE);
|
||||||
|
struct mpd_cmd_ctx *cmd_ctx = (struct mpd_cmd_ctx *)malloc(sizeof(struct mpd_cmd_ctx));
|
||||||
|
|
||||||
bev = bufferevent_filter_new(bev, mpd_input_filter, NULL, BEV_OPT_CLOSE_ON_FREE, NULL, NULL);
|
if (!cmd_ctx)
|
||||||
bufferevent_setcb(bev, mpd_read_cb, NULL, mpd_event_cb, bev);
|
{
|
||||||
|
DPRINTF(E_LOG, L_MPD, "Out of memory for command context\n");
|
||||||
|
bufferevent_free(bev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_ctx->authenticated = !cfg_getstr(cfg_getsec(cfg, "library"), "password");
|
||||||
|
|
||||||
|
bev = bufferevent_filter_new(bev, mpd_input_filter, NULL, BEV_OPT_CLOSE_ON_FREE, free, cmd_ctx);
|
||||||
|
bufferevent_setcb(bev, mpd_read_cb, NULL, mpd_event_cb, cmd_ctx);
|
||||||
bufferevent_enable(bev, EV_READ | EV_WRITE);
|
bufferevent_enable(bev, EV_READ | EV_WRITE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user