+++ /dev/null
---- mod_auth_any-1.2.2/src/mod_auth_any.c.fork 2002-07-02 15:40:25.000000000 -0400
-+++ mod_auth_any-1.2.2/src/mod_auth_any.c 2003-03-19 12:47:44.000000000 -0500
-@@ -170,127 +170,98 @@
-
- module MODULE_VAR_EXPORT auth_any_module;
-
--/* 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;
--
-- /* 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 (s[str_len] == '\'')
-- sq_count++;
--
-- /* Allocate the memory for the final string.
-- Each ' (one char) will become '\'' (4 chars), so multiply by 4
-- and don't forget to add 1 for terminating null. */
-- buf = (char*) malloc(sizeof(char) * (str_len + 1 + sq_count * 4));
--
-- /* 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(s[s_pos] == '\'') {
-- buf[buf_pos++] = '\'';
-- buf[buf_pos++] = '\\';
-- buf[buf_pos++] = '\'';
-- buf[buf_pos++] = '\'';
-- } else {
-- buf[buf_pos++] = s[s_pos];
-- }
-- }
-- /* don't forget the null terminator */
-- buf[buf_pos] = '\0';
--
-- return buf;
--}
--
- /*
-- nb:
--
-- The popen() call to the external validator program is made here.
--*/
-+ * Call the external program auth_pwfile with user and password as its
-+ * arguments. These should have been passed in over a pipe, but it's too
-+ * late to change that now. The called program should print the name of the
-+ * valid user to stdout, or print "Authentication Error" on failure.
-+ */
- static char *get_pw(request_rec *r, char *user, const char* password, char *auth_pwfile) {
-- configfile_t *f;
-- char* execstr;
-- char* l;
-- const char *rpw, *w;
-- FILE* ext_authprog;
-- FILE* fp;
-- char *escaped_password;
-+ char result[256];
-+ int fd[2], i, length = 0;
-+ pid_t pid;
- #ifdef __sun
- static char m_envstr[256]; /* sun's putenv() call is a bunch of bull malarkey */
- #endif
--
-- l = (char*) malloc (MAX_STRING_LEN * sizeof(char));
-- execstr = (char*) malloc (MAX_STRING_LEN * sizeof(char));
-
--#ifdef __sun
-- snprintf (m_envstr, 256, "%s=%s\0", "REMOTE_ADDR", r -> connection -> remote_ip);
-- putenv (m_envstr);
--#else
-- setenv ("REMOTE_ADDR", r -> connection -> remote_ip, 1);
--#endif
--
-- /* escape the password */
-- escaped_password = bash_single_quote_escape_string(password);
--
-- /* open the program stream */
-- snprintf (execstr, MAX_STRING_LEN, "%s %s \'%s\'", auth_pwfile, user, escaped_password);
--
-- /* free the escaped password before we forget */
-- free(escaped_password);
-+ memset (result, '\0', sizeof(result));
-
-- if (!(ext_authprog = popen (execstr, "r"))) {
-+ /* sanity check the auth_pwfile */
-+ if ((auth_pwfile == NULL) || (auth_pwfile[0] != '/')) {
-+ ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Invalid program: %s",
-+ auth_pwfile);
-+ return NULL;
-+ }
-
-- ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Could not popen() on program: %s: %s",
-- auth_pwfile, strerror(errno));
-- return NULL;
-+ /* set up our communication pipe */
-+ if (pipe (fd) == -1) {
-+ /* couldn't create pipe for some reason */
-+ ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Error creating pipe: %s",
-+ strerror(errno));
-+ return NULL;
- }
-- /* whew, the popen() has seemingly succeeded, let's write the username passwd stuff*/
-- if (feof(ext_authprog) == 0)
-- fgets (l, MAX_STRING_LEN, ext_authprog);
-- pclose (ext_authprog);
--
-- if (strncmp(l, "Authentication Error", 19) == 0) /* no authorized */
-- return NULL;
-- /* otherwise, we got a winner :), return user's real name */
-- return l;
-
-- /* ignore the rest */
-- /*
-- if (!(f = ap_pcfg_openfile(r->pool, auth_pwfile))) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-- "Could not open password file: %s", auth_pwfile);
-+ /* start our child */
-+ pid = fork ();
-+ switch (pid) {
-+ case -1:
-+ /* fork failed -- clean up and return */
-+ close (fd[0]);
-+ close (fd[1]);
-+ ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Error fork()ing: %s",
-+ strerror (errno));
- return NULL;
-+ break;
-+ case 0:
-+#ifdef __sun
-+ snprintf (m_envstr, sizeof(m_envstr), "%s=%s", "REMOTE_ADDR",
-+ r -> connection -> remote_ip);
-+ putenv (m_envstr);
-+#else
-+ setenv ("REMOTE_ADDR", r -> connection -> remote_ip, 1);
-+#endif
-+ /* close open fds */
-+ i = sysconf (_SC_OPEN_MAX);
-+ while (i >= 0) {
-+ if (i != fd[1]) {
-+ fcntl (i, F_SETFD, FD_CLOEXEC);
-+ }
-+ i--;
-+ }
-+ /* make the write end of the pipe our stdout */
-+ if (fd[1] != STDOUT_FILENO) {
-+ close (STDOUT_FILENO);
-+ dup2 (fd[1], STDOUT_FILENO);
-+ fcntl (STDOUT_FILENO, F_SETFD, 0);
-+ fcntl (fd[1], F_SETFD, FD_CLOEXEC);
-+ }
-+ execl (auth_pwfile, auth_pwfile, user, password, NULL);
-+ _exit (1);
-+ break;
-+ default:
-+ /* parent: read what the child has to say, if anything */
-+ close (fd[1]);
-+ do {
-+ i = read (fd[0], result + length, sizeof(result) - length - 1);
-+ if (i != -1) {
-+ length += i;
-+ }
-+ } while ((i != -1) && (i != 0) && (length < (sizeof(result) - 1)));
-+ close (fd[0]);
-+ break;
- }
--
-- while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
-- if ((l[0] == '#') || (!l[0]))
-- continue;
-- rpw = l;
-- w = ap_getword(r->pool, &rpw, ':');
-
-- if (!strcmp(user, w)) {
-- ap_cfg_closefile(f);
-- return ap_getword(r->pool, &rpw, ':');
-- }
-+ while ((length > 0) &&
-+ ((result[length - 1] == '\r') || (result[length - 1] == '\n'))) {
-+ result[--length] = '\0';
- }
-- ap_cfg_closefile(f);
-- return NULL;
-- */
-+
-+ if ((strlen(result) == 0) ||
-+ (strncmp(result, "Authentication Error", 19) == 0)) /* not authorized */
-+ return NULL;
-+
-+ /* otherwise, we got a winner :), return user's real name */
-+ return strdup(result);
- }
-
- static table *groups_for_user(pool *p, char *user, char *grpfile)
-@@ -351,9 +322,7 @@
- conn_rec *c = r->connection;
- const char *sent_pw;
- char *real_pw;
-- char *invalid_pw;
- int res;
-- FILE* fp;
-
- if ((res = ap_get_basic_auth_pw(r, &sent_pw)))
- return res;
-@@ -423,8 +392,6 @@
- table *grpstatus;
- const array_header *reqs_arr = ap_requires(r);
- require_line *reqs;
-- FILE* fp;
--
-
- /* BUG FIX: tadc, 11-Nov-1995. If there is no "requires" directive,
- * then any user will do.