mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-05 02:38:09 -05:00
[httpd/mpd] Adjustments to commit #69ff42f
This commit is contained in:
parent
69ff42fc6a
commit
a6fab4ac0d
58
src/httpd.c
58
src/httpd.c
@ -879,6 +879,7 @@ struct httpd_request *
|
||||
httpd_request_parse(struct evhttp_request *req, struct httpd_uri_parsed *uri_parsed, const char *user_agent, struct httpd_uri_map *uri_map)
|
||||
{
|
||||
struct httpd_request *hreq;
|
||||
struct evhttp_connection *evcon;
|
||||
struct evkeyvalq *headers;
|
||||
int i;
|
||||
int ret;
|
||||
@ -890,12 +891,19 @@ httpd_request_parse(struct evhttp_request *req, struct httpd_uri_parsed *uri_par
|
||||
hreq->uri_parsed = uri_parsed;
|
||||
hreq->query = &(uri_parsed->ev_query);
|
||||
|
||||
if (req && !user_agent)
|
||||
if (req)
|
||||
{
|
||||
headers = evhttp_request_get_input_headers(req);
|
||||
hreq->user_agent = evhttp_find_header(headers, "User-Agent");
|
||||
|
||||
evcon = evhttp_request_get_connection(req);
|
||||
if (evcon)
|
||||
evhttp_connection_get_peer(evcon, &hreq->peer_address, &hreq->peer_port);
|
||||
else
|
||||
DPRINTF(E_LOG, L_HTTPD, "Connection to client lost or missing\n");
|
||||
}
|
||||
else
|
||||
|
||||
if (user_agent)
|
||||
hreq->user_agent = user_agent;
|
||||
|
||||
// Find a handler for the path
|
||||
@ -1400,44 +1408,14 @@ httpd_redirect_to_index(struct evhttp_request *req, const char *uri)
|
||||
httpd_send_reply(req, HTTP_MOVETEMP, "Moved", NULL, HTTPD_SEND_NO_GZIP);
|
||||
}
|
||||
|
||||
/* |:todo:|This is also needed for mpd and should probably go somewhere else. */
|
||||
bool
|
||||
peer_address_is_trusted(const char *addr)
|
||||
{
|
||||
cfg_t *section;
|
||||
const char *network;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (strncmp(addr, "::ffff:", strlen("::ffff:")) == 0)
|
||||
addr += strlen("::ffff:");
|
||||
|
||||
section = cfg_getsec(cfg, "general");
|
||||
|
||||
n = cfg_size(section, "trusted_networks");
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
network = cfg_getnstr(section, "trusted_networks", i);
|
||||
|
||||
if (strncmp(network, addr, strlen(network)) == 0)
|
||||
return true;
|
||||
|
||||
if ((strcmp(network, "localhost") == 0) && (strcmp(addr, "127.0.0.1") == 0 || strcmp(addr, "::1") == 0))
|
||||
return true;
|
||||
|
||||
if (strcmp(network, "any") == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
httpd_peer_is_trusted(struct evhttp_request *req)
|
||||
httpd_admin_check_auth(struct evhttp_request *req)
|
||||
{
|
||||
struct evhttp_connection *evcon;
|
||||
char *addr;
|
||||
uint16_t port;
|
||||
const char *passwd;
|
||||
int ret;
|
||||
|
||||
evcon = evhttp_request_get_connection(req);
|
||||
if (!evcon)
|
||||
@ -1447,16 +1425,8 @@ httpd_peer_is_trusted(struct evhttp_request *req)
|
||||
}
|
||||
|
||||
evhttp_connection_get_peer(evcon, &addr, &port);
|
||||
return peer_address_is_trusted(addr);
|
||||
}
|
||||
|
||||
bool
|
||||
httpd_admin_check_auth(struct evhttp_request *req)
|
||||
{
|
||||
const char *passwd;
|
||||
int ret;
|
||||
|
||||
if (httpd_peer_is_trusted(req))
|
||||
if (peer_address_is_trusted(addr))
|
||||
return true;
|
||||
|
||||
passwd = cfg_getstr(cfg_getsec(cfg, "general"), "admin_password");
|
||||
|
@ -51,6 +51,9 @@ struct httpd_request {
|
||||
struct evkeyvalq *query;
|
||||
// http request struct (if available)
|
||||
struct evhttp_request *req;
|
||||
// Source IP address (ipv4 or ipv6) and port of the request (if available)
|
||||
char *peer_address;
|
||||
unsigned short peer_port;
|
||||
// A pointer to extra data that the module handling the request might need
|
||||
void *extra_data;
|
||||
|
||||
@ -147,12 +150,6 @@ httpd_redirect_to_admin(struct evhttp_request *req);
|
||||
void
|
||||
httpd_redirect_to_index(struct evhttp_request *req, const char *uri);
|
||||
|
||||
bool
|
||||
peer_address_is_trusted(const char *addr);
|
||||
|
||||
bool
|
||||
httpd_peer_is_trusted(struct evhttp_request *req);
|
||||
|
||||
bool
|
||||
httpd_admin_check_auth(struct evhttp_request *req);
|
||||
|
||||
|
@ -715,7 +715,7 @@ daap_request_authorize(struct httpd_request *hreq)
|
||||
char *passwd;
|
||||
int ret;
|
||||
|
||||
if (httpd_peer_is_trusted(hreq->req))
|
||||
if (peer_address_is_trusted(hreq->peer_address))
|
||||
return 0;
|
||||
|
||||
param = evhttp_find_header(hreq->query, "session-id");
|
||||
@ -913,11 +913,11 @@ daap_reply_login(struct httpd_request *hreq)
|
||||
CHECK_ERR(L_DAAP, evbuffer_expand(hreq->reply, 32));
|
||||
|
||||
param = evhttp_find_header(hreq->query, "pairing-guid");
|
||||
if (param && !httpd_peer_is_trusted(hreq->req))
|
||||
if (param && !peer_address_is_trusted(hreq->peer_address))
|
||||
{
|
||||
if (strlen(param) < 3)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Login attempt with invalid pairing-guid: %s\n", param);
|
||||
DPRINTF(E_LOG, L_DAAP, "Login attempt from %s with invalid pairing-guid: %s\n", hreq->peer_address, param);
|
||||
return DAAP_REPLY_FORBIDDEN;
|
||||
}
|
||||
|
||||
@ -927,20 +927,20 @@ daap_reply_login(struct httpd_request *hreq)
|
||||
ret = db_pairing_fetch_byguid(&pi);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "Login attempt with invalid pairing-guid: %s\n", param);
|
||||
DPRINTF(E_LOG, L_DAAP, "Login attempt from %s with invalid pairing-guid: %s\n", hreq->peer_address, param);
|
||||
free_pi(&pi, 1);
|
||||
return DAAP_REPLY_FORBIDDEN;
|
||||
}
|
||||
|
||||
DPRINTF(E_INFO, L_DAAP, "Remote '%s' logging in with GUID %s\n", pi.name, pi.guid);
|
||||
DPRINTF(E_INFO, L_DAAP, "Remote '%s' (%s) logging in with GUID %s\n", pi.name, hreq->peer_address, pi.guid);
|
||||
free_pi(&pi, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hreq->user_agent)
|
||||
DPRINTF(E_INFO, L_DAAP, "Client '%s' logging in\n", hreq->user_agent);
|
||||
DPRINTF(E_INFO, L_DAAP, "Client '%s' logging in from %s\n", hreq->user_agent, hreq->peer_address);
|
||||
else
|
||||
DPRINTF(E_INFO, L_DAAP, "Client (unknown user-agent) logging in\n");
|
||||
DPRINTF(E_INFO, L_DAAP, "Client (unknown user-agent) logging in from %s\n", hreq->peer_address);
|
||||
}
|
||||
|
||||
param = evhttp_find_header(hreq->query, "request-session-id");
|
||||
|
@ -547,7 +547,7 @@ dacp_request_authorize(struct httpd_request *hreq)
|
||||
int32_t id;
|
||||
int ret;
|
||||
|
||||
if (httpd_peer_is_trusted(hreq->req))
|
||||
if (peer_address_is_trusted(hreq->peer_address))
|
||||
return 0;
|
||||
|
||||
param = evhttp_find_header(hreq->query, "session-id");
|
||||
|
@ -284,7 +284,7 @@ rsp_request_authorize(struct httpd_request *hreq)
|
||||
char *passwd;
|
||||
int ret;
|
||||
|
||||
if (httpd_peer_is_trusted(hreq->req))
|
||||
if (peer_address_is_trusted(hreq->peer_address))
|
||||
return 0;
|
||||
|
||||
passwd = cfg_getstr(cfg_getsec(cfg, "library"), "password");
|
||||
|
40
src/misc.c
40
src/misc.c
@ -43,6 +43,7 @@
|
||||
#include <uniconv.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "conffile.h"
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
@ -992,6 +993,45 @@ murmur_hash64(const void *key, int len, uint32_t seed)
|
||||
# error Platform not supported
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
peer_address_is_trusted(const char *addr)
|
||||
{
|
||||
cfg_t *section;
|
||||
const char *network;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (!addr)
|
||||
return false;
|
||||
|
||||
if (strncmp(addr, "::ffff:", strlen("::ffff:")) == 0)
|
||||
addr += strlen("::ffff:");
|
||||
|
||||
section = cfg_getsec(cfg, "general");
|
||||
|
||||
n = cfg_size(section, "trusted_networks");
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
network = cfg_getnstr(section, "trusted_networks", i);
|
||||
|
||||
if (!network || network[0] == '\0')
|
||||
return false;
|
||||
|
||||
if (strncmp(network, addr, strlen(network)) == 0)
|
||||
return true;
|
||||
|
||||
if ((strcmp(network, "localhost") == 0) && (strcmp(addr, "127.0.0.1") == 0 || strcmp(addr, "::1") == 0))
|
||||
return true;
|
||||
|
||||
if (strcmp(network, "any") == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
clock_gettime_with_res(clockid_t clock_id, struct timespec *tp, struct timespec *res)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@ -104,6 +105,12 @@ b64_encode(const uint8_t *in, size_t len);
|
||||
uint64_t
|
||||
murmur_hash64(const void *key, int len, uint32_t seed);
|
||||
|
||||
|
||||
/* Checks if the address is in a network that is configured as trusted */
|
||||
bool
|
||||
peer_address_is_trusted(const char *addr);
|
||||
|
||||
|
||||
#ifndef HAVE_CLOCK_GETTIME
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
|
14
src/mpd.c
14
src/mpd.c
@ -36,6 +36,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/buffer.h>
|
||||
@ -43,9 +44,6 @@
|
||||
#include <event2/http.h>
|
||||
#include <event2/listener.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "artwork.h"
|
||||
#include "commands.h"
|
||||
@ -4614,26 +4612,28 @@ mpd_input_filter(struct evbuffer *src, struct evbuffer *dst, ev_ssize_t lim, enu
|
||||
return BEV_OK;
|
||||
}
|
||||
|
||||
/* |:todo:| This should probably go somewhere else. */
|
||||
static const char *
|
||||
sockaddr_to_string(const struct sockaddr *address, char *addr_str, int addr_str_len)
|
||||
{
|
||||
struct sockaddr_in *addr;
|
||||
struct sockaddr_in6 *addr6;
|
||||
const char *ret;
|
||||
|
||||
if (address->sa_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)address;
|
||||
addr = (struct sockaddr_in *)address;
|
||||
ret = evutil_inet_ntop(AF_INET, &addr->sin_addr, addr_str, addr_str_len);
|
||||
}
|
||||
else if (address->sa_family == AF_INET6)
|
||||
{
|
||||
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)address;
|
||||
addr6 = (struct sockaddr_in6 *)address;
|
||||
ret = evutil_inet_ntop(AF_INET6, &addr6->sin6_addr, addr_str, addr_str_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4659,6 +4659,7 @@ mpd_accept_conn_cb(struct evconnlistener *listener,
|
||||
struct event_base *base = evconnlistener_get_base(listener);
|
||||
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));
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
|
||||
if (!cmd_ctx)
|
||||
{
|
||||
@ -4670,7 +4671,6 @@ mpd_accept_conn_cb(struct evconnlistener *listener,
|
||||
cmd_ctx->authenticated = !cfg_getstr(cfg_getsec(cfg, "library"), "password");
|
||||
if (!cmd_ctx->authenticated)
|
||||
{
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
sockaddr_to_string(address, addr_str, sizeof(addr_str));
|
||||
cmd_ctx->authenticated = peer_address_is_trusted(addr_str);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user