Annotation of embedaddon/sudo/plugins/sudoers/toke_util.c, revision 1.1.1.2
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>
1.1.1.2 ! misho 51:
1.1 misho 52: #include "sudoers.h"
53: #include "parse.h"
54: #include "toke.h"
55: #include <gram.h>
56:
57: static int arg_len = 0;
58: static int arg_size = 0;
59:
1.1.1.2 ! misho 60: static int
1.1 misho 61: hexchar(const char *s)
62: {
1.1.1.2 ! misho 63: int i, result = 0;
! 64: debug_decl(hexchar, SUDO_DEBUG_PARSER)
1.1 misho 65:
66: s += 2; /* skip \\x */
67: for (i = 0; i < 2; i++) {
68: switch (*s) {
69: case 'A':
70: case 'a':
71: result += 10;
72: break;
73: case 'B':
74: case 'b':
75: result += 11;
76: break;
77: case 'C':
78: case 'c':
79: result += 12;
80: break;
81: case 'D':
82: case 'd':
83: result += 13;
84: break;
85: case 'E':
86: case 'e':
87: result += 14;
88: break;
89: case 'F':
90: case 'f':
91: result += 15;
92: break;
93: default:
94: result += *s - '0';
95: break;
96: }
97: if (i == 0) {
98: result *= 16;
99: s++;
100: }
101: }
1.1.1.2 ! misho 102: debug_return_int(result);
1.1 misho 103: }
104:
1.1.1.2 ! misho 105: bool
1.1 misho 106: fill_txt(const char *src, int len, int olen)
107: {
108: char *dst;
1.1.1.2 ! misho 109: debug_decl(fill_txt, SUDO_DEBUG_PARSER)
1.1 misho 110:
111: dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
112: if (dst == NULL) {
113: yyerror(_("unable to allocate memory"));
1.1.1.2 ! misho 114: debug_return_bool(false);
1.1 misho 115: }
116: yylval.string = dst;
117:
118: /* Copy the string and collapse any escaped characters. */
119: dst += olen;
120: while (len--) {
121: if (*src == '\\' && len) {
122: if (src[1] == 'x' && len >= 3 &&
123: isxdigit((unsigned char) src[2]) &&
124: isxdigit((unsigned char) src[3])) {
125: *dst++ = hexchar(src);
126: src += 4;
127: len -= 3;
128: } else {
129: src++;
130: len--;
131: *dst++ = *src++;
132: }
133: } else {
134: *dst++ = *src++;
135: }
136: }
137: *dst = '\0';
1.1.1.2 ! misho 138: debug_return_bool(true);
1.1 misho 139: }
140:
1.1.1.2 ! misho 141: bool
1.1 misho 142: append(const char *src, int len)
143: {
144: int olen = 0;
1.1.1.2 ! misho 145: debug_decl(append, SUDO_DEBUG_PARSER)
1.1 misho 146:
147: if (yylval.string != NULL)
148: olen = strlen(yylval.string);
149:
1.1.1.2 ! misho 150: debug_return_bool(fill_txt(src, len, olen));
1.1 misho 151: }
152:
153: #define SPECIAL(c) \
154: ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
155:
1.1.1.2 ! misho 156: bool
1.1 misho 157: fill_cmnd(const char *src, int len)
158: {
159: char *dst;
160: int i;
1.1.1.2 ! misho 161: debug_decl(fill_cmnd, SUDO_DEBUG_PARSER)
1.1 misho 162:
163: arg_len = arg_size = 0;
164:
165: dst = yylval.command.cmnd = (char *) malloc(len + 1);
166: if (yylval.command.cmnd == NULL) {
167: yyerror(_("unable to allocate memory"));
1.1.1.2 ! misho 168: debug_return_bool(false);
1.1 misho 169: }
170:
171: /* Copy the string and collapse any escaped sudo-specific characters. */
172: for (i = 0; i < len; i++) {
173: if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
174: *dst++ = src[++i];
175: else
176: *dst++ = src[i];
177: }
178: *dst = '\0';
179:
180: yylval.command.args = NULL;
1.1.1.2 ! misho 181: debug_return_bool(true);
1.1 misho 182: }
183:
1.1.1.2 ! misho 184: bool
1.1 misho 185: fill_args(const char *s, int len, int addspace)
186: {
187: int new_len;
188: char *p;
1.1.1.2 ! misho 189: debug_decl(fill_args, SUDO_DEBUG_PARSER)
1.1 misho 190:
191: if (yylval.command.args == NULL) {
192: addspace = 0;
193: new_len = len;
194: } else
195: new_len = arg_len + len + addspace;
196:
197: if (new_len >= arg_size) {
198: /* Allocate more space than we need for subsequent args */
199: while (new_len >= (arg_size += COMMANDARGINC))
200: ;
201:
202: p = yylval.command.args ?
203: (char *) realloc(yylval.command.args, arg_size) :
204: (char *) malloc(arg_size);
205: if (p == NULL) {
206: efree(yylval.command.args);
207: yyerror(_("unable to allocate memory"));
1.1.1.2 ! misho 208: debug_return_bool(false);
1.1 misho 209: } else
210: yylval.command.args = p;
211: }
212:
213: /* Efficiently append the arg (with a leading space if needed). */
214: p = yylval.command.args + arg_len;
215: if (addspace)
216: *p++ = ' ';
217: if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
218: yyerror(_("fill_args: buffer overflow")); /* paranoia */
1.1.1.2 ! misho 219: debug_return_bool(false);
1.1 misho 220: }
221: arg_len = new_len;
1.1.1.2 ! misho 222: debug_return_bool(true);
1.1 misho 223: }
224:
225: /*
226: * Check to make sure an IPv6 address does not contain multiple instances
227: * of the string "::". Assumes strlen(s) >= 1.
1.1.1.2 ! misho 228: * Returns true if address is valid else false.
1.1 misho 229: */
1.1.1.2 ! misho 230: bool
1.1 misho 231: ipv6_valid(const char *s)
232: {
233: int nmatch = 0;
1.1.1.2 ! misho 234: debug_decl(ipv6_valid, SUDO_DEBUG_PARSER)
1.1 misho 235:
236: for (; *s != '\0'; s++) {
237: if (s[0] == ':' && s[1] == ':') {
238: if (++nmatch > 1)
239: break;
240: }
241: if (s[0] == '/')
242: nmatch = 0; /* reset if we hit netmask */
243: }
244:
1.1.1.2 ! misho 245: debug_return_bool(nmatch <= 1);
1.1 misho 246: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>