diff options
author | Federico Ceratto <federico.ceratto@gmail.com> | 2017-12-19 23:39:21 +0000 |
---|---|---|
committer | Federico Ceratto <federico.ceratto@gmail.com> | 2017-12-19 23:39:21 +0000 |
commit | 61aedf201c2c4bf0e5aa4db32e74f4d860b88593 (patch) | |
tree | bcf4f9a0cd8bc2daf38b2ff9f29bfcc1e5ed8968 /src/socket.c | |
parent | New upstream version 1.8.0+dfsg (diff) | |
download | netdata-61aedf201c2c4bf0e5aa4db32e74f4d860b88593.tar.xz netdata-61aedf201c2c4bf0e5aa4db32e74f4d860b88593.zip |
New upstream version 1.9.0+dfsgupstream/1.9.0+dfsg
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/src/socket.c b/src/socket.c index d28df81a6..906ab33dd 100644 --- a/src/socket.c +++ b/src/socket.c @@ -857,7 +857,7 @@ int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) { // -------------------------------------------------------------------------------------------------------------------- // accept_socket() - accept a socket and store client IP and port -int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize) { +int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *client_port, size_t portsize, SIMPLE_PATTERN *access_list) { struct sockaddr_storage sadr; socklen_t addrlen = sizeof(sadr); @@ -873,6 +873,13 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien client_port[portsize - 1] = '\0'; switch (((struct sockaddr *)&sadr)->sa_family) { + case AF_UNIX: + debug(D_LISTENER, "New UNIX domain web client from %s on socket %d.", client_ip, fd); + // set the port - certain versions of libc return garbage on unix sockets + strncpy(client_port, "UNIX", portsize); + client_port[portsize - 1] = '\0'; + break; + case AF_INET: debug(D_LISTENER, "New IPv4 web client from %s port %s on socket %d.", client_ip, client_port, fd); break; @@ -881,7 +888,8 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien if (strncmp(client_ip, "::ffff:", 7) == 0) { memmove(client_ip, &client_ip[7], strlen(&client_ip[7]) + 1); debug(D_LISTENER, "New IPv4 web client from %s port %s on socket %d.", client_ip, client_port, fd); - } else + } + else debug(D_LISTENER, "New IPv6 web client from %s port %s on socket %d.", client_ip, client_port, fd); break; @@ -889,6 +897,22 @@ int accept_socket(int fd, int flags, char *client_ip, size_t ipsize, char *clien debug(D_LISTENER, "New UNKNOWN web client from %s port %s on socket %d.", client_ip, client_port, fd); break; } + + if(access_list) { + if(!strcmp(client_ip, "127.0.0.1") || !strcmp(client_ip, "::1")) { + strncpy(client_ip, "localhost", ipsize); + client_ip[ipsize - 1] = '\0'; + } + + if(unlikely(!simple_pattern_matches(access_list, client_ip))) { + errno = 0; + debug(D_LISTENER, "Permission denied for client '%s', port '%s'", client_ip, client_port); + error("DENIED ACCESS to client '%s'", client_ip); + close(nfd); + nfd = -1; + errno = EPERM; + } + } } #ifdef HAVE_ACCEPT4 else if(errno == ENOSYS) @@ -928,8 +952,8 @@ struct poll { struct pollinfo *inf; struct pollinfo *first_free; - void *(*add_callback)(int fd, short int *events); - void (*del_callback)(int fd, void *data); + void *(*add_callback)(int fd, int socktype, short int *events); + void (*del_callback)(int fd, int socktype, void *data); int (*rcv_callback)(int fd, int socktype, void *data, short int *events); int (*snd_callback)(int fd, int socktype, void *data, short int *events); }; @@ -984,7 +1008,7 @@ static inline struct pollinfo *poll_add_fd(struct poll *p, int fd, int socktype, p->max = pi->slot; if(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET) { - pi->data = p->add_callback(fd, &pf->events); + pi->data = p->add_callback(fd, pi->socktype, &pf->events); } if(pi->flags & POLLINFO_FLAG_SERVER_SOCKET) { @@ -1003,7 +1027,7 @@ static inline void poll_close_fd(struct poll *p, struct pollinfo *pi) { if(unlikely(pf->fd == -1)) return; if(pi->flags & POLLINFO_FLAG_CLIENT_SOCKET) { - p->del_callback(pf->fd, pi->data); + p->del_callback(pf->fd, pi->socktype, pi->data); } close(pf->fd); @@ -1036,14 +1060,16 @@ static inline void poll_close_fd(struct poll *p, struct pollinfo *pi) { debug(D_POLLFD, "POLLFD: DEL: completed, slots = %zu, used = %zu, min = %zu, max = %zu, next free = %zd", p->slots, p->used, p->min, p->max, p->first_free?(ssize_t)p->first_free->slot:(ssize_t)-1); } -static void *add_callback_default(int fd, short int *events) { +static void *add_callback_default(int fd, int socktype, short int *events) { (void)fd; + (void)socktype; (void)events; return NULL; } -static void del_callback_default(int fd, void *data) { +static void del_callback_default(int fd, int socktype, void *data) { (void)fd; + (void)socktype; (void)data; if(data) @@ -1100,10 +1126,11 @@ void poll_events_cleanup(void *data) { } void poll_events(LISTEN_SOCKETS *sockets - , void *(*add_callback)(int fd, short int *events) - , void (*del_callback)(int fd, void *data) + , void *(*add_callback)(int fd, int socktype, short int *events) + , void (*del_callback)(int fd, int socktype, void *data) , int (*rcv_callback)(int fd, int socktype, void *data, short int *events) , int (*snd_callback)(int fd, int socktype, void *data, short int *events) + , SIMPLE_PATTERN *access_list , void *data ) { int retval; @@ -1182,7 +1209,7 @@ void poll_events(LISTEN_SOCKETS *sockets char client_port[NI_MAXSERV + 1]; debug(D_POLLFD, "POLLFD: LISTENER: calling accept4() slot %zu (fd %d)", i, fd); - nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1); + nfd = accept_socket(fd, SOCK_NONBLOCK, client_ip, NI_MAXHOST + 1, client_port, NI_MAXSERV + 1, access_list); if (nfd < 0) { // accept failed @@ -1212,6 +1239,8 @@ void poll_events(LISTEN_SOCKETS *sockets debug(D_POLLFD, "POLLFD: LISTENER: reading data from UDP slot %zu (fd %d)", i, fd); + // FIXME: access_list is not applied to UDP + p.rcv_callback(fd, pi->socktype, pi->data, &pf->events); break; } |