Imported Upstream version 3.0.1
This commit is contained in:
@@ -10,6 +10,9 @@ srcdir=@srcdir@
|
||||
SRC_INCLUDE=@srcdir@/../include
|
||||
CFG_INCLUDE=../include
|
||||
|
||||
# Mainly used for rpmbuild
|
||||
# DESTDIR=
|
||||
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@ @DEFS@ -I $(CFG_INCLUDE) -I $(SRC_INCLUDE)
|
||||
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||
@@ -19,16 +22,22 @@ OTHERLIBS=@OTHERLIBS@
|
||||
|
||||
CP=@CP@
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
CFGDIR=@sysconfdir@
|
||||
BINDIR=@bindir@
|
||||
SBINDIR=@sbindir@
|
||||
LIBEXECDIR=@libexecdir@
|
||||
prefix=$(DESTDIR)@prefix@
|
||||
exec_prefix=$(DESTDIR)@exec_prefix@
|
||||
CFGDIR=$(DESTDIR)@pkgsysconfdir@
|
||||
BINDIR=$(DESTDIR)@bindir@
|
||||
SBINDIR=$(DESTDIR)@sbindir@
|
||||
LIBEXECDIR=$(DESTDIR)@libexecdir@
|
||||
INSTALL=@INSTALL@
|
||||
NAGIOS_INSTALL_OPTS=@NAGIOS_INSTALL_OPTS@
|
||||
NRPE_INSTALL_OPTS=@NRPE_INSTALL_OPTS@
|
||||
|
||||
PLUGINSDIR=$(DESTDIR)@pluginsdir@
|
||||
PIDDIR=$(DESTDIR)@piddir@
|
||||
TMPFILESDIR=$(DESTDIR)@tmpfilesd@
|
||||
SRC_TMPFILE=@src_tmpfile@
|
||||
|
||||
|
||||
# Generated automatically from configure script
|
||||
SNPRINTF_O=@SNPRINTF_O@
|
||||
|
||||
@@ -39,19 +48,33 @@ nrpe: $(srcdir)/nrpe.c $(srcdir)/utils.c $(srcdir)/acl.c $(SRC_INCLUDE)/nrpe.h $
|
||||
$(CC) $(CFLAGS) -o $@ $(srcdir)/nrpe.c $(srcdir)/utils.c $(srcdir)/acl.c $(LDFLAGS) $(SOCKETLIBS) $(LIBWRAPLIBS) $(SNPRINTF_O) $(OTHERLIBS)
|
||||
|
||||
check_nrpe: $(srcdir)/check_nrpe.c $(srcdir)/utils.c $(SRC_INCLUDE)/utils.h $(SRC_INCLUDE)/common.h $(CFG_INCLUDE)/config.h
|
||||
$(CC) $(CFLAGS) -o $@ $(srcdir)/check_nrpe.c $(srcdir)/utils.c $(LDFLAGS) $(SOCKETLIBS) $(OTHERLIBS)
|
||||
$(CC) $(CFLAGS) -o $@ $(srcdir)/check_nrpe.c $(srcdir)/utils.c $(LDFLAGS) $(SOCKETLIBS) $(SNPRINTF_O) $(OTHERLIBS)
|
||||
|
||||
install:
|
||||
$(MAKE) install-plugin
|
||||
$(MAKE) install-daemon
|
||||
|
||||
install-plugin:
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) -d $(DESTDIR)$(LIBEXECDIR)
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) check_nrpe $(DESTDIR)$(LIBEXECDIR)
|
||||
install-plugin: install-uninstall
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) -d $(LIBEXECDIR)
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) -d $(PLUGINSDIR)
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) check_nrpe $(PLUGINSDIR)
|
||||
|
||||
install-daemon:
|
||||
$(INSTALL) -m 775 $(NAGIOS_INSTALL_OPTS) -d $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -m 775 $(NRPE_INSTALL_OPTS) nrpe $(DESTDIR)$(BINDIR)
|
||||
install-daemon: install-uninstall
|
||||
$(INSTALL) -m 755 nrpe $(SBINDIR)
|
||||
@if test ! -d "$(PIDDIR)" ; then \
|
||||
echo $(INSTALL) -m 755 $(NRPE_INSTALL_OPTS) -d $(PIDDIR); \
|
||||
$(INSTALL) -m 755 $(NRPE_INSTALL_OPTS) -d $(PIDDIR); \
|
||||
fi
|
||||
@if test "$(TMPFILESDIR)" != "N/A" -a x$(SRC_TMPFILE) != x ; then \
|
||||
echo $(INSTALL) -m 755 -d `dirname $(TMPFILESDIR)`; \
|
||||
$(INSTALL) -m 755 -d `dirname $(TMPFILESDIR)`; \
|
||||
echo $(INSTALL) -m 644 ../startup/$(SRC_TMPFILE) $(TMPFILESDIR); \
|
||||
$(INSTALL) -m 644 ../startup/$(SRC_TMPFILE) $(TMPFILESDIR); \
|
||||
fi
|
||||
|
||||
install-uninstall:
|
||||
$(INSTALL) -m 755 -d $(SBINDIR)
|
||||
$(INSTALL) -m 755 ../uninstall $(SBINDIR)/nrpe-uninstall
|
||||
|
||||
clean:
|
||||
rm -f core nrpe check_nrpe $(SNPRINTF_O)
|
||||
|
||||
103
src/acl.c
103
src/acl.c
@@ -28,6 +28,8 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "../include/config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -256,8 +258,7 @@ int add_ipv4_to_acl(char *ipv4) {
|
||||
|
||||
int add_ipv6_to_acl(char *ipv6) {
|
||||
char *ipv6tmp;
|
||||
char *addrtok;
|
||||
char *addrsave;
|
||||
char *addr_part, *mask_part;
|
||||
struct in6_addr addr;
|
||||
struct in6_addr mask;
|
||||
int maskval;
|
||||
@@ -275,23 +276,25 @@ int add_ipv6_to_acl(char *ipv6) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_part = ipv6tmp;
|
||||
mask_part = strchr(ipv6tmp, '/');
|
||||
if (mask_part) {
|
||||
*mask_part = '\0';
|
||||
++mask_part;
|
||||
}
|
||||
|
||||
/* Parse the address itself */
|
||||
addrtok = strtok_r(ipv6tmp, "/", &addrsave);
|
||||
if(inet_pton(AF_INET6, addrtok, &addr) <= 0) {
|
||||
syslog(LOG_ERR, "Invalid IPv6 address in ACL: %s\n", ipv6);
|
||||
if(inet_pton(AF_INET6, addr_part, &addr) <= 0) {
|
||||
free(ipv6tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check whether there is a netmask */
|
||||
addrtok = strtok_r(NULL, "/", &addrsave);
|
||||
if(NULL != addrtok) {
|
||||
if (mask_part && *mask_part) {
|
||||
/* If so, build a netmask */
|
||||
|
||||
/* Get the number of bits in the mask */
|
||||
maskval = atoi(addrtok);
|
||||
maskval = atoi(mask_part);
|
||||
if(maskval < 0 || maskval > 128) {
|
||||
syslog(LOG_ERR, "Invalid IPv6 netmask in ACL: %s\n", ipv6);
|
||||
free(ipv6tmp);
|
||||
return 0;
|
||||
}
|
||||
@@ -458,14 +461,15 @@ int add_domain_to_acl(char *domain) {
|
||||
* 0 - on failure
|
||||
*/
|
||||
|
||||
int is_an_allowed_host(int family, void *host) {
|
||||
struct ip_acl *ip_acl_curr = ip_acl_head;
|
||||
int nbytes;
|
||||
int x;
|
||||
struct dns_acl *dns_acl_curr = dns_acl_head;
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
struct hostent *he;
|
||||
int is_an_allowed_host(int family, void *host)
|
||||
{
|
||||
struct ip_acl *ip_acl_curr = ip_acl_head;
|
||||
int nbytes;
|
||||
int x;
|
||||
struct dns_acl *dns_acl_curr = dns_acl_head;
|
||||
struct sockaddr_in *addr;
|
||||
struct sockaddr_in6 addr6;
|
||||
struct addrinfo *res, *ai;
|
||||
|
||||
while (ip_acl_curr != NULL) {
|
||||
if(ip_acl_curr->family == family) {
|
||||
@@ -498,34 +502,31 @@ int is_an_allowed_host(int family, void *host) {
|
||||
}
|
||||
|
||||
while(dns_acl_curr != NULL) {
|
||||
he = gethostbyname(dns_acl_curr->domain);
|
||||
if (he == NULL) return 0;
|
||||
if (!getaddrinfo(dns_acl_curr->domain, NULL, NULL, &res)) {
|
||||
|
||||
while (*he->h_addr_list) {
|
||||
switch(he->h_addrtype) {
|
||||
case AF_INET:
|
||||
memmove((char *)&addr,*he->h_addr_list++, sizeof(addr));
|
||||
if (addr.s_addr == ((struct in_addr *)host)->s_addr) return 1;
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy((char *)&addr6, *he->h_addr_list++, sizeof(addr6));
|
||||
for(x = 0; x < nbytes; x++) {
|
||||
if(addr6.s6_addr[x] !=
|
||||
((struct in6_addr *)host)->s6_addr[x]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(x == nbytes) {
|
||||
/* All bytes in host's address match the ACL */
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
for (ai = res; ai; ai = ai->ai_next) {
|
||||
|
||||
switch(ai->ai_family) {
|
||||
|
||||
case AF_INET:
|
||||
addr = (struct sockaddr_in*)(ai->ai_addr);
|
||||
if (addr->sin_addr.s_addr == ((struct in_addr*)host)->s_addr)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
memcpy((char*)&addr6, ai->ai_addr, sizeof(addr6));
|
||||
if (!memcmp(&addr6.sin6_addr, &host, sizeof(addr6.sin6_addr)))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dns_acl_curr = dns_acl_curr->next;
|
||||
|
||||
dns_acl_curr = dns_acl_curr->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The trim() function takes a source string and copies it to the destination string,
|
||||
* stripped of leading and training whitespace. The destination string must be
|
||||
@@ -535,8 +536,8 @@ int is_an_allowed_host(int family, void *host) {
|
||||
void trim( char *src, char *dest) {
|
||||
char *sptr, *dptr;
|
||||
|
||||
for( sptr = src; isblank( *sptr) && *sptr; sptr++); /* Jump past leading spaces */
|
||||
for( dptr = dest; !isblank( *sptr) && *sptr; ) {
|
||||
for( sptr = src; isspace( *sptr) && *sptr; sptr++); /* Jump past leading spaces */
|
||||
for( dptr = dest; !isspace( *sptr) && *sptr; ) {
|
||||
*dptr = *sptr;
|
||||
sptr++;
|
||||
dptr++;
|
||||
@@ -545,20 +546,24 @@ void trim( char *src, char *dest) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function splits allowed_hosts to substrings with comma(,) as a delimeter.
|
||||
/* This function splits allowed_hosts to substrings with comma(,) as a delimiter.
|
||||
* It doesn't check validness of ACL record (add_ipv4_to_acl() and add_domain_to_acl() do),
|
||||
* just trims spaces from ACL records.
|
||||
* After this it sends ACL records to add_ipv4_to_acl() or add_domain_to_acl().
|
||||
*/
|
||||
|
||||
void parse_allowed_hosts(char *allowed_hosts) {
|
||||
char *hosts = strdup( allowed_hosts); /* Copy since strtok* modifes original */
|
||||
char *hosts = strdup( allowed_hosts); /* Copy since strtok* modifies original */
|
||||
char *saveptr;
|
||||
char *tok;
|
||||
const char *delim = ",";
|
||||
char *trimmed_tok;
|
||||
|
||||
tok = strtok_r( hosts, delim, &saveptr);
|
||||
#ifdef HAVE_STRTOK_R
|
||||
tok = strtok_r(hosts, delim, &saveptr);
|
||||
#else
|
||||
tok = strtok(hosts, delim);
|
||||
#endif
|
||||
while( tok) {
|
||||
trimmed_tok = malloc( sizeof( char) * ( strlen( tok) + 1));
|
||||
trim( tok, trimmed_tok);
|
||||
@@ -569,7 +574,11 @@ void parse_allowed_hosts(char *allowed_hosts) {
|
||||
}
|
||||
}
|
||||
free( trimmed_tok);
|
||||
tok = strtok_r(( char *)0, delim, &saveptr);
|
||||
#ifdef HAVE_STRTOK_R
|
||||
tok = strtok_r(NULL, delim, &saveptr);
|
||||
#else
|
||||
tok = strtok(NULL, delim);
|
||||
#endif
|
||||
}
|
||||
|
||||
free( hosts);
|
||||
|
||||
1686
src/check_nrpe.c
1686
src/check_nrpe.c
File diff suppressed because it is too large
Load Diff
3800
src/nrpe.c
3800
src/nrpe.c
File diff suppressed because it is too large
Load Diff
@@ -270,7 +270,7 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
|
||||
struct pr_chunk *cnk = NULL;
|
||||
struct pr_chunk_x *clist = NULL;
|
||||
int max_pos;
|
||||
size_t ret = -1;
|
||||
size_t ret = (size_t)-1;
|
||||
|
||||
VA_COPY(args, args_in);
|
||||
|
||||
|
||||
453
src/utils.c
453
src/utils.c
@@ -32,58 +32,64 @@
|
||||
#include "../include/common.h"
|
||||
#include "../include/utils.h"
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
extern int asprintf(char **ptr, const char *format, ...);
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 32
|
||||
# define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
# define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
static unsigned long crc32_table[256];
|
||||
|
||||
static int my_create_socket(struct addrinfo *ai, const char *bind_address);
|
||||
|
||||
|
||||
/* build the crc table - must be called before calculating the crc value */
|
||||
void generate_crc32_table(void){
|
||||
void generate_crc32_table(void)
|
||||
{
|
||||
unsigned long crc, poly;
|
||||
int i, j;
|
||||
|
||||
poly=0xEDB88320L;
|
||||
for(i=0;i<256;i++){
|
||||
crc=i;
|
||||
for(j=8;j>0;j--){
|
||||
if(crc & 1)
|
||||
crc=(crc>>1)^poly;
|
||||
poly = 0xEDB88320L;
|
||||
for (i = 0; i < 256; i++) {
|
||||
crc = i;
|
||||
for (j = 8; j > 0; j--) {
|
||||
if (crc & 1)
|
||||
crc = (crc >> 1) ^ poly;
|
||||
else
|
||||
crc>>=1;
|
||||
}
|
||||
crc32_table[i]=crc;
|
||||
}
|
||||
crc >>= 1;
|
||||
}
|
||||
crc32_table[i] = crc;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* calculates the CRC 32 value for a buffer */
|
||||
unsigned long calculate_crc32(char *buffer, int buffer_size){
|
||||
register unsigned long crc;
|
||||
unsigned long calculate_crc32(char *buffer, int buffer_size)
|
||||
{
|
||||
register unsigned long crc = 0xFFFFFFFF;
|
||||
int this_char;
|
||||
int current_index;
|
||||
|
||||
crc=0xFFFFFFFF;
|
||||
|
||||
for(current_index=0;current_index<buffer_size;current_index++){
|
||||
this_char=(int)buffer[current_index];
|
||||
crc=((crc>>8) & 0x00FFFFFF) ^ crc32_table[(crc ^ this_char) & 0xFF];
|
||||
}
|
||||
for (current_index = 0; current_index < buffer_size; current_index++) {
|
||||
this_char = (int)buffer[current_index];
|
||||
crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ this_char) & 0xFF];
|
||||
}
|
||||
|
||||
return (crc ^ 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* fill a buffer with semi-random data */
|
||||
void randomize_buffer(char *buffer,int buffer_size){
|
||||
void randomize_buffer(char *buffer, int buffer_size)
|
||||
{
|
||||
FILE *fp;
|
||||
int x;
|
||||
int seed;
|
||||
@@ -91,103 +97,106 @@ void randomize_buffer(char *buffer,int buffer_size){
|
||||
/**** FILL BUFFER WITH RANDOM ALPHA-NUMERIC CHARACTERS ****/
|
||||
|
||||
/***************************************************************
|
||||
Only use alpha-numeric characters becase plugins usually
|
||||
Only use alpha-numeric characters because plugins usually
|
||||
only generate numbers and letters in their output. We
|
||||
want the buffer to contain the same set of characters as
|
||||
plugins, so its harder to distinguish where the real output
|
||||
ends and the rest of the buffer (padded randomly) starts.
|
||||
***************************************************************/
|
||||
***************************************************************/
|
||||
|
||||
/* try to get seed value from /dev/urandom, as its a better source of entropy */
|
||||
fp=fopen("/dev/urandom","r");
|
||||
if(fp!=NULL){
|
||||
seed=fgetc(fp);
|
||||
fp = fopen("/dev/urandom", "r");
|
||||
if (fp != NULL) {
|
||||
seed = fgetc(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
}
|
||||
/* else fallback to using the current time as the seed */
|
||||
else
|
||||
seed=(int)time(NULL);
|
||||
seed = (int)time(NULL);
|
||||
|
||||
srand(seed);
|
||||
for(x=0;x<buffer_size;x++)
|
||||
buffer[x]=(int)'0'+(int)(72.0*rand()/(RAND_MAX+1.0));
|
||||
for (x = 0; x < buffer_size; x++)
|
||||
buffer[x] = (int)'0' + (int)(72.0 * rand() / (RAND_MAX + 1.0));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* opens a connection to a remote host */
|
||||
int my_connect(const char *host, struct sockaddr_storage * hostaddr, u_short port,
|
||||
int address_family, const char *bind_address){
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
int my_connect(const char *host, struct sockaddr_storage *hostaddr, u_short port,
|
||||
int address_family, const char *bind_address)
|
||||
#else
|
||||
int my_connect(const char *host, struct sockaddr *hostaddr, u_short port,
|
||||
int address_family, const char *bind_address)
|
||||
#endif
|
||||
{
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
||||
int gaierr;
|
||||
int sock = -1;
|
||||
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = address_family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
snprintf(strport, sizeof strport, "%u", port);
|
||||
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
|
||||
fprintf(stderr,"Could not resolve hostname %.100s: %s\n", host,
|
||||
gai_strerror(gaierr));
|
||||
fprintf(stderr, "Could not resolve hostname %.100s: %s\n", host, gai_strerror(gaierr));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through addresses for this host, and try each one in
|
||||
* sequence until the connection succeeds.
|
||||
*/
|
||||
* Loop through addresses for this host, and try each one in
|
||||
* sequence until the connection succeeds.
|
||||
*/
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) continue;
|
||||
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
|
||||
strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
|
||||
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
|
||||
continue;
|
||||
if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
|
||||
strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
|
||||
fprintf(stderr, "my_connect: getnameinfo failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Create a socket for connecting. */
|
||||
sock = my_create_socket(ai, bind_address);
|
||||
if (sock < 0) {
|
||||
/* Any error is already output */
|
||||
continue;
|
||||
}
|
||||
if (sock < 0)
|
||||
continue; /* Any error is already output */
|
||||
|
||||
if (connect(sock, ai->ai_addr, ai->ai_addrlen) >= 0) {
|
||||
/* Successful connection. */
|
||||
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,"connect to address %s port %s: %s\n", ntop, strport,
|
||||
} else {
|
||||
fprintf(stderr, "connect to address %s port %s: %s\n", ntop, strport,
|
||||
strerror(errno));
|
||||
close(sock);
|
||||
sock = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(aitop);
|
||||
|
||||
/* Return failure if we didn't get a successful connection. */
|
||||
if (sock == -1) {
|
||||
fprintf(stderr, "connect to host %s port %s: %s", host, strport,
|
||||
strerror(errno));
|
||||
fprintf(stderr, "connect to host %s port %s: %s\n", host, strport, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* Creates a socket for the connection. */
|
||||
int my_create_socket(struct addrinfo *ai, const char *bind_address) {
|
||||
int my_create_socket(struct addrinfo *ai, const char *bind_address)
|
||||
{
|
||||
int sock, gaierr;
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (sock < 0) fprintf(stderr,"socket: %.100s\n", strerror(errno));
|
||||
if (sock < 0)
|
||||
fprintf(stderr, "socket: %.100s\n", strerror(errno));
|
||||
|
||||
/* Bind the socket to an alternative local IP address */
|
||||
if (bind_address == NULL) return sock;
|
||||
if (bind_address == NULL)
|
||||
return sock;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = ai->ai_family;
|
||||
@@ -195,24 +204,23 @@ int my_create_socket(struct addrinfo *ai, const char *bind_address) {
|
||||
hints.ai_protocol = ai->ai_protocol;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
gaierr = getaddrinfo(bind_address, NULL, &hints, &res);
|
||||
if(gaierr) {
|
||||
fprintf(stderr, "getaddrinfo: %s: %s\n", bind_address,
|
||||
gai_strerror(gaierr));
|
||||
if (gaierr) {
|
||||
fprintf(stderr, "getaddrinfo: %s: %s\n", bind_address, gai_strerror(gaierr));
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
if(bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
}
|
||||
if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
fprintf(stderr, "bind: %s: %s\n", bind_address, strerror(errno));
|
||||
close(sock);
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return sock;
|
||||
}
|
||||
|
||||
void add_listen_addr(struct addrinfo **listen_addrs, int address_family,
|
||||
char *addr, int port) {
|
||||
void add_listen_addr(struct addrinfo **listen_addrs, int address_family, char *addr, int port)
|
||||
{
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char strport[NI_MAXSERV];
|
||||
int gaierr;
|
||||
@@ -222,109 +230,191 @@ void add_listen_addr(struct addrinfo **listen_addrs, int address_family,
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
|
||||
snprintf(strport, sizeof strport, "%d", port);
|
||||
if((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
|
||||
syslog(LOG_ERR,"bad addr or host: %s (%s)\n", addr ? addr : "<NULL>",
|
||||
gai_strerror(gaierr));
|
||||
if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
|
||||
syslog(LOG_ERR, "bad addr or host: %s (%s)\n", addr ? addr : "<NULL>",
|
||||
gai_strerror(gaierr));
|
||||
exit(1);
|
||||
}
|
||||
for(ai = aitop; ai->ai_next; ai = ai->ai_next);
|
||||
}
|
||||
for (ai = aitop; ai->ai_next; ai = ai->ai_next) ;
|
||||
ai->ai_next = *listen_addrs;
|
||||
*listen_addrs = aitop;
|
||||
}
|
||||
|
||||
int clean_environ(const char *keep_env_vars, const char *nrpe_user)
|
||||
{
|
||||
#ifdef HAVE_PATHS_H
|
||||
static char *path = _PATH_STDPATH;
|
||||
#else
|
||||
static char *path = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";
|
||||
#endif
|
||||
struct passwd *pw;
|
||||
size_t len, var_sz = 0;
|
||||
char **kept = NULL, *value, *var, *keep = NULL;
|
||||
int i, j, keepcnt = 0;
|
||||
|
||||
if (keep_env_vars && *keep_env_vars)
|
||||
asprintf(&keep, "%s,NRPE_MULTILINESUPPORT,NRPE_PROGRAMVERSION", keep_env_vars);
|
||||
else
|
||||
asprintf(&keep, "NRPE_MULTILINESUPPORT,NRPE_PROGRAMVERSION");
|
||||
if (keep == NULL) {
|
||||
syslog(LOG_ERR, "Could not sanitize the environment. Aborting!");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
void strip(char *buffer){
|
||||
|
||||
++keepcnt;
|
||||
i = strlen(keep);
|
||||
while (i--) {
|
||||
if (keep[i] == ',')
|
||||
++keepcnt;
|
||||
}
|
||||
|
||||
if ((kept = calloc(keepcnt + 1, sizeof(char *))) == NULL) {
|
||||
syslog(LOG_ERR, "Could not sanitize the environment. Aborting!");
|
||||
return ERROR;
|
||||
}
|
||||
for (i = 0, var = my_strsep(&keep, ","); var != NULL; var = my_strsep(&keep, ","))
|
||||
kept[i++] = strip(var);
|
||||
|
||||
var = NULL;
|
||||
i = 0;
|
||||
while (environ[i]) {
|
||||
value = environ[i];
|
||||
if ((len = strcspn(value, "=")) == 0) {
|
||||
free(keep);
|
||||
free(kept);
|
||||
free(var);
|
||||
syslog(LOG_ERR, "Could not sanitize the environment. Aborting!");
|
||||
return ERROR;
|
||||
}
|
||||
if (len >= var_sz) {
|
||||
var_sz = len + 1;
|
||||
var = realloc(var, var_sz);
|
||||
}
|
||||
strncpy(var, environ[i], var_sz);
|
||||
var[len] = 0;
|
||||
|
||||
for (j = 0; kept[j]; ++j) {
|
||||
if (!strncmp(var, kept[j], strlen(kept[j])))
|
||||
break;
|
||||
}
|
||||
if (kept[j]) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsetenv(var);
|
||||
}
|
||||
|
||||
free(var);
|
||||
free(keep);
|
||||
free(kept);
|
||||
|
||||
pw = (struct passwd *)getpwnam(nrpe_user);
|
||||
if (pw == NULL)
|
||||
return OK;
|
||||
|
||||
setenv("PATH", path, 1);
|
||||
setenv("IFS", " \t\n", 1);
|
||||
setenv("HOME", pw->pw_dir, 0);
|
||||
setenv("SHELL", pw->pw_shell, 0);
|
||||
setenv("LOGNAME", nrpe_user, 0);
|
||||
setenv("USER", nrpe_user, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
char *strip(char *buffer)
|
||||
{
|
||||
int x;
|
||||
int index;
|
||||
char *buf = buffer;
|
||||
|
||||
for(x=strlen(buffer);x>=1;x--){
|
||||
index=x-1;
|
||||
if(buffer[index]==' ' || buffer[index]=='\r' || buffer[index]=='\n' || buffer[index]=='\t')
|
||||
buffer[index]='\x0';
|
||||
for (x = strlen(buffer); x >= 1; x--) {
|
||||
index = x - 1;
|
||||
if (buffer[index] == ' ' || buffer[index] == '\r' || buffer[index] == '\n'
|
||||
|| buffer[index] == '\t')
|
||||
buffer[index] = '\x0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
while (*buf == ' ' || *buf == '\r' || *buf == '\n' || *buf == '\t') {
|
||||
++buf;
|
||||
--x;
|
||||
}
|
||||
if (buf != buffer) {
|
||||
memmove(buffer, buf, x);
|
||||
buffer[x] = '\x0';
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* sends all data - thanks to Beej's Guide to Network Programming */
|
||||
int sendall(int s, char *buf, int *len){
|
||||
int total=0;
|
||||
int bytesleft=*len;
|
||||
int n=0;
|
||||
int sendall(int s, char *buf, int *len)
|
||||
{
|
||||
int total = 0;
|
||||
int bytesleft = *len;
|
||||
int n = 0;
|
||||
|
||||
/* send all the data */
|
||||
while(total<*len){
|
||||
|
||||
/* send some data */
|
||||
n=send(s,buf+total,bytesleft,0);
|
||||
|
||||
/* break on error */
|
||||
if(n==-1)
|
||||
while (total < *len) {
|
||||
n = send(s, buf + total, bytesleft, 0); /* send some data */
|
||||
if (n == -1) /* break on error */
|
||||
break;
|
||||
|
||||
/* apply bytes we sent */
|
||||
total+=n;
|
||||
bytesleft-=n;
|
||||
}
|
||||
|
||||
/* return number of bytes actually send here */
|
||||
*len=total;
|
||||
|
||||
/* return -1 on failure, 0 on success */
|
||||
return n==-1?-1:0;
|
||||
}
|
||||
total += n;
|
||||
bytesleft -= n;
|
||||
}
|
||||
|
||||
*len = total; /* return number of bytes actually sent here */
|
||||
return n == -1 ? -1 : 0; /* return -1 on failure, 0 on success */
|
||||
}
|
||||
|
||||
/* receives all data - modelled after sendall() */
|
||||
int recvall(int s, char *buf, int *len, int timeout){
|
||||
int total=0;
|
||||
int bytesleft=*len;
|
||||
int n=0;
|
||||
int recvall(int s, char *buf, int *len, int timeout)
|
||||
{
|
||||
time_t start_time;
|
||||
time_t current_time;
|
||||
|
||||
/* clear the receive buffer */
|
||||
bzero(buf,*len);
|
||||
int total = 0;
|
||||
int bytesleft = *len;
|
||||
int n = 0;
|
||||
|
||||
bzero(buf, *len); /* clear the receive buffer */
|
||||
time(&start_time);
|
||||
|
||||
/* receive all data */
|
||||
while(total<*len){
|
||||
while (total < *len) {
|
||||
n = recv(s, buf + total, bytesleft, 0); /* receive some data */
|
||||
|
||||
/* receive some data */
|
||||
n=recv(s,buf+total,bytesleft,0);
|
||||
|
||||
/* no data has arrived yet (non-blocking socket) */
|
||||
if(n==-1 && errno==EAGAIN){
|
||||
if (n == -1 && errno == EAGAIN) {
|
||||
/* no data has arrived yet (non-blocking socket) */
|
||||
time(¤t_time);
|
||||
if(current_time-start_time>timeout)
|
||||
if (current_time - start_time > timeout)
|
||||
break;
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* receive error or client disconnect */
|
||||
else if(n<=0)
|
||||
break;
|
||||
} else if (n <= 0)
|
||||
break; /* receive error or client disconnect */
|
||||
|
||||
/* apply bytes we received */
|
||||
total+=n;
|
||||
bytesleft-=n;
|
||||
}
|
||||
total += n;
|
||||
bytesleft -= n;
|
||||
}
|
||||
|
||||
/* return number of bytes actually received here */
|
||||
*len=total;
|
||||
*len = total;
|
||||
|
||||
/* return <=0 on failure, bytes received on success */
|
||||
return (n<=0)?n:total;
|
||||
}
|
||||
return (n <= 0) ? n : total;
|
||||
}
|
||||
|
||||
|
||||
/* fixes compiler problems under Solaris, since strsep() isn't included */
|
||||
|
||||
/* this code is taken from the glibc source */
|
||||
char *my_strsep (char **stringp, const char *delim){
|
||||
char *my_strsep(char **stringp, const char *delim)
|
||||
{
|
||||
char *begin, *end;
|
||||
|
||||
begin = *stringp;
|
||||
@@ -334,40 +424,84 @@ char *my_strsep (char **stringp, const char *delim){
|
||||
/* A frequent case is when the delimiter string contains only one
|
||||
character. Here we don't need to call the expensive `strpbrk'
|
||||
function and instead work using `strchr'. */
|
||||
if(delim[0]=='\0' || delim[1]=='\0'){
|
||||
if (delim[0] == '\0' || delim[1] == '\0') {
|
||||
char ch = delim[0];
|
||||
|
||||
if(ch=='\0')
|
||||
end=NULL;
|
||||
else{
|
||||
if(*begin==ch)
|
||||
end=begin;
|
||||
if (ch == '\0')
|
||||
end = NULL;
|
||||
else {
|
||||
if (*begin == ch)
|
||||
end = begin;
|
||||
else
|
||||
end=strchr(begin+1,ch);
|
||||
}
|
||||
end = strchr(begin + 1, ch);
|
||||
}
|
||||
|
||||
else
|
||||
/* Find the end of the token. */
|
||||
end = strpbrk (begin, delim);
|
||||
|
||||
if(end){
|
||||
} else
|
||||
end = strpbrk(begin, delim); /* Find the end of the token. */
|
||||
|
||||
if (end) {
|
||||
/* Terminate the token and set *STRINGP past NUL character. */
|
||||
*end++='\0';
|
||||
*stringp=end;
|
||||
}
|
||||
else
|
||||
*end++ = '\0';
|
||||
*stringp = end;
|
||||
} else
|
||||
/* No more delimiters; this is the last token. */
|
||||
*stringp=NULL;
|
||||
*stringp = NULL;
|
||||
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
int b64_decode(unsigned char *encoded)
|
||||
{
|
||||
static const char *b64 = {
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||
};
|
||||
int i, j, l, padding = 0;
|
||||
unsigned char c[4], *outp = encoded;
|
||||
|
||||
union {
|
||||
unsigned c3;
|
||||
struct {
|
||||
unsigned f1:6;
|
||||
unsigned f2:6;
|
||||
unsigned f3:6;
|
||||
unsigned f4:6;
|
||||
} fields;
|
||||
} enc;
|
||||
|
||||
enc.c3 = 0;
|
||||
l = strlen((char *)encoded);
|
||||
for (i = 0; i < l; i += 4) {
|
||||
for (j = 0; j < 4; ++j) {
|
||||
if (encoded[i + j] == '=') {
|
||||
c[j] = 0;
|
||||
++padding;
|
||||
} else if (encoded[i + j] >= 'A' && encoded[i + j] <= 'Z')
|
||||
c[j] = encoded[i + j] - 'A';
|
||||
else if (encoded[i + j] >= 'a' && encoded[i + j] <= 'z')
|
||||
c[j] = encoded[i + j] - 'a' + 26;
|
||||
else if (encoded[i + j] >= '0' && encoded[i + j] <= '9')
|
||||
c[j] = encoded[i + j] - '0' + 52;
|
||||
else if (encoded[i + j] == '+')
|
||||
c[j] = encoded[i + j] - '+' + 62;
|
||||
else
|
||||
c[j] = encoded[i + j] - '/' + 63;
|
||||
}
|
||||
enc.fields.f1 = c[3];
|
||||
enc.fields.f2 = c[2];
|
||||
enc.fields.f3 = c[1];
|
||||
enc.fields.f4 = c[0];
|
||||
*outp++ = (enc.c3 >> 16) & 0xff;
|
||||
*outp++ = (enc.c3 >> 8) & 0xff;
|
||||
*outp++ = (enc.c3) & 0xff;
|
||||
}
|
||||
*outp = '\0';
|
||||
|
||||
return outp - encoded - padding;
|
||||
}
|
||||
|
||||
/* show license */
|
||||
void display_license(void){
|
||||
|
||||
void display_license(void)
|
||||
{
|
||||
printf("This program is released under the GPL (see below) with the additional\n");
|
||||
printf("exemption that compiling, linking, and/or using OpenSSL is allowed.\n\n");
|
||||
|
||||
@@ -384,7 +518,4 @@ void display_license(void){
|
||||
printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user