1 /**********************************************************************
2  * Copyright (C) (2004) (Jack Louis) <jack@dyadsecurity.com>          *
3  *                                                                    *
4  * This program is free software; you can redistribute it and/or      *
5  * modify it under the terms of the GNU General Public License        *
6  * as published by the Free Software Foundation; either               *
7  * version 2 of the License, or (at your option) any later            *
8  * version.                                                           *
9  *                                                                    *
10  * This program is distributed in the hope that it will be useful,    *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
13  * GNU General Public License for more details.                       *
14  *                                                                    *
15  * You should have received a copy of the GNU General Public License  *
16  * along with this program; if not, write to the Free Software        *
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.          *
18  **********************************************************************/
19 #include <config.h>
20 
21 #include <stdlib.h>
22 #include <unistd.h>
23 
24 #include <terminate.h>
25 #include <output.h>
26 #include <xmalloc.h>
27 #include <putil.h>
28 #include "parse.tab.h"
29 
30 #undef LAZY_GDB
31 
32 static int buffer_size=0;
33 static char *bbuf=NULL;
34 
35 static int ptcpflags=0;
36 
37 extern void yyerror(const char *);
38 
39 #define PPBLOCK_SIZE 64
40 
yyescapestr(const char * in,buf_t * bout)41 int yyescapestr(const char *in, buf_t *bout) {
42 	char *out=NULL, bstr=0;
43 	int j=0, j1=0;
44 #define BIN bstr=1
45 
46 	assert(in != NULL);
47 	if (*in == '"' && *(in + 1) != '\0') in++;
48 
49 	/* we'll do better down there */
50 	out=xstrdup(in);
51 
52 	for (j=0, j1=0 ; j < (int)strlen(in) ; j++) {
53 		if (in[j] == '\\' && in[j + 1] != '\0') {
54 			const char *tmpptr=NULL;
55 			int oweight=0, result=0;
56 
57 			++j;
58 			switch (in[j]) {
59 				case 'a':
60 					out[j1++]='\a'; BIN; break;
61 				case 'b':
62 					out[j1++]='\b'; BIN; break;
63 				case 'f':
64 					out[j1++]='\f'; BIN; break;
65 				case 'n':
66 					out[j1++]='\n'; BIN; break;
67 				case 'r':
68 					out[j1++]='\r'; BIN; break;
69 				case 't':
70 					out[j1++]='\t'; BIN; break;
71 				case 'v':
72 					out[j1++]='\v'; BIN; break;
73 				case '\'': /* " and ' are escaped to be the same thing */
74 				case '"':
75 					out[j1++]=in[j]; j++; break;
76 				case '\\':
77 					out[j1++]='\\'; break;
78 				case '0': case '1': case '2': case '3':
79 				case '4': case '5': case '6': case '7':
80 					BIN;
81 					/* start at index 0, go to max 3 spaces with all chars being 0 - 7 */
82 					for (tmpptr=&in[j], oweight=0;
83 					 *tmpptr != '\0' && (*tmpptr >= 0x30 && *tmpptr <= 0x37) && oweight < 65;
84 					tmpptr++) {
85 						if (oweight) {
86 							oweight=(oweight * 8);
87 						}
88 						else {
89 							oweight++;
90 						}
91 					}
92 
93 					for (tmpptr=&in[j], result=0;
94 					*tmpptr != '\0' && (*tmpptr >= 0x30 && *tmpptr <= 0x37) && oweight > 0;
95 					tmpptr++, j++, oweight=(oweight / 8)) {
96 						int add=0; char bob[2];
97 
98 						bob[0]=*tmpptr; bob[1]='\0';
99 						add=atoi(bob);
100 						result += (add * oweight);
101 					}
102 					/* truncate \777 to 0xFF like \377 */
103 					out[j1++]=(result & 0xFF); --j;
104 					/* im too lazy to refactor this so i dont need the -- so :P */
105 					break;
106 				case 'x':
107 					BIN;
108 					/* start at index 0, go to max 2 spaces with all chars being 0 - 7 */
109 					j++;
110 					tmpptr=&in[j];
111 					if (*tmpptr == '\0' || *(tmpptr + 1) == '\0') {
112 						MSG(M_ERR, "Broken hex escape, its late, sorry\n");
113 						terminate(TERM_ERROR);
114 					}
115 					if (1) {
116 						char str[3];
117 						int num=0;
118 
119 						str[0]=*tmpptr; str[1]=*(tmpptr + 1); str[2]='\0'; j++;
120 
121 						if (sscanf(str, "%x", &num) != 1) {
122 							MSG(M_ERR, "Broken hex escape (from sscanf), sorry `%s'\n", str);
123 							terminate(TERM_ERROR);
124 						}
125 						out[j1++]=(uint8_t)(num & 0xFF);
126 					}
127 					break;
128 				default:
129 					MSG(M_WARN, "Warning unhandled escapechar `%c'\n", in[j]);
130 					break;
131 			}
132 		}
133 		else {
134 			if ((j + 1) != (int)strlen(in)) { /* no trailing " from string */
135 				out[j1++]=in[j];
136 			}
137 		}
138 	}
139 
140 	if (bstr) {
141 		bout->len=0;
142 		bout->ptr=NULL;
143 		bout->len=j1;
144 		bout->ptr=(char *)xmalloc((size_t)j1);
145 		memset(bout->ptr, 0, (size_t)j1);
146 		memcpy(bout->ptr, out, (size_t)j1);
147 	}
148 	else {
149 		/* terminate with a \0 if non-binary */
150 		bout->len=j1;
151 		bout->ptr=(char *)xmalloc((size_t)(j1 + 1));
152 		memset(bout->ptr, 0, (size_t)(j1 + 1));
153 		memcpy(bout->ptr, out, (size_t)j1);
154 	}
155 	xfree(out);
156 
157 	if (bstr) {
158 		return BSTR;
159 	}
160 	return STR;
161 }
162 
pbuffer_get(buf_t * in)163 void pbuffer_get(buf_t *in) {
164 	in->len=buffer_size;
165 	in->ptr=bbuf;
166 }
167 
pbuffer_append(buf_t * in)168 void pbuffer_append(buf_t *in) {
169 	assert(in != NULL);
170 
171 	if (bbuf == NULL) {
172 		bbuf=(char *)xmalloc(in->len);
173 		memcpy(bbuf, in->ptr, in->len);
174 		buffer_size=in->len;
175 	}
176 	else {
177 		char *newbuf=NULL;
178 
179 		newbuf=(char *)xmalloc(buffer_size + in->len);
180 		memcpy(newbuf, bbuf, (size_t)buffer_size);
181 		memcpy(newbuf + buffer_size, in->ptr, in->len);
182 		xfree(bbuf);
183 		bbuf=newbuf;
184 		buffer_size=(buffer_size + in->len);
185 	}
186 	return;
187 }
188 
pbuffer_reset(void)189 void pbuffer_reset(void) {
190 	buffer_size=0;
191 	if (bbuf) {
192 		xfree(bbuf);
193 	}
194 	bbuf=NULL;
195 	return;
196 }
197 
add_tcpflag(int flag)198 void add_tcpflag(int flag) {
199 	if (flag < 0 || flag > 0xFF) {
200 		yyerror("tcp flag out of range");
201 		return;
202 	}
203 	ptcpflags |= flag;
204 }
205 
get_tcpflags(void)206 int get_tcpflags(void) {
207 	if (ptcpflags < 0 || ptcpflags > 0xFF) {
208 		yyerror("combined tcp flags are out of range");
209 		return 0;
210 	}
211 	return ptcpflags;
212 }
213