]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
added proxy authentication patch from Jon Thackray <jrmt@uk.gdscorp.com>
authorwessels <>
Tue, 27 Aug 1996 04:47:45 +0000 (04:47 +0000)
committerwessels <>
Tue, 27 Aug 1996 04:47:45 +0000 (04:47 +0000)
CONTRIBUTORS
include/util.h
lib/Makefile.in
lib/uudecode.c [new file with mode: 0644]
src/cache_cf.cc
src/client_side.cc
src/errorpage.cc
src/main.cc
src/redirect.cc
src/squid.h
src/stat.cc

index 0e72c8abfe70381bdf83b1279fd8b8469818c2f4..141fb8f33c4681fa53da3c67c8dba76417ed88d8 100644 (file)
@@ -1,5 +1,4 @@
-Special thanks go to people who have volunteered their time, effort, 
-and ideas to make this software available.
+Special thanks go to people who have volunteered their time, effort, and ideas to make this software available.
 
        Henrik Nordstrom <henrik.nordstrom@ida.his.se>
        Daniel O'Callaghan <danny@miriworld.its.unimelb.EDU.AU>
@@ -30,6 +29,7 @@ and ideas to make this software available.
        Russell Street <r.street@auckland.ac.nz>
        Cord Beermann <webadm@cc.fh-lippe.de>
        Stephen R. van den Berg <srb@cuci.nl>
+       Jon Thackray <jrmt@uk.gdscorp.com>
 
 
 Development of this caching software is funded by the National Science
index ee28cc6cdcd623f4b89e446ab5573fc0070e7c82..6cf0f81c4cb841dc0163a03f967f70d02b271f0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: util.h,v 1.9 1996/08/26 19:56:59 wessels Exp $
+ * $Id: util.h,v 1.10 1996/08/26 22:47:46 wessels Exp $
  *
  * AUTHOR: Harvest Derived
  *
@@ -199,4 +199,6 @@ extern void errorlog();
 
 extern void Tolower _PARAMS((char *));
 
+extern char *uudecode _PARAMS((char *));
+
 #endif /* ndef _UTIL_H_ */
index 0e2aefd8f500da6119ded4dcd8e9e139c0388194..6e1adbacc2062f8e72c2acf660434b87efbf294d 100644 (file)
@@ -3,7 +3,7 @@
 #
 #  Darren Hardy, hardy@cs.colorado.edu, April 1994
 #
-#  $Id: Makefile.in,v 1.11 1996/08/26 19:57:00 wessels Exp $
+#  $Id: Makefile.in,v 1.12 1996/08/26 22:47:47 wessels Exp $
 #
 prefix         = @prefix@
 srcdir         = @srcdir@
@@ -27,7 +27,8 @@ UTILOBJS      = rfc850.o \
                  debug.o \
                  log.o \
                  tempnam.o \
-                 base64.o
+                 base64.o \
+                 uudecode.o
 REGEXOBJS      = GNUregex.o
 LIBS           = libmiscutil.a libregex.a
 
diff --git a/lib/uudecode.c b/lib/uudecode.c
new file mode 100644 (file)
index 0000000..c615f00
--- /dev/null
@@ -0,0 +1,65 @@
+#include "util.h"
+
+extern char** environ;
+
+/* aaaack but it's fast and const should make it shared text page. */
+const int pr2six[256]={
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
+    52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
+    10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
+    28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+    64,64,64,64,64,64,64,64,64,64,64,64,64
+};
+
+char *uudecode(char *bufcoded) {
+    int nbytesdecoded;
+    register unsigned char *bufin;
+    register char *bufplain;
+    register unsigned char *bufout;
+    register int nprbytes;
+    
+    /* Strip leading whitespace. */
+    
+    while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
+    
+    /* Figure out how many characters are in the input buffer.
+     * Allocate this many from the per-transaction pool for the result.
+     */
+    bufin = (unsigned char *)bufcoded;
+    while(pr2six[*(bufin++)] <= 63);
+    nprbytes = (char *)bufin - bufcoded - 1;
+    nbytesdecoded = ((nprbytes+3)/4) * 3;
+
+    bufplain = xmalloc(nbytesdecoded + 1);
+    if (bufplain == NULL)
+      return(NULL);
+    bufout = (unsigned char *)bufplain;
+    
+    bufin = (unsigned char *)bufcoded;
+    
+    while (nprbytes > 0) {
+        *(bufout++) = 
+            (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
+        *(bufout++) = 
+            (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
+        *(bufout++) = 
+            (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
+        bufin += 4;
+        nprbytes -= 4;
+    }
+    
+    if(nprbytes & 03) {
+        if(pr2six[bufin[-2]] > 63)
+            nbytesdecoded -= 2;
+        else
+            nbytesdecoded -= 1;
+    }
+    bufplain[nbytesdecoded] = '\0';
+    return bufplain;
+}
index 6378d268fa5f031c7a3c2c822bff0b5faf343840..9651d9a3ba36d976e8944eb829e014511c5526ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cache_cf.cc,v 1.71 1996/08/26 22:00:04 wessels Exp $
+ * $Id: cache_cf.cc,v 1.72 1996/08/26 22:47:49 wessels Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -145,6 +145,10 @@ struct SquidConfig Config;
 #define DefaultCacheLogFile    DEFAULT_CACHE_LOG
 #define DefaultAccessLogFile   DEFAULT_ACCESS_LOG
 #define DefaultStoreLogFile    DEFAULT_STORE_LOG
+#if USE_PROXY_AUTH
+#define DefaultProxyAuthFile    (char *)NULL   /* default NONE */
+#define DefaultProxyAuthIgnoreDomain "none-at-all"
+#endif /* USE_PROXY_AUTH */
 #define DefaultLogRotateNumber  10
 #define DefaultAdminEmail      "webmaster"
 #define DefaultFtpgetProgram   DEFAULT_FTPGET
@@ -667,6 +671,22 @@ static void parseDirLine()
     wordlistAdd(&Config.cache_dirs, token);
 }
 
+#if USE_PROXY_AUTH
+static void parseProxyAuthLine()
+{
+    char *token;
+
+    token = strtok(NULL, w_space);
+    if (token == NULL)
+        self_destruct();
+    safe_free(Config.proxyAuthFile);
+    safe_free(Config.proxyAuthIgnoreDomain);
+    Config.proxyAuthFile = xstrdup(token);
+    if ((token = strtok(NULL, w_space)))
+        Config.proxyAuthIgnoreDomain = xstrdup(token);
+}
+#endif /* USE_PROXY_AUTH */
+
 static void parseHttpdAccelLine()
 {
     char *token;
@@ -1196,6 +1216,11 @@ int parseConfigFile(file_name)
        else if (!strcmp(token, "redirect_children"))
            parseIntegerValue(&Config.redirectChildren);
 
+#if USE_PROXY_AUTH
+         else if (!strcmp(token, "proxy_authentication"))
+             parseProxyAuthLine();
+#endif /* USE_PROXY_AUTH */
+
        else if (!strcmp(token, "source_ping"))
            parseOnOff(&Config.sourcePing);
 
@@ -1386,6 +1411,10 @@ static void configFreeMemory()
     safe_free(Config.pidFilename);
     safe_free(Config.visibleHostname);
     safe_free(Config.ftpUser);
+#if USE_PROXY_AUTH
+    safe_free(Config.proxyAuthFile);
+    safe_free(Config.proxyAuthIgnoreDomain);
+#endif /* USE_PROXY_AUTH */
     safe_free(Config.Announce.host);
     safe_free(Config.Announce.file);
     safe_free(Config.errHtmlText);
@@ -1463,6 +1492,10 @@ static void configSetFactoryDefaults()
     Config.Accel.withProxy = DefaultAccelWithProxy;
     Config.pidFilename = safe_xstrdup(DefaultPidFilename);
     Config.visibleHostname = safe_xstrdup(DefaultVisibleHostname);
+#if USE_PROXY_AUTH
+    Config.proxyAuthFile = safe_xstrdup(DefaultProxyAuthFile);
+    Config.proxyAuthIgnoreDomain = safe_xstrdup(DefaultProxyAuthIgnoreDomain);
+#endif /* USE_PROXY_AUTH */
     Config.ftpUser = safe_xstrdup(DefaultFtpUser);
     Config.Announce.host = safe_xstrdup(DefaultAnnounceHost);
     Config.Announce.port = DefaultAnnouncePort;
index 086bbcd3ef0dfbec2ed8b2afbd74e2fcb808c690..aafb67a80986018aa6c508199c504980b9d36aa8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.9 1996/08/20 15:44:17 wessels Exp $
+ * $Id: client_side.cc,v 1.10 1996/08/26 22:47:50 wessels Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -74,6 +74,33 @@ static void clientLookupIdentDone(data)
 {
 }
 
+#if USE_PROXY_AUTH
+/* return 1 if allowed, 0 if denied */
+static int clientProxyAuthCheck(icpState)
+     icpStateData *icpState;
+{
+    char *proxy_user;
+
+    /* Check that the user is allowed to access via this proxy-cache
+     * don't restrict if they're accessing a local domain or
+     * an object of type cacheobj:// */
+    if (Config.proxyAuthFile == NULL)
+       return 1;
+    if (strstr(icpState->url, Config.proxyAuthIgnoreDomain))
+       return 1;
+    if (urlParseProtocol(icpState->url) == PROTO_CACHEOBJ)
+       return 1;
+
+    proxy_user = proxyAuthenticate(icpState->request_hdr);
+    strncpy(icpState->ident, proxy_user, ICP_IDENT_SZ);
+    debug(12, 6, "jrmt: user = %s\n", icpState->ident);
+
+    if (strcmp(icpState->ident, dash_str) == 0)
+       return 0;
+    return 1;
+}
+#endif /* USE_PROXY_AUTH */
+
 void clientAccessCheck(icpState, handler)
      icpStateData *icpState;
      void (*handler) _PARAMS((icpStateData *, int));
@@ -81,11 +108,28 @@ void clientAccessCheck(icpState, handler)
     int answer = 1;
     request_t *r = icpState->request;
     aclCheck_t *ch = NULL;
+
     if (icpState->aclChecklist == NULL) {
        icpState->aclChecklist = xcalloc(1, sizeof(aclCheck_t));
        icpState->aclChecklist->src_addr = icpState->peer.sin_addr;
        icpState->aclChecklist->request = requestLink(icpState->request);
     }
+#if USE_PROXY_AUTH
+    if (clientProxyAuthCheck == 0) {
+        char *wbuf = NULL;
+        int fd = icpState->fd;
+       debug(12, 4, "Proxy Denied: %s\n", icpState->url);
+       icpState->log_type = ERR_PROXY_DENIED;
+       icpState->http_code = 407;
+       wbuf = xstrdup(proxy_denied_msg(icpState->http_code,
+               icpState->method,
+               icpState->url,
+               fd_table[fd].ipaddr));
+       icpSendERROR(fd, icpState->log_type, wbuf, icpState, icpState->http_code);
+       return;
+    }
+#endif /* USE_PROXY_AUTH */
+
     ch = icpState->aclChecklist;
     icpState->aclHandler = handler;
     if (httpd_accel_mode && !Config.Accel.withProxy && r->protocol != PROTO_CACHEOBJ) {
@@ -161,4 +205,146 @@ static void clientRedirectDone(data, result)
        (PF) icpDetectClientClose,
        (void *) icpState);
     icp_hit_or_miss(fd, icpState);
+#if USE_PROXY_AUTH
+}
+
+/* Check the modification time on the file that holds the proxy
+ * passwords every 'n' seconds, and if it has changed, reload it
+ */
+#define CHECK_PROXY_FILE_TIME 300
+
+char *proxyAuthenticate(char *headers)
+{
+    /* Keep the time measurements and the hash
+     * table of users and passwords handy */
+    static time_t last_time = 0;
+    static time_t change_time = 0;
+    static HashID validated = 0;
+    static char *passwords = NULL;
+    LOCAL_ARRAY(char, sent_user, ICP_IDENT_SZ);
+
+    char *s = NULL;
+    char *sent_userandpw = NULL;
+    char *user = NULL;
+    char *passwd = NULL;
+    char *clear_userandpw = NULL;
+    time_t current_time;
+    struct stat buf;
+    int i;
+    hash_link *hashr = NULL;
+    FILE *f = NULL;
+
+    /* Look for Proxy-[Aa]uthorization: Basic in the
+     * headers sent by the client
+     */
+    if ((s = mime_get_header(headers, "Proxy-authorization:")) == NULL) {
+       /* Check for MS Internet Explorer too, as well as Netscape
+        * FIXME: Need a version of mime_get_header that uses strcasecmp()
+        */
+       if ((s = mime_get_header(headers, "Proxy-Authorization:")) == NULL) {
+           debug(12, 5, "jrmt: Can't find authorization header\n");
+           return (dash_str);
+       }
+    }
+    /* Skip the 'Basic' part */
+    s += strlen(" Basic");
+    sent_userandpw = xstrdup(s);
+    strtok(sent_userandpw, "\n");      /* Trim trailing \n before decoding */
+    clear_userandpw = uudecode(sent_userandpw);
+    xfree(sent_userandpw);
+
+    strncpy(sent_user, clear_userandpw, ICP_IDENT_SZ);
+    strtok(sent_user, ":");    /* Remove :password */
+    debug(12, 5, "jrmt: user = %s\n", sent_user);
+
+    /* Look at the Last-modified time of the proxy.passwords
+     * file every ten seconds, to see if it's been changed via
+     * a cgi-bin script, etc. If so, reload a fresh copy into memory
+     */
+
+    current_time = time(NULL);
+
+    if ((current_time - last_time) > CHECK_PROXY_FILE_TIME) {
+       debug(12, 5, "jrmt: checking password file %s hasn't changed\n", Config.proxyAuthFile);
+
+       if (stat(Config.proxyAuthFile, &buf) == 0) {
+           if (buf.st_mtime != change_time) {
+               debug(12, 0, "jrmt: reloading changed proxy authentication password file %s \n", Config.proxyAuthFile);
+               change_time = buf.st_mtime;
+
+               if (passwords != NULL)
+                   xfree(passwords);
+
+               if (validated != 0) {
+                   debug(12, 5, "jrmt: invalidating old entries\n");
+                   for (i = 0, hashr = hash_first(validated); hashr; hashr = hash_next(validated)) {
+                       debug(12, 6, "jrmt: deleting %s\n", hashr->key);
+                       hash_delete(validated, hashr->key);
+                   }
+               } else {
+                   /* First time around, 7921 should be big enough for GDS :-) */
+                   if ((validated = hash_create(urlcmp, 7921, hash_string)) < 0) {
+                       debug(1, 1, "ERK: can't create hash table. Turning auth off");
+                       Config.proxyAuthOn = 0;
+                       return (dash_str);
+                   }
+               }
+
+               passwords = xmalloc((size_t) buf.st_size + 2);
+               f = fopen(Config.proxyAuthFile, "r");
+               fread(passwords, buf.st_size, 1, f);
+               *(passwords + buf.st_size) = '\0';
+               strcat(passwords, "\n");
+               fclose(f);
+
+               user = strtok(passwords, ":");
+               passwd = strtok(NULL, "\n");
+
+               debug(12, 5, "jrmt: adding new passwords to hash table\n");
+               while (user != NULL) {
+                   if (strlen(user) > 1 && strlen(passwd) > 1) {
+                       debug(12, 6, "jrmt: adding %s, %s to hash table\n", user, passwd);
+                       hash_insert(validated, user, (void *) passwd);
+                   }
+                   user = strtok(NULL, ":");
+                   passwd = strtok(NULL, "\n");
+               }
+           }
+       } else {
+           debug(1, 1, "ERK: can't access proxy_auth_file %s. Turning authentication off until SIGHUPed", Config.proxyAuthFile);
+           Config.proxyAuthOn = 0;
+           return (dash_str);
+       }
+    }
+    last_time = current_time;
+
+    hashr = hash_lookup(validated, sent_user);
+    if (hashr == NULL) {
+       /* User doesn't exist; deny them */
+       debug(12, 4, "jrmt: user %s doesn't exist\n", sent_user);
+       xfree(clear_userandpw);
+       return (dash_str);
+    }
+    /* See if we've already validated them */
+    if (strcmp(hashr->item, "OK") == 0) {
+       debug(12, 5, "jrmt: user %s previously validated\n", sent_user);
+       xfree(clear_userandpw);
+       return sent_user;
+    }
+    passwd = strstr(clear_userandpw, ":");
+    passwd++;
+
+    if (strcmp(hashr->item, (char *) crypt(passwd, hashr->item))) {
+       /* Passwords differ, deny access */
+       debug(12, 4, "jrmt: authentication failed: user %s passwords differ\n", sent_user);
+       debug(12, 6, "jrmt: password given: %s, actual %s\n", passwd, hashr->item);
+       xfree(clear_userandpw);
+       return (dash_str);
+    }
+    debug(12, 5, "jrmt: user %s validated\n", sent_user);
+    hash_insert(validated, sent_user, (void *) "OK");
+
+    xfree(clear_userandpw);
+    return (sent_user);
+#endif /* USE_PROXY_AUTH */
 }
index 925284c4623c10d9b1fc082489593783c14863c2..deec1c632871fcd2b15ad38a43f739387121fccf 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.cc,v 1.31 1996/08/26 19:09:59 wessels Exp $
+ * $Id: errorpage.cc,v 1.32 1996/08/26 22:47:51 wessels Exp $
  *
  * DEBUG: section 4     Error Generation
  * AUTHOR: Duane Wessels
@@ -127,7 +127,11 @@ static char *auth_msg = NULL;
 
 void errorInitialize()
 {
+#ifndef USE_PROXY_AUTH
     tmp_error_buf = xmalloc(MAX_URL * 4);
+#else
+    tmp_error_buf = xmalloc(8192);
+#endif /* USE_PROXY_AUTH */
     meta_data.misc += MAX_URL * 4;
     tbuf = xmalloc(MAX_URL * 3);
     meta_data.misc += MAX_URL * 3;
@@ -317,3 +321,49 @@ WWW-Authenticate: Basic realm=\"%s\"\r\n\
        tbuf, realm, auth_msg);
     return tmp_error_buf;
 }
+
+
+#define PROXY_AUTH_ERR_MSG "\
+HTTP/1.0 %d Cache Access Denied\r\n\
+Proxy-Authenticate: Basic realm=\"Squid proxy-caching web server\"\r\n\
+Content-type: text/html\r\n\
+\r\n\
+<TITLE>Cache Access Denied</TITLE>\n\
+<H2>Cache Access Denied</H2>\n\
+<P>\n\
+Sorry, you are not currently allowed to request\n\
+<PRE>    %s</PRE>\n\
+from this cache until you have authenticated yourself.\n\
+\n<p>\
+You need to use Netscape version 2.0 or greater, or Microsoft Internet Explorer 3.0\n\
+or an HTTP/1.1 compliant browser for this to work.\n\
+Please contact the <a href=\"mailto:%s\">cache administrator</a>\n\
+if you have difficulties authenticating yourself, or\n\
+<a href=\"http://%s/cgi-bin/chpasswd.cgi\">change</a>\n\
+your default password.\n\
+<P>\n\
+%s\n\
+<HR>\n\
+<ADDRESS>\n\
+Generated by %s/%s@%s\n\
+</ADDRESS>\n\
+"
+
+char *proxy_denied_msg(code, method, url, client)
+     int code;
+     int method;
+     char *url;
+     char *client;
+{
+    sprintf(tmp_error_buf, PROXY_AUTH_ERR_MSG,
+       code,
+       url,
+       Config.adminEmail,
+       getMyHostname(),
+       Config.errHtmlText,
+       appname,
+       version_string,
+       getMyHostname());
+    return tmp_error_buf;
+}
+
index 7c4301c08608ce49c1ff85716ee8b0c2bdfd206e..2324b04c45abcb8778c16d6b67789090269f82e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: main.cc,v 1.62 1996/08/26 19:13:03 wessels Exp $
+ * $Id: main.cc,v 1.63 1996/08/26 22:47:54 wessels Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -127,6 +127,7 @@ char version_string[] = SQUID_VERSION;
 char appname[] = "squid";
 char localhost[] = "127.0.0.1";
 struct in_addr local_addr;
+char *dash_str = "-";
 
 /* for error reporting from xmalloc and friends */
 extern void (*failure_notify) _PARAMS((char *));
index 472a0f64a0df8a8fab88aef969220f05b8354c31..f700cb6fc8b0e4fbb9ec6b2ea59d2abc4db6e3c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: redirect.cc,v 1.11 1996/08/20 15:44:18 wessels Exp $
+ * $Id: redirect.cc,v 1.12 1996/08/26 22:47:55 wessels Exp $
  *
  * DEBUG: section 29    Redirector
  * AUTHOR: Duane Wessels
@@ -83,7 +83,6 @@ static int NRedirectors = 0;
 static int NRedirectorsOpen = 0;
 static struct redirectQueueData *redirectQueueHead = NULL;
 static struct redirectQueueData **redirectQueueTailP = &redirectQueueHead;
-static char *dash_str = "-";
 
 static int redirectCreateRedirector(command)
      char *command;
index a50439f801ad71a44b2b7a61af99204abe93d1cc..af6c0ada975830ca0c8e896ba8c376072ea272a0 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: squid.h,v 1.40 1996/08/26 22:00:07 wessels Exp $
+ * $Id: squid.h,v 1.41 1996/08/26 22:47:56 wessels Exp $
  *
  * AUTHOR: Duane Wessels
  *
@@ -293,3 +293,4 @@ extern void ttlAddToList _PARAMS((char *, time_t, int, time_t));
 extern void ttlAddToForceList _PARAMS((char *, time_t, time_t));
 extern int waisStart _PARAMS((int, char *, method_t, char *, StoreEntry *));
 extern void storeDirClean _PARAMS((void));
+extern char *dash_str;
index 43b1dc5bad54f0afc76922ff12246f611a5a376a..2214cb320fca42d1bf93d99feaf66af71989f843 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: stat.cc,v 1.53 1996/08/14 21:58:03 wessels Exp $
+ * $Id: stat.cc,v 1.54 1996/08/26 22:47:57 wessels Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -882,10 +882,9 @@ void log_append(obj, url, caddr, size, action, method, http_code, msec, ident, h
 {
     LOCAL_ARRAY(char, tmp, 6000);      /* MAX_URL is 4096 */
     int x;
-    static char *dash = "-";
     char *client = NULL;
     hier_code hier_code = HIER_NONE;
-    char *hier_host = dash;
+    char *hier_host = dash_str;
     int hier_timeout = 0;
 
     if (Config.Log.log_fqdn)
@@ -896,14 +895,14 @@ void log_append(obj, url, caddr, size, action, method, http_code, msec, ident, h
     getCurrentTime();
 
     if (!method)
-       method = dash;
+       method = dash_str;
     if (!url)
-       url = dash;
+       url = dash_str;
     if (!ident || ident[0] == '\0')
-       ident = dash;
+       ident = dash_str;
     if (hierData) {
        hier_code = hierData->code;
-       hier_host = hierData->host ? hierData->host : dash;
+       hier_host = hierData->host ? hierData->host : dash_str;
        hier_timeout = hierData->timeout;
     }
     if (obj->logfile_status == LOG_ENABLE) {