0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-05-04 09:10:31 +00:00
netdata_netdata/libnetdata/socket/socket.h
Andrew Moss 187620911c Allow hostnames in Access Control Lists ()
##### Summary
The Access Control List (ACL) configuration parameters can now use hostnames with simple patterns. Incoming connections are resolved using reverse DNS to obtain the hostname. Where a hostname is resolved, forward DNS resolution is performed to check the IP address is really associated with the hostname. If the checks pass then the patterns supplied are checked. Any patterns supplied for numeric ip addresses are also checked.

##### Component Name
daemon

##### Additional Information
Fixes 

* Reverse lookup on ip to get hostname
* Forward lookup on hostname to get IP addresses.
* Validation that the incomming ip is associated with the host.

If these checks fail the hostname is discarded so it cannot match against the access-list
patterns. If these checks validate the ip successfully then the resolved hostname is
pattern-matched as described in the previous commit.
2019-09-18 16:45:52 +02:00

204 lines
8.3 KiB
C

// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef NETDATA_SOCKET_H
#define NETDATA_SOCKET_H
#include "../libnetdata.h"
#ifndef MAX_LISTEN_FDS
#define MAX_LISTEN_FDS 50
#endif
typedef enum web_client_acl {
WEB_CLIENT_ACL_NONE = 0,
WEB_CLIENT_ACL_NOCHECK = 0,
WEB_CLIENT_ACL_DASHBOARD = 1 << 0,
WEB_CLIENT_ACL_REGISTRY = 1 << 1,
WEB_CLIENT_ACL_BADGE = 1 << 2,
WEB_CLIENT_ACL_MGMT = 1 << 3,
WEB_CLIENT_ACL_STREAMING = 1 << 4,
WEB_CLIENT_ACL_NETDATACONF = 1 << 5,
WEB_CLIENT_ACL_SSL_OPTIONAL = 1 << 6,
WEB_CLIENT_ACL_SSL_FORCE = 1 << 7,
WEB_CLIENT_ACL_SSL_DEFAULT = 1 << 8
} WEB_CLIENT_ACL;
#define web_client_can_access_dashboard(w) ((w)->acl & WEB_CLIENT_ACL_DASHBOARD)
#define web_client_can_access_registry(w) ((w)->acl & WEB_CLIENT_ACL_REGISTRY)
#define web_client_can_access_badges(w) ((w)->acl & WEB_CLIENT_ACL_BADGE)
#define web_client_can_access_mgmt(w) ((w)->acl & WEB_CLIENT_ACL_MGMT)
#define web_client_can_access_stream(w) ((w)->acl & WEB_CLIENT_ACL_STREAMING)
#define web_client_can_access_netdataconf(w) ((w)->acl & WEB_CLIENT_ACL_NETDATACONF)
#define web_client_is_using_ssl_optional(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_OPTIONAL)
#define web_client_is_using_ssl_force(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_FORCE)
#define web_client_is_using_ssl_default(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_DEFAULT)
typedef struct listen_sockets {
struct config *config; // the config file to use
const char *config_section; // the netdata configuration section to read settings from
const char *default_bind_to; // the default bind to configuration string
uint16_t default_port; // the default port to use
int backlog; // the default listen backlog to use
size_t opened; // the number of sockets opened
size_t failed; // the number of sockets attempted to open, but failed
int fds[MAX_LISTEN_FDS]; // the open sockets
char *fds_names[MAX_LISTEN_FDS]; // descriptions for the open sockets
int fds_types[MAX_LISTEN_FDS]; // the socktype for the open sockets (SOCK_STREAM, SOCK_DGRAM)
int fds_families[MAX_LISTEN_FDS]; // the family of the open sockets (AF_UNIX, AF_INET, AF_INET6)
WEB_CLIENT_ACL fds_acl_flags[MAX_LISTEN_FDS]; // the acl to apply to the open sockets (dashboard, badges, streaming, netdata.conf, management)
} LISTEN_SOCKETS;
extern char *strdup_client_description(int family, const char *protocol, const char *ip, uint16_t port);
extern int listen_sockets_setup(LISTEN_SOCKETS *sockets);
extern void listen_sockets_close(LISTEN_SOCKETS *sockets);
extern int connect_to_this(const char *definition, int default_port, struct timeval *timeout);
extern int connect_to_one_of(const char *destination, int default_port, struct timeval *timeout, size_t *reconnects_counter, char *connected_to, size_t connected_to_size);
#ifdef ENABLE_HTTPS
extern ssize_t recv_timeout(struct netdata_ssl *ssl,int sockfd, void *buf, size_t len, int flags, int timeout);
extern ssize_t send_timeout(struct netdata_ssl *ssl,int sockfd, void *buf, size_t len, int flags, int timeout);
#else
extern ssize_t recv_timeout(int sockfd, void *buf, size_t len, int flags, int timeout);
extern ssize_t send_timeout(int sockfd, void *buf, size_t len, int flags, int timeout);
#endif
extern int sock_setnonblock(int fd);
extern int sock_delnonblock(int fd);
extern int sock_setreuse(int fd, int reuse);
extern int sock_setreuse_port(int fd, int reuse);
extern int sock_enlarge_in(int fd);
extern int sock_enlarge_out(int fd);
extern int connection_allowed(int fd, char *client_ip, char *client_host, size_t hostsize,
SIMPLE_PATTERN *access_list, const char *patname);
extern int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize,
char *client_host, size_t hostsize, SIMPLE_PATTERN *access_list);
#ifndef HAVE_ACCEPT4
extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
#ifndef SOCK_NONBLOCK
#define SOCK_NONBLOCK 00004000
#endif /* #ifndef SOCK_NONBLOCK */
#ifndef SOCK_CLOEXEC
#define SOCK_CLOEXEC 02000000
#endif /* #ifndef SOCK_CLOEXEC */
#endif /* #ifndef HAVE_ACCEPT4 */
// ----------------------------------------------------------------------------
// poll() based listener
#define POLLINFO_FLAG_SERVER_SOCKET 0x00000001
#define POLLINFO_FLAG_CLIENT_SOCKET 0x00000002
#define POLLINFO_FLAG_DONT_CLOSE 0x00000004
typedef struct poll POLLJOB;
typedef struct pollinfo {
POLLJOB *p; // the parent
size_t slot; // the slot id
int fd; // the file descriptor
int socktype; // the client socket type
WEB_CLIENT_ACL port_acl; // the access lists permitted on this web server port (it's -1 for client sockets)
char *client_ip; // Max INET6_ADDRSTRLEN bytes
char *client_port; // Max NI_MAXSERV bytes
char *client_host; // Max NI_MAXHOST bytes
time_t connected_t; // the time the socket connected
time_t last_received_t; // the time the socket last received data
time_t last_sent_t; // the time the socket last sent data
size_t recv_count; // the number of times the socket was ready for inbound traffic
size_t send_count; // the number of times the socket was ready for outbound traffic
uint32_t flags; // internal flags
// callbacks for this socket
void (*del_callback)(struct pollinfo *pi);
int (*rcv_callback)(struct pollinfo *pi, short int *events);
int (*snd_callback)(struct pollinfo *pi, short int *events);
// the user data
void *data;
// linking of free pollinfo structures
// for quickly finding the next available
// this is like a stack, it grows and shrinks
// (with gaps - lower empty slots are preferred)
struct pollinfo *next;
} POLLINFO;
struct poll {
size_t slots;
size_t used;
size_t min;
size_t max;
size_t limit;
time_t complete_request_timeout;
time_t idle_timeout;
time_t checks_every;
time_t timer_milliseconds;
void *timer_data;
struct pollfd *fds;
struct pollinfo *inf;
struct pollinfo *first_free;
SIMPLE_PATTERN *access_list;
void *(*add_callback)(POLLINFO *pi, short int *events, void *data);
void (*del_callback)(POLLINFO *pi);
int (*rcv_callback)(POLLINFO *pi, short int *events);
int (*snd_callback)(POLLINFO *pi, short int *events);
void (*tmr_callback)(void *timer_data);
};
#define pollinfo_from_slot(p, slot) (&((p)->inf[(slot)]))
extern int poll_default_snd_callback(POLLINFO *pi, short int *events);
extern int poll_default_rcv_callback(POLLINFO *pi, short int *events);
extern void poll_default_del_callback(POLLINFO *pi);
extern void *poll_default_add_callback(POLLINFO *pi, short int *events, void *data);
extern POLLINFO *poll_add_fd(POLLJOB *p
, int fd
, int socktype
, WEB_CLIENT_ACL port_acl
, uint32_t flags
, const char *client_ip
, const char *client_port
, const char *client_host
, void *(*add_callback)(POLLINFO *pi, short int *events, void *data)
, void (*del_callback)(POLLINFO *pi)
, int (*rcv_callback)(POLLINFO *pi, short int *events)
, int (*snd_callback)(POLLINFO *pi, short int *events)
, void *data
);
extern void poll_close_fd(POLLINFO *pi);
extern void poll_events(LISTEN_SOCKETS *sockets
, void *(*add_callback)(POLLINFO *pi, short int *events, void *data)
, void (*del_callback)(POLLINFO *pi)
, int (*rcv_callback)(POLLINFO *pi, short int *events)
, int (*snd_callback)(POLLINFO *pi, short int *events)
, void (*tmr_callback)(void *timer_data)
, SIMPLE_PATTERN *access_list
, void *data
, time_t tcp_request_timeout_seconds
, time_t tcp_idle_timeout_seconds
, time_t timer_milliseconds
, void *timer_data
, size_t max_tcp_sockets
);
#endif //NETDATA_SOCKET_H