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>