head	1.1;
access;
symbols;
locks; strict;
comment	@# @;


1.1
date	2012.09.04.13.45.28;	author rea;	state Exp;
branches;
next	;


desc
@@


1.1
log
@SVN rev 303652 on 2012-09-04 13:45:28Z by rea

security/squidclamav: fix DoS and XSS vulnerabilities

Apply upstream patches for CVE-2012-3501 and CVE-2012-4667.

Security:	http://www.vuxml.org/freebsd/ce680f0a-eea6-11e1-8bd8-0022156e8794.html
Security:	http://www.vuxml.org/freebsd/8defa0f9-ee8a-11e1-8bd8-0022156e8794.html
PR:		171022
QA page:	http://codelabs.ru/fbsd/ports/qa/security/squidclamav/5.7_1
Approved by:	maintainer timeout (1 week)
@
text
@Fix CVE-2012-3501, DoS when external URL checker is used

This fix was integrated into 6.7 and 5.8.

Obtained-from: https://github.com/darold/squidclamav/commit/80f74451f628264d1d9a1f1c0bbcebc932ba5e00.diff

--- src/squidclamav.c.orig	2010-12-11 15:20:46.000000000 +0300
+++ src/squidclamav.c	2012-08-25 15:55:51.708586983 +0400
@@@@ -62,6 +62,7 @@@@
 static char * escape_quote (char *s);
 void timeit (struct timeval start, char *level);
 int dconnect (void);
+char * replace(const char *s, const char *old, const char *new);
 void replace_chr(char string[], char *from, char *to);
 void free_global ();		/* routine to free global pointer */
 void freeBuff (struct IN_BUFF);
@@@@ -474,11 +475,15 @@@@
       /* chaining with SquidGuard - before bridge mode or not*/
       if ((bridge_mode == 0) && (squidguard != NULL)) {
 		if (usepipe == 1) {
+ 			char *rbuff = NULL;
+			/* escaping escaped character to prevent unescaping by squidguard */
+			rbuff = replace(rbuff, "%", "%25");
 			if (debug > 0)
 			    logit(log_file, "DEBUG Sending request to chained program: %s\n", squidguard);
 			fprintf(sgfpw,"%s\n",sbuff);
 			fflush(sgfpw);
 			xfree(escaped);
+			xfree(rbuff);
 			escaped = NULL;
 			/* the chained redirector must return empty line if ok or the redirection url */
 			chain_ret = (char *)malloc(sizeof(char)*MAX_URL);
@@@@ -1114,3 +1119,38 @@@@
 }
 
 
+/**
+ * Searches all occurrences of old into s
+ * and replaces with new
+ */
+char *
+replace(const char *s, const char *old, const char *new)
+{
+	char *ret;
+	int i, count = 0;
+	size_t newlen = strlen(new);
+	size_t oldlen = strlen(old);
+
+	for (i = 0; s[i] != '\0'; i++) {
+		if (strstr(&s[i], old) == &s[i]) {
+			count++;
+			i += oldlen - 1;
+		}
+	}
+	ret = malloc(i + 1 + count * (newlen - oldlen));
+	if (ret != NULL) {
+		i = 0;
+		while (*s) {
+			if (strstr(s, old) == s) {
+				strcpy(&ret[i], new);
+				i += newlen;
+				s += oldlen;
+			} else {
+				ret[i++] = *s++;
+			}
+		}
+		ret[i] = '\0';
+	}
+
+	return ret;
+}
@
