Annotation of embedaddon/sudo/plugins/sudoers/regress/parser/check_addr.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
                      3:  *
                      4:  * Permission to use, copy, modify, and distribute this software for any
                      5:  * purpose with or without fee is hereby granted, provided that the above
                      6:  * copyright notice and this permission notice appear in all copies.
                      7:  *
                      8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                      9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     15:  */
                     16: 
                     17: #include <config.h>
                     18: 
                     19: #include <sys/types.h>
                     20: #include <sys/socket.h>
                     21: #include <stdio.h>
                     22: #ifdef STDC_HEADERS
                     23: # include <stdlib.h>
                     24: # include <stddef.h>
                     25: #else
                     26: # ifdef HAVE_STDLIB_H
                     27: #  include <stdlib.h>
                     28: # endif
                     29: #endif /* STDC_HEADERS */
                     30: #include <stdarg.h>
                     31: #ifdef HAVE_STRING_H
                     32: # include <string.h>
                     33: #endif /* HAVE_STRING_H */
                     34: #ifdef HAVE_STRINGS_H
                     35: # include <strings.h>
                     36: #endif /* HAVE_STRINGS_H */
                     37: #include <ctype.h>
                     38: #include <errno.h>
                     39: #include <grp.h>
                     40: #include <pwd.h>
                     41: 
                     42: #include <netinet/in.h>
                     43: #include <arpa/inet.h>
                     44: #include <netdb.h>
                     45: 
                     46: #include "sudoers.h"
                     47: #include "parse.h"
                     48: #include "interfaces.h"
                     49: 
                     50: static int check_addr_printf(int msg_type, const char *fmt, ...);
                     51: 
                     52: /* for match_addr.c */
                     53: struct interface *interfaces;
                     54: sudo_printf_t sudo_printf = check_addr_printf;
                     55: 
                     56: static int
                     57: check_addr(char *input)
                     58: {
                     59:     int expected, matched;
                     60:     size_t len;
                     61:     char *cp;
                     62: 
                     63:     while (isspace((unsigned char)*input))
                     64:        input++;
                     65: 
                     66:     /* input: "addr[/mask] 1/0" */
                     67:     len = strcspn(input, " \t");
                     68:     cp = input + len;
                     69:     while (isspace((unsigned char)*cp))
                     70:        cp++;
                     71:     expected = atoi(cp);
                     72:     input[len] = '\0';
                     73: 
                     74:     matched = addr_matches(input);
                     75:     if (matched != expected) {
                     76:        warningx("%s %smatched: FAIL", input, matched ? "" : "not ");
                     77:        return 1;
                     78:     }
                     79:     return 0;
                     80: }
                     81: 
                     82: static void
                     83: usage(void)
                     84: {
                     85:     fprintf(stderr, "usage: check_addr datafile\n");
                     86:     exit(1);
                     87: }
                     88: 
                     89: int
                     90: main(int argc, char *argv[])
                     91: {
                     92:     int ntests = 0, errors = 0;
                     93:     char *cp, line[2048];
                     94:     size_t len;
                     95:     FILE *fp;
                     96: 
                     97: #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
                     98:     setprogname(argc > 0 ? argv[0] : "check_addr");
                     99: #endif
                    100: 
                    101:     if (argc != 2)
                    102:        usage();
                    103: 
                    104:     fp = fopen(argv[1], "r");
                    105:     if (fp == NULL)
                    106:        errorx(1, "unable to open %s", argv[1]);
                    107: 
                    108:     /*
                    109:      * Input is in the following format.  There are two types of
                    110:      * lines: interfaces, which sets the address and mask of the
                    111:      * locally connected ethernet interfaces for the lines that
                    112:      * follow and, address lines that include and address (with
                    113:      * optional netmask) to match, followed by expected match status
                    114:      * (1 or 0).  E.g.
                    115:      *
                    116:      * interfaces: addr1/mask addr2/mask ...
                    117:      * address: addr[/mask] 1/0
                    118:      * address: addr[/mask] 1/0
                    119:      * interfaces: addr3/mask addr4/mask ...
                    120:      * address: addr[/mask] 1/0
                    121:      */
                    122: 
                    123:     while (fgets(line, sizeof(line), fp) != NULL) {
                    124:        len = strcspn(line, "\n");
                    125:        line[len] = '\0';
                    126: 
                    127:        /* Ignore comments */
                    128:        if ((cp = strchr(line, '#')) != NULL)
                    129:            *cp = '\0';
                    130: 
                    131:        /* Skip blank lines. */
                    132:        if (line[0] == '\0')
                    133:            continue;
                    134: 
                    135:        if (strncmp(line, "interfaces:", sizeof("interfaces:") - 1) == 0) {
                    136:            set_interfaces(line + sizeof("interfaces:") - 1);
                    137:        } else if (strncmp(line, "address:", sizeof("address:") - 1) == 0) {
                    138:            errors += check_addr(line + sizeof("address:") - 1);
                    139:            ntests++;
                    140:        } else {
                    141:            warningx("unexpected data line: %s\n", line);
                    142:            continue;
                    143:        }
                    144:     }
                    145: 
                    146:     printf("check_addr: %d tests run, %d errors, %d%% success rate\n",
                    147:        ntests, errors, (ntests - errors) * 100 / ntests);
                    148: 
                    149:     exit(errors);
                    150: }
                    151: 
                    152: /* STUB */
                    153: void
                    154: cleanup(int gotsig)
                    155: {
                    156:     return;
                    157: }
                    158: 
                    159: static int
                    160: check_addr_printf(int msg_type, const char *fmt, ...)
                    161: {
                    162:     va_list ap;
                    163:     FILE *fp;
                    164:             
                    165:     switch (msg_type) {
                    166:     case SUDO_CONV_INFO_MSG:
                    167:         fp = stdout;
                    168:         break;
                    169:     case SUDO_CONV_ERROR_MSG:
                    170:         fp = stderr;
                    171:         break;
                    172:     default:
                    173:         errno = EINVAL;
                    174:         return -1;
                    175:     }
                    176:    
                    177:     va_start(ap, fmt);
                    178:     vfprintf(fp, fmt, ap);
                    179:     va_end(ap);
                    180:    
                    181:     return 0;
                    182: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>