summaryrefslogtreecommitdiff
path: root/www/mod_auth_any
diff options
context:
space:
mode:
authorMario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>2003-03-25 04:23:11 +0000
committerMario Sergio Fujikawa Ferreira <lioux@FreeBSD.org>2003-03-25 04:23:11 +0000
commit0025bdf0b2935e18a51f4a900650754c207175a5 (patch)
tree7843767d8e7a5f47abe9adc65b6afa236e27f1d4 /www/mod_auth_any
parentBump PORTREVISION by updating audio/speex. (diff)
o Fix vulnerability that allows execution of arbitrary commands on
the server with the uid of the apache process. Background [1]: "The module accepts a username and password from the web client, passes them to a user-space executable (using popen(3), which invokes a shell) and waits for a response in order to authenticate the user. The password is quoted on the popen() command line to avoid interpretation of shell special chars, but the username is not. Thus a malicious user can execute commands by supplying an appropriately crafted username. (e.g. "foo&mail me@my.home</etc/passwd") "The problem is easily fixed by adding quotes (and escaping any quotes already present) to the username and password in the popen command line." o Fix this by adding a escaping function from [2]. Then, modifying this function appropriately with ideas from [3]. Apply the new escaping code to mod_auth_any. o Bump PORTREVISION Submitted by: Security Officer (nectar), Red Hat Security Response Team <security@redhat.com> [1] Obtained from: mod_auth_any CVS [2], nalin@redhat.com [3]
Notes
Notes: svn path=/head/; revision=77439
Diffstat (limited to 'www/mod_auth_any')
-rw-r--r--www/mod_auth_any/Makefile5
-rw-r--r--www/mod_auth_any/files/bash_single_quote_escape_string.c45
-rw-r--r--www/mod_auth_any/files/patch-mod_auth_any.c37
3 files changed, 87 insertions, 0 deletions
diff --git a/www/mod_auth_any/Makefile b/www/mod_auth_any/Makefile
index 9616135cb8f3..50a0c52c2028 100644
--- a/www/mod_auth_any/Makefile
+++ b/www/mod_auth_any/Makefile
@@ -7,6 +7,7 @@
PORTNAME= mod_auth_any
PORTVERSION= 1.0.2
+PORTREVISION= 1
CATEGORIES= www
MASTER_SITES= ftp://ftp.itlab.musc.edu/pub/toolbox/mod_auth_any/
EXTRACT_SUFX= .tgz
@@ -20,6 +21,10 @@ RUN_DEPENDS= ${APXS}:${APACHE_PORT}
APXS?= ${LOCALBASE}/sbin/apxs
APACHE_PORT?= ${PORTSDIR}/www/apache13
+post-patch:
+ @${CAT} ${FILESDIR}/bash_single_quote_escape_string.c >> \
+ ${WRKSRC}/${PORTNAME}.c
+
do-build:
@cd ${WRKSRC} && ${APXS} -c ${PORTNAME}.c
diff --git a/www/mod_auth_any/files/bash_single_quote_escape_string.c b/www/mod_auth_any/files/bash_single_quote_escape_string.c
new file mode 100644
index 000000000000..439b205c4426
--- /dev/null
+++ b/www/mod_auth_any/files/bash_single_quote_escape_string.c
@@ -0,0 +1,45 @@
+/* Escape special characters in the input string so that the bash
+ shell will not interpolate them when the input string is withing
+ single quotes.
+
+ IN: null-terminated character array containing string to be interpolated
+ OUT: newly allocate (using malloc) null-terminated character array
+ containing the input string with the special characters properly
+ escaped */
+char* bash_single_quote_escape_string(const char *s) {
+ /* used to count the length of the string and the number of single quotes */
+ int str_len, sq_count;
+ int s_pos, buf_pos; /* copy chars loop counter */
+ /* used to hold the final result string */
+ char *buf;
+ const char *escapees = "\"'\\$~` \t|&;()<>";
+
+ /* Count the single quotes.
+ LOOP INVARIANT: str_len < (number of chars in string 's')
+ POSTCONDITION: sq_count == (number of single quotes in string 's') */
+ for (str_len = 0, sq_count = 0; s[str_len] != '\0'; str_len++)
+ if (strchr(escapees, s[str_len]) != NULL)
+ sq_count++;
+
+ /* Allocate the memory for the final string.
+ Each ' (one char) will become \' (2 chars), so multiply by 2
+ and don't forget to add 1 for terminating null. */
+ buf = (char*) malloc(sizeof(char) * (str_len + 1 + sq_count * 2));
+
+ /* Copy the chars of 's' into 'buf', turning each ' into \' */
+ for (s_pos = 0, buf_pos = 0; s_pos < str_len; s_pos++) {
+ /* If we see a single quote, then put '\'' into 'buf' and advance
+ buf_pos 4 positions, else put the next char from 's' into 'buf'
+ and advance buf_pos 1 position. */
+ if(strchr(escapees, s[s_pos]) != NULL) {
+ buf[buf_pos++] = '\\';
+ buf[buf_pos++] = s[s_pos];
+ } else {
+ buf[buf_pos++] = s[s_pos];
+ }
+ }
+ /* don't forget the null terminator */
+ buf[buf_pos] = '\0';
+
+ return buf;
+}
diff --git a/www/mod_auth_any/files/patch-mod_auth_any.c b/www/mod_auth_any/files/patch-mod_auth_any.c
new file mode 100644
index 000000000000..e234b8517b10
--- /dev/null
+++ b/www/mod_auth_any/files/patch-mod_auth_any.c
@@ -0,0 +1,37 @@
+--- mod_auth_any.c.orig Tue Jan 9 05:48:20 2001
++++ mod_auth_any.c Tue Mar 25 01:09:55 2003
+@@ -121,6 +121,7 @@
+
+ */
+
++char* bash_single_quote_escape_string(const char *);
+
+ /* NB: debugging stuff */
+ extern int errno;
+@@ -180,13 +181,25 @@
+ const char *rpw, *w;
+ FILE* ext_authprog;
+ FILE* fp;
++ char *escaped_user, *escaped_password;
+
+ l = (char*) malloc (MAX_STRING_LEN * sizeof(char));
++ memset (l, '\0', MAX_STRING_LEN);
+ execstr = (char*) malloc (MAX_STRING_LEN * sizeof(char));
+
+ setenv ("REMOTE_ADDR", r -> connection -> remote_ip, 1);
++
++ /* escape the user name and the password */
++ escaped_user = bash_single_quote_escape_string(user);
++ escaped_password = bash_single_quote_escape_string(password);
++
+ /* open the program stream */
+- snprintf (execstr, MAX_STRING_LEN, "%s %s \"%s\"", auth_pwfile, user, password);
++ snprintf (execstr, MAX_STRING_LEN, "%s %s %s", auth_pwfile, escaped_user, escaped_password);
++
++ /* free the escaped user and password before we forget */
++ free(escaped_user);
++ free(escaped_password);
++
+ if (!(ext_authprog = popen (execstr, "r"))) {
+
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Could not popen() on program: %s: %s",