2 MiddleMan filtering proxy server
3 Copyright (C) 2002 Jason McLaughlin
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 load <mime> section from XML file into MIME_LIST-type struct
26 MIME_LIST *mime_load(MIME_LIST * mime_list, XML_LIST * xml_list)
28 MIME_LIST *tmp_list = mime_list;
29 struct MIME_LIST_LIST *allow = NULL, *deny = NULL;
31 if (tmp_list == NULL) {
32 tmp_list = xmalloc(sizeof(MIME_LIST));
33 tmp_list->dtemplate = NULL;
34 tmp_list->allow = NULL;
35 tmp_list->deny = NULL;
36 tmp_list->empty = NULL;
37 tmp_list->policy = POLICY_ALLOW;
38 tmp_list->empty = mime_ll_new(NULL);
40 tmp_list->enabled = TRUE;
44 pthread_rwlock_init(&tmp_list->lock, NULL);
46 allow = tmp_list->allow;
47 deny = tmp_list->deny;
50 while ((xml_list = xml_section(xml_list, "<mime>"))) {
51 XML_LIST_LOOP(xml_list, "<mime>") {
52 XML_LIST_CMP(xml_list, "<allow>") {
53 allow = mime_ll_new(allow);
54 allow->id = mime_list->id++;
56 if (tmp_list->allow == NULL)
57 tmp_list->allow = allow;
58 XML_LIST_LOOP(xml_list, "<allow>") {
59 XML_LIST_CMP(xml_list, "<enabled>") {
60 xml_list = xml_list->next;
61 if (xml_list->type == XML_VALUE) {
62 if (!strcasecmp(xml_list->item, "false"))
63 allow->enabled = FALSE;
65 allow->enabled = TRUE;
68 XML_LIST_CMP(xml_list, "<comment>") {
69 xml_list = xml_list->next;
70 if (xml_list->type == XML_VALUE)
71 mime_ll_insert(allow, xml_list->item, NULL, NULL, NULL, NULL);
73 XML_LIST_CMP(xml_list, "<template>") {
74 xml_list = xml_list->next;
75 if (xml_list->type == XML_VALUE)
76 mime_ll_insert(allow, NULL, xml_list->item, NULL, NULL, NULL);
78 XML_LIST_CMP(xml_list, "<host>") {
79 xml_list = xml_list->next;
80 if (xml_list->type == XML_VALUE)
81 mime_ll_insert(allow, NULL, NULL, xml_list->item, NULL, NULL);
83 XML_LIST_CMP(xml_list, "<mime>") {
84 xml_list = xml_list->next;
85 if (xml_list->type == XML_VALUE)
86 mime_ll_insert(allow, NULL, NULL, NULL, xml_list->item, NULL);
88 XML_LIST_CMP(xml_list, "<file>") {
89 xml_list = xml_list->next;
90 if (xml_list->type == XML_VALUE)
91 mime_ll_insert(allow, NULL, NULL, NULL, NULL, xml_list->item);
95 XML_LIST_CMP(xml_list, "<deny>") {
96 deny = mime_ll_new(deny);
97 deny->id = mime_list->id++;
99 if (tmp_list->deny == NULL)
100 tmp_list->deny = deny;
101 XML_LIST_LOOP(xml_list, "<deny>") {
102 XML_LIST_CMP(xml_list, "<enabled>") {
103 xml_list = xml_list->next;
104 if (xml_list->type == XML_VALUE) {
105 if (!strcasecmp(xml_list->item, "false"))
106 deny->enabled = FALSE;
108 deny->enabled = TRUE;
111 XML_LIST_CMP(xml_list, "<comment.") {
112 xml_list = xml_list->next;
113 if (xml_list->type == XML_VALUE)
114 mime_ll_insert(deny, xml_list->item, NULL, NULL, NULL, NULL);
116 XML_LIST_CMP(xml_list, "<template>") {
117 xml_list = xml_list->next;
118 if (xml_list->type == XML_VALUE)
119 mime_ll_insert(deny, NULL, xml_list->item, NULL, NULL, NULL);
121 XML_LIST_CMP(xml_list, "<host>") {
122 xml_list = xml_list->next;
123 if (xml_list->type == XML_VALUE)
124 mime_ll_insert(deny, NULL, NULL, xml_list->item, NULL, NULL);
126 XML_LIST_CMP(xml_list, "<mime>") {
127 xml_list = xml_list->next;
128 if (xml_list->type == XML_VALUE)
129 mime_ll_insert(deny, NULL, NULL, NULL, xml_list->item, NULL);
131 XML_LIST_CMP(xml_list, "<file>") {
132 xml_list = xml_list->next;
133 if (xml_list->type == XML_VALUE)
134 mime_ll_insert(deny, NULL, NULL, NULL, NULL, xml_list->item);
138 XML_LIST_CMP(xml_list, "<policy>") {
139 xml_list = xml_list->next;
140 if (xml_list->type == XML_VALUE) {
141 if (!strcasecmp(xml_list->item, "allow"))
142 tmp_list->policy = POLICY_ALLOW;
143 else if (!strcasecmp(xml_list->item, "deny"))
144 tmp_list->policy = POLICY_DENY;
147 XML_LIST_CMP(xml_list, "<default>") {
148 xml_list = xml_list->next;
149 if (xml_list->type == XML_VALUE) {
150 FREE_AND_NULL(tmp_list->dtemplate);
151 tmp_list->dtemplate = xstrdup(xml_list->item);
154 XML_LIST_CMP(xml_list, "<enabled>") {
155 xml_list = xml_list->next;
156 if (xml_list->type == XML_VALUE) {
157 if (!strcasecmp(xml_list->item, "false"))
158 tmp_list->enabled = FALSE;
160 tmp_list->enabled = TRUE;
169 XML_LIST *mime_xml(MIME_LIST * mime_list, XML_LIST * xml_list)
173 struct MIME_LIST_LIST *ml = NULL;
175 if (mime_list == NULL)
178 pthread_rwlock_rdlock(&mime_list->lock);
180 xml_list = xml_list_add(xml_list, "<mime>", XML_TAG);
182 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
183 xml_list = xml_list_add(xml_list, (mime_list->enabled == TRUE) ? "true" : "false", XML_VALUE);
184 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
186 xml_list = xml_list_add(xml_list, "<policy>", XML_TAG);
187 xml_list = xml_list_add(xml_list, (mime_list->policy == POLICY_ALLOW) ? "allow" : "deny", XML_VALUE);
188 xml_list = xml_list_add(xml_list, "</policy>", XML_TAG);
190 if (mime_list->dtemplate != NULL) {
191 xml_list = xml_list_add(xml_list, "<default>", XML_TAG);
192 ptr = string_to_xml(mime_list->dtemplate);
193 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
195 xml_list = xml_list_add(xml_list, "</default>", XML_TAG);
198 for (i = 0; i < 2; i++) {
201 ml = mime_list->allow;
204 ml = mime_list->deny;
208 for (; ml; ml = ml->next) {
209 xml_list = xml_list_add(xml_list, (i == 0) ? "<allow>" : "<deny>", XML_TAG);
211 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
212 xml_list = xml_list_add(xml_list, (ml->enabled == TRUE) ? "true" : "false", XML_VALUE);
213 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
215 if (ml->comment != NULL) {
216 xml_list = xml_list_add(xml_list, "<comment>", XML_TAG);
217 ptr = string_to_xml(ml->comment);
218 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
220 xml_list = xml_list_add(xml_list, "</comment>", XML_TAG);
223 if (ml->mime != NULL) {
224 xml_list = xml_list_add(xml_list, "<mime>", XML_TAG);
225 ptr = string_to_xml(ml->mime);
226 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
228 xml_list = xml_list_add(xml_list, "</mime>", XML_TAG);
231 if (ml->host != NULL) {
232 xml_list = xml_list_add(xml_list, "<host>", XML_TAG);
233 ptr = string_to_xml(ml->host);
234 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
236 xml_list = xml_list_add(xml_list, "</host>", XML_TAG);
239 if (ml->file != NULL) {
240 xml_list = xml_list_add(xml_list, "<file>", XML_TAG);
241 ptr = string_to_xml(ml->file);
242 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
244 xml_list = xml_list_add(xml_list, "</file>", XML_TAG);
247 if (ml->template != NULL) {
248 xml_list = xml_list_add(xml_list, "<template>", XML_TAG);
249 ptr = string_to_xml(ml->template);
250 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
252 xml_list = xml_list_add(xml_list, "</template>", XML_TAG);
255 xml_list = xml_list_add(xml_list, (i == 0) ? "</allow>" : "</deny>", XML_TAG);
259 xml_list = xml_list_add(xml_list, "</mime>", XML_TAG);
261 pthread_rwlock_unlock(&mime_list->lock);
266 void mime_ll_insert(struct MIME_LIST_LIST *x, char *a, char *b, char *c, char *d, char *e)
269 FREE_AND_NULL(x->comment);
272 x->comment = xstrdup(a);
275 FREE_AND_NULL(x->template);
278 x->template = xstrdup(b);
283 FREE_AND_NULL(x->host);
286 x->host = xstrdup(c);
287 x->he = reg_compile(c, REGFLAGS);
294 FREE_AND_NULL(x->mime);
297 x->mime = xstrdup(d);
298 x->me = reg_compile(d, REGFLAGS);
307 x->file = xstrdup(e);
308 x->fe = reg_compile(e, REGFLAGS);
314 struct MIME_LIST_LIST *mime_ll_delete(struct MIME_LIST_LIST *x)
316 struct MIME_LIST_LIST *start = x;
318 while (start->prev != NULL)
322 x->next->prev = x->prev;
324 x->prev->next = x->next;
334 FREE_AND_NULL(x->comment);
335 FREE_AND_NULL(x->template);
336 FREE_AND_NULL(x->host);
337 FREE_AND_NULL(x->file);
338 FREE_AND_NULL(x->mime);
345 struct MIME_LIST_LIST *mime_ll_new(struct MIME_LIST_LIST *x)
348 x = xmalloc(sizeof(*x));
351 while (x->next != NULL)
353 x->next = xmalloc(sizeof(*x));
373 free memory used by a MIME_LIST-type struct
375 void mime_free(MIME_LIST * mime_list)
380 mime_ll_free(mime_list->allow);
381 mime_ll_free(mime_list->deny);
383 FREE_AND_NULL(mime_list->dtemplate);
385 pthread_rwlock_destroy(&mime_list->lock);
390 void mime_ll_free(struct MIME_LIST_LIST *ml)
392 struct MIME_LIST_LIST *tmp;
403 FREE_AND_NULL(ml->comment);
404 FREE_AND_NULL(ml->host);
405 FREE_AND_NULL(ml->file);
406 FREE_AND_NULL(ml->mime);
407 FREE_AND_NULL(ml->template);
416 check if a specific mime-type is allowed, and return pointer to list node
419 struct MIME_LIST_LIST *mime_check(MIME_LIST * mime_list, CONNECTION * connection)
421 int action = FALSE, result = TRUE, ret, i;
422 struct MIME_LIST_LIST *current, *match = NULL;
424 pthread_rwlock_rdlock(&mime_list->lock);
426 if (mime_list->enabled == FALSE || connection->bypass & FEATURE_MIME)
429 for (i = 0; i < 2; i++) {
431 if (mime_list->policy == POLICY_ALLOW) {
432 current = mime_list->deny;
436 current = mime_list->allow;
440 } else if (result == action) {
441 if (mime_list->policy == POLICY_ALLOW) {
442 current = mime_list->allow;
445 current = mime_list->deny;
451 for (; current != NULL; current = current->next) {
452 if (current->enabled == FALSE)
455 if (current->he != NULL) {
456 ret = reg_exec(current->he, connection->header->host);
461 if (current->fe != NULL) {
462 ret = reg_exec(current->fe, connection->header->file);
467 if (current->me != NULL && connection->rheader->content_type != NULL) {
468 ret = reg_exec(current->me, connection->rheader->content_type);
471 } else if (current->me != NULL)
480 return (!result) ? (match != NULL) ? match : mime_list->empty : NULL;