Annotation of embedaddon/sudo/plugins/sudoers/toke_util.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 1996, 1998-2005, 2007-2011
        !             3:  *     Todd C. Miller <Todd.Miller@courtesan.com>
        !             4:  *
        !             5:  * Permission to use, copy, modify, and distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            16:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
        !            17:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
        !            18:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            19:  *
        !            20:  * Sponsored in part by the Defense Advanced Research Projects
        !            21:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
        !            22:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
        !            23:  */
        !            24: 
        !            25: #include <config.h>
        !            26: 
        !            27: #include <sys/types.h>
        !            28: #include <sys/param.h>
        !            29: #include <stdio.h>
        !            30: #ifdef STDC_HEADERS
        !            31: # include <stdlib.h>
        !            32: # include <stddef.h>
        !            33: #else
        !            34: # ifdef HAVE_STDLIB_H
        !            35: #  include <stdlib.h>
        !            36: # endif
        !            37: #endif /* STDC_HEADERS */
        !            38: #ifdef HAVE_STRING_H
        !            39: # include <string.h>
        !            40: #endif /* HAVE_STRING_H */
        !            41: #ifdef HAVE_STRINGS_H
        !            42: # include <strings.h>
        !            43: #endif /* HAVE_STRINGS_H */
        !            44: #ifdef HAVE_UNISTD_H
        !            45: # include <unistd.h>
        !            46: #endif /* HAVE_UNISTD_H */
        !            47: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
        !            48: # include <malloc.h>
        !            49: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
        !            50: #include <ctype.h>
        !            51: #include "sudoers.h"
        !            52: #include "parse.h"
        !            53: #include "toke.h"
        !            54: #include <gram.h>
        !            55: 
        !            56: static int arg_len = 0;
        !            57: static int arg_size = 0;
        !            58: 
        !            59: static unsigned char
        !            60: hexchar(const char *s)
        !            61: {
        !            62:     int i;
        !            63:     int result = 0;
        !            64: 
        !            65:     s += 2; /* skip \\x */
        !            66:     for (i = 0; i < 2; i++) {
        !            67:        switch (*s) {
        !            68:        case 'A':
        !            69:        case 'a':
        !            70:            result += 10;
        !            71:            break;
        !            72:        case 'B':
        !            73:        case 'b':
        !            74:            result += 11;
        !            75:            break;
        !            76:        case 'C':
        !            77:        case 'c':
        !            78:            result += 12;
        !            79:            break;
        !            80:        case 'D':
        !            81:        case 'd':
        !            82:            result += 13;
        !            83:            break;
        !            84:        case 'E':
        !            85:        case 'e':
        !            86:            result += 14;
        !            87:            break;
        !            88:        case 'F':
        !            89:        case 'f':
        !            90:            result += 15;
        !            91:            break;
        !            92:        default:
        !            93:            result += *s - '0';
        !            94:            break;
        !            95:        }
        !            96:        if (i == 0) {
        !            97:            result *= 16;
        !            98:            s++;
        !            99:        }
        !           100:     }
        !           101:     return (unsigned char)result;
        !           102: }
        !           103: 
        !           104: int
        !           105: fill_txt(const char *src, int len, int olen)
        !           106: {
        !           107:     char *dst;
        !           108: 
        !           109:     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
        !           110:     if (dst == NULL) {
        !           111:        yyerror(_("unable to allocate memory"));
        !           112:        return FALSE;
        !           113:     }
        !           114:     yylval.string = dst;
        !           115: 
        !           116:     /* Copy the string and collapse any escaped characters. */
        !           117:     dst += olen;
        !           118:     while (len--) {
        !           119:        if (*src == '\\' && len) {
        !           120:            if (src[1] == 'x' && len >= 3 && 
        !           121:                isxdigit((unsigned char) src[2]) &&
        !           122:                isxdigit((unsigned char) src[3])) {
        !           123:                *dst++ = hexchar(src);
        !           124:                src += 4;
        !           125:                len -= 3;
        !           126:            } else {
        !           127:                src++;
        !           128:                len--;
        !           129:                *dst++ = *src++;
        !           130:            }
        !           131:        } else {
        !           132:            *dst++ = *src++;
        !           133:        }
        !           134:     }
        !           135:     *dst = '\0';
        !           136:     return TRUE;
        !           137: }
        !           138: 
        !           139: int
        !           140: append(const char *src, int len)
        !           141: {
        !           142:     int olen = 0;
        !           143: 
        !           144:     if (yylval.string != NULL)
        !           145:        olen = strlen(yylval.string);
        !           146: 
        !           147:     return fill_txt(src, len, olen);
        !           148: }
        !           149: 
        !           150: #define SPECIAL(c) \
        !           151:     ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
        !           152: 
        !           153: int
        !           154: fill_cmnd(const char *src, int len)
        !           155: {
        !           156:     char *dst;
        !           157:     int i;
        !           158: 
        !           159:     arg_len = arg_size = 0;
        !           160: 
        !           161:     dst = yylval.command.cmnd = (char *) malloc(len + 1);
        !           162:     if (yylval.command.cmnd == NULL) {
        !           163:        yyerror(_("unable to allocate memory"));
        !           164:        return FALSE;
        !           165:     }
        !           166: 
        !           167:     /* Copy the string and collapse any escaped sudo-specific characters. */
        !           168:     for (i = 0; i < len; i++) {
        !           169:        if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
        !           170:            *dst++ = src[++i];
        !           171:        else
        !           172:            *dst++ = src[i];
        !           173:     }
        !           174:     *dst = '\0';
        !           175: 
        !           176:     yylval.command.args = NULL;
        !           177:     return TRUE;
        !           178: }
        !           179: 
        !           180: int
        !           181: fill_args(const char *s, int len, int addspace)
        !           182: {
        !           183:     int new_len;
        !           184:     char *p;
        !           185: 
        !           186:     if (yylval.command.args == NULL) {
        !           187:        addspace = 0;
        !           188:        new_len = len;
        !           189:     } else
        !           190:        new_len = arg_len + len + addspace;
        !           191: 
        !           192:     if (new_len >= arg_size) {
        !           193:        /* Allocate more space than we need for subsequent args */
        !           194:        while (new_len >= (arg_size += COMMANDARGINC))
        !           195:            ;
        !           196: 
        !           197:        p = yylval.command.args ?
        !           198:            (char *) realloc(yylval.command.args, arg_size) :
        !           199:            (char *) malloc(arg_size);
        !           200:        if (p == NULL) {
        !           201:            efree(yylval.command.args);
        !           202:            yyerror(_("unable to allocate memory"));
        !           203:            return FALSE;
        !           204:        } else
        !           205:            yylval.command.args = p;
        !           206:     }
        !           207: 
        !           208:     /* Efficiently append the arg (with a leading space if needed). */
        !           209:     p = yylval.command.args + arg_len;
        !           210:     if (addspace)
        !           211:        *p++ = ' ';
        !           212:     if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
        !           213:        yyerror(_("fill_args: buffer overflow"));       /* paranoia */
        !           214:        return FALSE;
        !           215:     }
        !           216:     arg_len = new_len;
        !           217:     return TRUE;
        !           218: }
        !           219: 
        !           220: /*
        !           221:  * Check to make sure an IPv6 address does not contain multiple instances
        !           222:  * of the string "::".  Assumes strlen(s) >= 1.
        !           223:  * Returns TRUE if address is valid else FALSE.
        !           224:  */
        !           225: int
        !           226: ipv6_valid(const char *s)
        !           227: {
        !           228:     int nmatch = 0;
        !           229: 
        !           230:     for (; *s != '\0'; s++) {
        !           231:        if (s[0] == ':' && s[1] == ':') {
        !           232:            if (++nmatch > 1)
        !           233:                break;
        !           234:        }
        !           235:        if (s[0] == '/')
        !           236:            nmatch = 0;                 /* reset if we hit netmask */
        !           237:     }
        !           238: 
        !           239:     return nmatch <= 1;
        !           240: }

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