Back to index

nagios-nrpe  2.13
Functions
acl.c File Reference
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netdb.h>
#include <syslog.h>
#include <stdarg.h>
#include "../include/acl.h"

Go to the source code of this file.

Functions

int isvalidchar (int c)
char * acl_substring (char *string, int s, int e)
int add_ipv4_to_acl (char *ipv4)
int add_domain_to_acl (char *domain)
int is_an_allowed_host (struct in_addr host)
void trim (char *src, char *dest)
void parse_allowed_hosts (char *allowed_hosts)
unsigned int prefix_from_mask (struct in_addr mask)
void show_acl_lists (void)

Function Documentation

char* acl_substring ( char *  string,
int  s,
int  e 
)

Definition at line 96 of file acl.c.

                                                 {
    char *substring;
    int len = e - s;

        if (len < 0)
                return NULL;

    if ( (substring = malloc(len + 1)) == NULL)
        return NULL;

    memmove(substring, string + s, len + 1);
    return substring;
}
int add_domain_to_acl ( char *  domain)

Definition at line 278 of file acl.c.

                                    {
        int state = 0;
        int len = strlen(domain);
        int i, c;

        struct dns_acl *dns_acl_curr;

        if (len > 63)
                return 0;

        for (i = 0; i < len; i++) {
                c = domain[i];
                switch (isvalidchar(c)) {
                case 1:
                        state = 1;
                        break;
                case 2:
                        switch (state) {
                        case 0: case 1: case 5: case 6:
                                state = 1;
                                break;
                        case 2: case 3: case 4:
                                state++;
                                break;
                        }
                        break;

                case 4:
                        switch (state) {
                        case 0: case 2:
                                state = -1;
                                break;
                        default:
                                state = 2;
                        }
                        break;
                case 6:
                        switch (state) {
                        case 0: case 2:
                                state = -1;
                                break;
                        default:
                                state = 6;
                        }
                        break;
                default:
                        /* Not valid chars */
                        return 0;
                }
        }

        /* Check exit code */
        switch (state) {
        case 1: case 4: case 5:
                /* Add name to domain ACL list */
                if ( (dns_acl_curr = malloc(sizeof(*dns_acl_curr))) == NULL) {
                        syslog(LOG_ERR,"Can't allocate memory for ACL, malloc error\n");
                        return 0;
                }
                strcpy(dns_acl_curr->domain, domain);
                dns_acl_curr->next = NULL;

                if (dns_acl_head == NULL)
                        dns_acl_head = dns_acl_curr;
                else
                        dns_acl_prev->next = dns_acl_curr;

                dns_acl_prev = dns_acl_curr;
                return 1;
        default:
                return 0;
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int add_ipv4_to_acl ( char *  ipv4)

Definition at line 133 of file acl.c.

                                {
        int state = 0;
        int octet = 0;
        int index = 0;  /* position in data array */
        int data[5];    /* array to store ip octets and mask */
        int len = strlen(ipv4);
        int i, c;
        unsigned long ip, mask;
        struct ip_acl *ip_acl_curr;

        /* Check for min and max IPv4 valid length */
        if (len < 7 || len > 18)
                return 0;

        /* default mask for ipv4 */
        data[4] = 32;

        /* Basic IPv4 format check */
        for (i = 0; i < len; i++) {
                /* Return 0 on error state */
                if (state == -1)
                        return 0;

                c = ipv4[i];

                switch (c) {
                case '0': case '1': case '2': case '3': case '4':
                case '5': case '6': case '7': case '8': case '9':
                        octet = octet * 10 + CHAR_TO_NUMBER(c);
                        switch (state) {
                        case 0: case 2: case 4: case 6: case 8:
                                state++;
                                break;
                        }
                        break;
                case '.':
                        switch (state) {
                        case 1: case 3: case 5:
                                data[index++] = octet;
                                octet = 0;
                                state++;
                                break;
                        default:
                                state = -1;
                        }
                        break;
                case '/':
                        switch (state) {
                        case 7:
                                data[index++] = octet;
                                octet = 0;
                                state++;
                                break;
                        default:
                                state = -1;
                        }
                        break;
                default:
                        state = -1;
                }
        }

        /* Exit state handling */
        switch (state) {
        case 7: case 9:
                data[index] = octet;
                break;
        default:
                /* Bad states */
                return 0;
        }

        /*
         * Final IPv4 format check.
         */
        for (i=0; i < 4; i++) {
                if (data[i] < 0 || data[i] > 255) {
                        syslog(LOG_ERR,"Invalid IPv4 address/network format(%s) in allowed_hosts option\n",ipv4);
                        return 0;
                }
        }

        if (data[4] < 0 || data[4] > 32) {
                syslog(LOG_ERR,"Invalid IPv4 network mask format(%s) in allowed_hosts option\n",ipv4);
                return 0;
        }

        /* Conver ip and mask to unsigned long */
        ip = htonl((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]);
        mask =  htonl(-1 << (32 - data[4]));

        /* Wrong network address */
        if ( (ip & mask) != ip) {
                syslog(LOG_ERR,"IP address and mask do not match in %s\n",ipv4);
                return 0;
        }

        /* Add addr to ip_acl list */
        if ( (ip_acl_curr = malloc(sizeof(*ip_acl_curr))) == NULL) {
                syslog(LOG_ERR,"Can't allocate memory for ACL, malloc error\n");
                return 0;
        }

        /* Save result in ACL ip list */
        ip_acl_curr->addr.s_addr = ip;
        ip_acl_curr->mask.s_addr = mask;
        ip_acl_curr->next = NULL;

        if (ip_acl_head == NULL) {
                ip_acl_head = ip_acl_curr;
        } else {
                ip_acl_prev->next = ip_acl_curr;
        }
        ip_acl_prev = ip_acl_curr;
        return 1;
}

Here is the caller graph for this function:

int is_an_allowed_host ( struct in_addr  host)

Definition at line 359 of file acl.c.

                                            {
        struct ip_acl *ip_acl_curr = ip_acl_head;
        struct dns_acl *dns_acl_curr = dns_acl_head;
        struct in_addr addr;
        struct hostent *he;

        while (ip_acl_curr != NULL) {
                if ( (host.s_addr & ip_acl_curr->mask.s_addr) == ip_acl_curr->addr.s_addr)
                        return 1;

                ip_acl_curr = ip_acl_curr->next;
        }

        while(dns_acl_curr != NULL) {
        he = gethostbyname(dns_acl_curr->domain);
        if (he == NULL)
                        return 0;

                while (*he->h_addr_list) {
                        memmove((char *)&addr,*he->h_addr_list++, sizeof(addr));
                        if (addr.s_addr == host.s_addr)
                                return 1;
                }
                dns_acl_curr = dns_acl_curr->next;
        }
        return 0;
}

Here is the caller graph for this function:

int isvalidchar ( int  c)

Definition at line 61 of file acl.c.

                       {
        if (!isascii(c))
                return 0;

        if (isdigit(c))
                return 1;

        if (isalpha(c))
                return 2;

        if (isspace(c))
                return 3;

        switch (c) {
        case '.':
                return 4;
                break;
        case '/':
                return 5;
                break;
        case '-':
                return 6;
                break;
        case ',':
                return 7;
                break;
        default:
                return 0;
        }
}

Here is the caller graph for this function:

void parse_allowed_hosts ( char *  allowed_hosts)

Definition at line 411 of file acl.c.

                                              {
       char *hosts = strdup( allowed_hosts);     /* Copy since strtok* modifes original */
       char *saveptr;
       char *tok;
       const char *delim = ",";
       char *trimmed_tok;

       tok = strtok_r( hosts, delim, &saveptr);
       while( tok) {
              trimmed_tok = malloc( sizeof( char) * ( strlen( tok) + 1));
              trim( tok, trimmed_tok);
              if( strlen( trimmed_tok) > 0) {
                     if (!add_ipv4_to_acl(trimmed_tok) && !add_domain_to_acl(trimmed_tok)) {
                            syslog(LOG_ERR,"Can't add to ACL this record (%s). Check allowed_hosts option!\n",trimmed_tok);
                     }
              }
              free( trimmed_tok);
              tok = strtok_r(( char *)0, delim, &saveptr);
       }

       free( hosts);
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int prefix_from_mask ( struct in_addr  mask)

Definition at line 438 of file acl.c.

                                                   {
        int prefix = 0;
        unsigned long bit = 1;
        int i;

        for (i = 0; i < 32; i++) {
                if (mask.s_addr & bit)
                        prefix++;

                bit = bit << 1;
        }
        return (prefix);
}

Here is the caller graph for this function:

void show_acl_lists ( void  )

Definition at line 456 of file acl.c.

                          {
        struct ip_acl *ip_acl_curr = ip_acl_head;
        struct dns_acl *dns_acl_curr = dns_acl_head;

        while (ip_acl_curr != NULL) {
                printf(" IP ACL: %s/%u %u\n", inet_ntoa(ip_acl_curr->addr), prefix_from_mask(ip_acl_curr->mask), ip_acl_curr->addr.s_addr);
                ip_acl_curr = ip_acl_curr->next;
        }

        while (dns_acl_curr != NULL) {
                printf("DNS ACL: %s\n", dns_acl_curr->domain);
                dns_acl_curr = dns_acl_curr->next;
        }
}

Here is the call graph for this function:

void trim ( char *  src,
char *  dest 
)

Definition at line 392 of file acl.c.

                                  {
       char *sptr, *dptr;

       for( sptr = src; isblank( *sptr) && *sptr; sptr++); /* Jump past leading spaces */
       for( dptr = dest; !isblank( *sptr) && *sptr; ) {
              *dptr = *sptr;
              sptr++;
              dptr++;
       }
       *dptr = '\0';
       return;
}

Here is the caller graph for this function: