Backing out bug 468087 and bug 456001
authorHonza Bambas <honzab@allpeers.com>
Mon, 12 Jan 2009 21:47:31 +0100
changeset 23563 6ebac19183d6bca1991e2b81381156f52b5450b5
parent 23562 ffd18ce16f58537cc75b8db7a47ae4b19b594830
child 23564 8f347bf50a53e16f8aa8e08f14ee92b10cff749f
push id4607
push userhonzab.moz@firemni.cz
push dateMon, 12 Jan 2009 20:48:31 +0000
treeherdermozilla-central@6ebac19183d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs468087, 456001
milestone1.9.2a1pre
Backing out bug 468087 and bug 456001
build/pgo/automation.py.in
build/pgo/certs/Makefile.in
build/pgo/server-locations.txt
testing/mochitest/ssltunnel/ssltunnel.cpp
--- a/build/pgo/automation.py.in
+++ b/build/pgo/automation.py.in
@@ -304,17 +304,16 @@ user_pref("browser.shell.checkDefaultBro
 user_pref("shell.checkDefaultClient", false);
 user_pref("browser.warnOnQuit", false);
 user_pref("accessibility.typeaheadfind.autostart", false);
 user_pref("javascript.options.showInConsole", true);
 user_pref("layout.debug.enable_data_xbl", true);
 user_pref("browser.EULA.override", true);
 user_pref("javascript.options.jit.content", true);
 user_pref("gfx.color_management.force_srgb", true);
-user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
 
 user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
 """
   prefs.append(part)
 
   locations = readLocations()
 
   # Grant God-power to all the privileged servers on which tests run.
@@ -392,57 +391,43 @@ def fillCertificateDB(profileDir):
   sslTunnelConfigPath = os.path.join(CERTS_DIR, "ssltunnel.cfg")
   sslTunnelConfig = open(sslTunnelConfigPath, "w")
   
   sslTunnelConfig.write("httpproxy:1\n")
   sslTunnelConfig.write("certdbdir:%s\n" % CERTS_DIR)
   sslTunnelConfig.write("forward:127.0.0.1:8888\n")
   sslTunnelConfig.write("listen:*:4443:pgo server certificate\n")
 
-  # Configure automatic certificate and bind custom certificates, client authentication
+  # Generate automatic certificate and bond custom certificates
   locations = readLocations()
   locations.pop(0)
   for loc in locations:
     if loc.scheme == "https" and "nocert" not in loc.options:
       customCertRE = re.compile("^cert=(?P<nickname>[0-9a-zA-Z_ ]+)")
-      clientAuthRE = re.compile("^clientauth=(?P<clientauth>[a-z]+)")
       for option in loc.options:
         match = customCertRE.match(option)
         if match:
           customcert = match.group("nickname");
-          sslTunnelConfig.write("listen:%s:%s:4443:%s\n" %
-              (loc.host, loc.port, customcert))
-
-        match = clientAuthRE.match(option)
-        if match:
-          clientauth = match.group("clientauth");
-          sslTunnelConfig.write("clientauth:%s:%s:4443:%s\n" %
-              (loc.host, loc.port, clientauth))
+          sslTunnelConfig.write("listen:%s:%s:4443:%s\n" % (loc.host, loc.port, customcert))
+          break
 
   sslTunnelConfig.close()
 
   # Pre-create the certification database for the profile
   certutil = DIST_BIN + "/certutil" + BIN_SUFFIX
-  pk12util = DIST_BIN + "/pk12util" + BIN_SUFFIX
-
   status = Process(certutil, ["-N", "-d", profileDir, "-f", pwfilePath], environment()).wait()
   if status != 0:
     return status
 
-  # Walk the cert directory and add custom CAs and client certs
+  # Walk the cert directory and add custom CAs as trusted
   files = os.listdir(CERTS_DIR)
   for item in files:
     root, ext = os.path.splitext(item)
     if ext == ".ca":
-      Process(certutil, ["-A", "-i", os.path.join(CERTS_DIR, item),
-        "-d", profileDir, "-f", pwfilePath, "-n", root, "-t", "CT,,"],
-        environment()).wait()
-    if ext == ".client":
-      Process(pk12util, ["-i", os.path.join(CERTS_DIR, item), "-w", pwfilePath,
-        "-d", profileDir], environment()).wait()
+      Process(certutil, ["-A", "-i", os.path.join(CERTS_DIR, item), "-d", profileDir, "-f", pwfilePath, "-n", root, "-t", "CT,,"], environment())
 
   os.unlink(pwfilePath)
   return 0
 
 def environment(env = None):
   if env == None:
     env = dict(os.environ)
 
--- a/build/pgo/certs/Makefile.in
+++ b/build/pgo/certs/Makefile.in
@@ -41,34 +41,24 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 _PROFILE_DIR = $(DEPTH)/_profile/pgo
 _CERTS_DIR = $(_PROFILE_DIR)/certs
 
-# Following files will be added as trusted Certificate Authorities
-# to the PGO profile.
-# Extension of those files MUST BE '.ca'.
+# Extension of files must be '.ca'
 _CERT_AUTHORITIES = \
     pgoca.ca \
     $(NULL)
 
-
-# Following files will be added as user/client certificates
-# to the PGO profile to be used for client authentication.
-# Extension of those files MUST BE '.client'.
-_CLIENT_CERTS = \
-    mochitest.client \
-    $(NULL)
-
 _SERV_FILES = \
     pgoca.p12 \
     cert8.db \
     key3.db \
     secmod.db \
     $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
-libs:: $(_SERV_FILES) $(_CERT_AUTHORITIES) $(_CLIENT_CERTS)
+libs:: $(_SERV_FILES) $(_CERT_AUTHORITIES)
 	$(INSTALL) $^ $(_CERTS_DIR)
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -106,18 +106,16 @@ http://sub2.test2.example.com:80     pri
 https://example.com:443                privileged
 https://test1.example.com:443          privileged
 https://test2.example.com:443          privileged
 https://sub1.test1.example.com:443     privileged
 https://sub1.test2.example.com:443     privileged
 https://sub2.test1.example.com:443     privileged
 https://sub2.test2.example.com:443     privileged
 https://nocert.example.com:443         privileged,nocert
-https://requestclientcert.example.com:443         privileged,clientauth=request
-https://requireclientcert.example.com:443         privileged,clientauth=require
 
 #
 # These are subdomains of <ält.example.org>.
 #
 http://sub1.xn--lt-uia.example.org:8000   privileged
 http://sub2.xn--lt-uia.example.org:80     privileged
 http://xn--exmple-cua.test:80             privileged
 http://sub1.xn--exmple-cua.test:80        privileged
--- a/testing/mochitest/ssltunnel/ssltunnel.cpp
+++ b/testing/mochitest/ssltunnel/ssltunnel.cpp
@@ -15,43 +15,32 @@
  * The Original Code is Mozilla test code
  *
  * The Initial Developer of the Original Code is
  * Mozilla Foundation
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Ted Mielczarek <ted.mielczarek@gmail.com>
- *   Honza Bambas <honzab@firemni.cz>
+ * Ted Mielczarek <ted.mielczarek@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-/*
- * WARNING: DO NOT USE THIS CODE IN PRODUCTION SYSTEMS.  It is highly likely to
- *          be plagued with the usual problems endemic to C (buffer overflows
- *          and the like).  We don't especially care here (but would accept
- *          patches!) because this is only intended for use in our test
- *          harnesses in controlled situations where input is guaranteed not to
- *          be malicious.
- */
-
-#include <assert.h>
 #include <stdio.h>
 #include <string>
 #include <vector>
 #include <algorithm>
 #include "prinit.h"
 #include "prerror.h"
 #include "prio.h"
 #include "prnetdb.h"
@@ -61,67 +50,29 @@
 #include "key.h"
 #include "keyt.h"
 #include "ssl.h"
 #include "plhash.h"
 
 using std::string;
 using std::vector;
 
-enum client_auth_option {
-  caNone = 0,
-  caRequire = 1,
-  caRequest = 2
-};
-
 // Structs for passing data into jobs on the thread pool
 typedef struct {
   PRInt32 listen_port;
   string cert_nickname;
   PLHashTable* host_cert_table;
-  PLHashTable* host_clientauth_table;
 } server_info_t;
 
 typedef struct {
   PRFileDesc* client_sock;
   PRNetAddr client_addr;
   server_info_t* server_info;
 } connection_info_t;
 
-const PRInt32 BUF_SIZE = 16384;
-const PRInt32 BUF_MARGIN = 1024;
-const PRInt32 BUF_TOTAL = BUF_SIZE + BUF_MARGIN;
-
-struct relayBuffer
-{
-  char *buffer, *bufferhead, *buffertail, *bufferend;
-
-  relayBuffer()
-  {
-    // Leave 1024 bytes more for request line manipulations
-    bufferhead = buffertail = buffer = new char[BUF_TOTAL];
-    bufferend = buffer + BUF_SIZE;
-  }
-
-  ~relayBuffer()
-  {
-    delete [] buffer;
-  }
-
-  void compact() {
-    if (buffertail == bufferhead)
-      buffertail = bufferhead = buffer;
-  }
-
-  bool empty() { return bufferhead == buffertail; }
-  size_t free() { return bufferend - buffertail; }
-  size_t margin() { return free() + BUF_MARGIN; }
-  size_t present() { return buffertail - bufferhead; }
-};
-
 // A couple of stack classes for managing NSS/NSPR resources
 class AutoCert {
 public:
   AutoCert(CERTCertificate* cert) { cert_ = cert; }
   ~AutoCert() { if (cert_) CERT_DestroyCertificate(cert_); }
   operator CERTCertificate*() { return cert_; }
 private:
   CERTCertificate* cert_;
@@ -155,92 +106,71 @@ private:
   PRFileDesc* fd_;
 };
 
 // These are suggestions. If the number of ports to proxy on * 2
 // is greater than either of these, then we'll use that value instead.
 const PRInt32 INITIAL_THREADS = 1;
 const PRInt32 MAX_THREADS = 5;
 const PRInt32 DEFAULT_STACKSIZE = (512 * 1024);
+const PRInt32 BUF_SIZE = 4096;
 
 // global data
 string nssconfigdir;
 vector<server_info_t> servers;
 PRNetAddr remote_addr;
 PRThreadPool* threads = NULL;
 PRLock* shutdown_lock = NULL;
 PRCondVar* shutdown_condvar = NULL;
 // Not really used, unless something fails to start
 bool shutdown_server = false;
 bool do_http_proxy = false;
-bool any_host_spec_config = false;
-
-PR_CALLBACK PRIntn ClientAuthValueComparator(const void *v1, const void *v2)
-{
-  int a = *static_cast<const client_auth_option*>(v1) -
-          *static_cast<const client_auth_option*>(v2);
-  if (a == 0)
-    return 0;
-  if (a > 0)
-    return 1;
-  else // (a < 0)
-    return -1;
-}
+bool any_host_cert_mapping = false;
 
 /*
  * Signal the main thread that the application should shut down.
  */
 void SignalShutdown()
 {
   PR_Lock(shutdown_lock);
   PR_NotifyCondVar(shutdown_condvar);
   PR_Unlock(shutdown_lock);
 }
 
 bool ReadConnectRequest(server_info_t* server_info, 
-    relayBuffer& buffer, PRInt32* result, string& certificate,
-    client_auth_option* clientauth, string& host)
+    char* bufferhead, char* buffertail, PRInt32* result, string* certificate)
 {
-  if (buffer.present() < 4)
+  if (buffertail - bufferhead < 4)
     return false;
-  if (strncmp(buffer.buffertail-4, "\r\n\r\n", 4))
+  if (strncmp(buffertail-4, "\r\n\r\n", 4))
     return false;
 
   *result = 400;
 
   char* token;
-  token = strtok(buffer.bufferhead, " ");
+  token = strtok(bufferhead, " ");
   if (!token) 
     return true;
   if (strcmp(token, "CONNECT")) 
     return true;
 
   token = strtok(NULL, " ");
   void* c = PL_HashTableLookup(server_info->host_cert_table, token);
   if (c)
-    certificate = static_cast<char*>(c);
-
-  host = "https://";
-  host += token;
-
-  c = PL_HashTableLookup(server_info->host_clientauth_table, token);
-  if (c)
-    *clientauth = *static_cast<client_auth_option*>(c);
-  else
-    *clientauth = caNone;
+    *certificate = (char*)c;
 
   token = strtok(NULL, "/");
   if (strcmp(token, "HTTP"))
     return true;
 
   *result = 200;
   return true;
 }
 
-bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, string &certificate, client_auth_option clientAuth)
+bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, string &certificate)
 {
   const char* certnick = certificate.empty() ?
       si->cert_nickname.c_str() : certificate.c_str();
 
   AutoCert cert(PK11_FindCertFromNickname(
       certnick, NULL));
   if (!cert) {
     fprintf(stderr, "Failed to find cert %s\n", si->cert_nickname.c_str());
@@ -264,67 +194,21 @@ bool ConfigureSSLServerSocket(PRFileDesc
       != SECSuccess) {
     fprintf(stderr, "Error configuring SSL server socket\n");
     return false;
   }
 
   SSL_OptionSet(ssl_socket, SSL_SECURITY, PR_TRUE);
   SSL_OptionSet(ssl_socket, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE);
   SSL_OptionSet(ssl_socket, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
-
-  if (clientAuth != caNone)
-  {
-    SSL_OptionSet(ssl_socket, SSL_REQUEST_CERTIFICATE, PR_TRUE);
-    SSL_OptionSet(ssl_socket, SSL_REQUIRE_CERTIFICATE, clientAuth == caRequire);
-  }
-
   SSL_ResetHandshake(ssl_socket, PR_TRUE);
 
   return true;
 }
 
-/**
- * This function prefixes Request-URI path with a full scheme-host-port
- * string.
- */
-bool AdjustRequestURI(relayBuffer& buffer, string *host)
-{
-  assert(buffer.margin());
-
-  // Cannot use strnchr so add a null char at the end. There is always some space left
-  // because we preserve a margin.
-  buffer.buffertail[1] = '\0';
-
-  char *token, *path;
-  path = strchr(buffer.bufferhead, ' ') + 1;
-  if (!path)
-    return false;
-
-  // If the path doesn't start with a slash don't change it, it is probably '*' or a full
-  // path already. Return true, we are done with this request adjustment.
-  if (*path != '/')
-    return true;
-
-  token = strchr(path, ' ') + 1;
-  if (!token)
-    return false;
-
-  if (strncmp(token, "HTTP/", 5))
-    return false;
-
-  size_t hostlength = host->length();
-  assert(hostlength <= buffer.margin());
-
-  memmove(path + hostlength, path, buffer.buffertail - path);
-  memcpy(path, host->c_str(), hostlength);
-  buffer.buffertail += hostlength;
-
-  return true;
-}
-
 bool ConnectSocket(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
 {
   PRStatus stat = PR_Connect(fd, addr, timeout);
   if (stat != PR_SUCCESS)
     return false;
 
   PRSocketOptionData option;
   option.option = PR_SockOpt_Nonblocking;
@@ -346,30 +230,57 @@ void HandleConnection(void* data)
   connection_info_t* ci = static_cast<connection_info_t*>(data);
   PRIntervalTime connect_timeout = PR_SecondsToInterval(2);
 
   AutoFD other_sock(PR_NewTCPSocket());
   bool client_done = false;
   bool client_error = false;
   bool connect_accepted = !do_http_proxy;
   bool ssl_updated = !do_http_proxy;
-  bool expect_request_start = do_http_proxy;
   string certificateToUse;
-  client_auth_option clientAuth;
-  string fullHost;
 
   if (other_sock) 
   {
     PRInt32 numberOfSockets = 1;
 
-    relayBuffer buffers[2];
+    struct relayBuffer
+    {
+      char *buffer, *bufferhead, *buffertail, *bufferend;
+      relayBuffer() 
+      { 
+        bufferhead = buffertail = buffer = new char[BUF_SIZE]; 
+        bufferend = buffer + BUF_SIZE; 
+      }
+      ~relayBuffer() 
+      { 
+        delete [] buffer; 
+      }
+
+      bool empty() 
+      { 
+        return bufferhead == buffertail; 
+      }
+      PRInt32 free() 
+      { 
+        return bufferend - buffertail; 
+      }
+      PRInt32 present() 
+      { 
+        return buffertail - bufferhead; 
+      }
+      void compact() 
+      { 
+        if (buffertail == bufferhead) 
+          buffertail = bufferhead = buffer;
+      }
+    } buffers[2];
 
     if (!do_http_proxy)
     {
-      if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse, caNone))
+      if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse))
         client_error = true;
       else if (!ConnectSocket(other_sock, &remote_addr, connect_timeout))
         client_error = true;
       else
         numberOfSockets = 2;
     }
 
     PRPollDesc sockets[2] = 
@@ -423,18 +334,18 @@ void HandleConnection(void* data)
               client_error = true;
           }
           else
           {
             buffers[s].buffertail += bytesRead;
 
             // We have to accept and handle the initial CONNECT request here
             PRInt32 response;
-            if (!connect_accepted && ReadConnectRequest(ci->server_info, buffers[s],
-                &response, certificateToUse, &clientAuth, fullHost))
+            if (!connect_accepted && ReadConnectRequest(ci->server_info, buffers[s].bufferhead, buffers[s].buffertail, 
+                &response, &certificateToUse))
             {
               // Clean the request as it would be read
               buffers[s].bufferhead = buffers[s].buffertail = buffers[s].buffer;
 
               // Store response to the oposite buffer
               if (response != 200)
               {
                 client_done = true;
@@ -457,22 +368,17 @@ void HandleConnection(void* data)
               connect_accepted = true;
               break;
             } // end of CONNECT handling
 
             if (!buffers[s].free()) // Do not poll for read when the buffer is full
               in_flags &= ~PR_POLL_READ;
 
             if (ssl_updated)
-            {
-              if (s == 0 && expect_request_start)
-                expect_request_start = !AdjustRequestURI(buffers[s], &fullHost);
-
               in_flags2 |= PR_POLL_WRITE;
-            }
           }
         } // PR_POLL_READ handling
 
         if (out_flags & PR_POLL_WRITE)
         {
           PRInt32 bytesWrite = PR_Send(sockets[s].fd, buffers[s2].bufferhead, 
               buffers[s2].present(), 0, PR_INTERVAL_NO_TIMEOUT);
 
@@ -487,17 +393,17 @@ void HandleConnection(void* data)
             if (buffers[s2].present())
               in_flags |= PR_POLL_WRITE;              
             else
             {
               if (!ssl_updated)
               {
                 // Proxy response has just been writen, update to ssl
                 ssl_updated = true;
-                if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse, clientAuth))
+                if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse))
                 {
                   client_error = true;
                   break;
                 }
 
                 numberOfSockets = 2;
               } // sslUpdate
 
@@ -617,146 +523,76 @@ int processConfigLine(char* configLine)
   // Configure the forward address of the target server
   if (!strcmp(keyword, "forward"))
   {
     char* ipstring = strtok(NULL, ":");
     if (PR_StringToNetAddr(ipstring, &remote_addr) != PR_SUCCESS) {
       fprintf(stderr, "Invalid remote IP address: %s\n", ipstring);
       return 1;
     }
-    char* serverportstring = strtok(NULL, ":");
-    int port = atoi(serverportstring);
+    char* portstring = strtok(NULL, ":");
+    int port = atoi(portstring);
     if (port <= 0) {
-      fprintf(stderr, "Invalid remote port: %s\n", serverportstring);
+      fprintf(stderr, "Invalid remote port: %s\n", portstring);
       return 1;
     }
     remote_addr.inet.port = PR_htons(port);
 
     return 0;
   }
 
   // Configure all listen sockets and port+certificate bindings
   if (!strcmp(keyword, "listen"))
   {
     char* hostname = strtok(NULL, ":");
     char* hostportstring = NULL;
     if (strcmp(hostname, "*"))
     {
-      any_host_spec_config = true;
+      any_host_cert_mapping = true;
       hostportstring = strtok(NULL, ":");
     }
 
-    char* serverportstring = strtok(NULL, ":");
+    char* portstring = strtok(NULL, ":");
     char* certnick = strtok(NULL, ":");
 
-    int port = atoi(serverportstring);
+    int port = atoi(portstring);
     if (port <= 0) {
-      fprintf(stderr, "Invalid port specified: %s\n", serverportstring);
+      fprintf(stderr, "Invalid port specified: %s\n", portstring);
       return 1;
     }
 
     if (server_info_t* existingServer = findServerInfo(port))
     {
       char *certnick_copy = new char[strlen(certnick)+1];
       char *hostname_copy = new char[strlen(hostname)+strlen(hostportstring)+2];
 
       strcpy(hostname_copy, hostname);
       strcat(hostname_copy, ":");
       strcat(hostname_copy, hostportstring);
       strcpy(certnick_copy, certnick);
 
-      PLHashEntry* entry = PL_HashTableAdd(existingServer->host_cert_table, hostname_copy, certnick_copy);
-      if (!entry) {
-        fprintf(stderr, "Out of memory");
-        return 1;
-      }
+      PL_HashTableAdd(existingServer->host_cert_table, hostname_copy, certnick_copy);
     }
     else
     {
       server_info_t server;
       server.cert_nickname = certnick;
       server.listen_port = port;
       server.host_cert_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareStrings, NULL, NULL);
       if (!server.host_cert_table)
       {
         fprintf(stderr, "Internal, could not create hash table\n");
         return 1;
       }
-      server.host_clientauth_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, ClientAuthValueComparator, NULL, NULL);
-      if (!server.host_clientauth_table)
-      {
-        fprintf(stderr, "Internal, could not create hash table\n");
-        return 1;
-      }
       servers.push_back(server);
     }
 
     return 0;
   }
   
-  if (!strcmp(keyword, "clientauth"))
-  {
-    char* hostname = strtok(NULL, ":");
-    char* hostportstring = strtok(NULL, ":");
-    char* serverportstring = strtok(NULL, ":");
-
-    int port = atoi(serverportstring);
-    if (port <= 0) {
-      fprintf(stderr, "Invalid port specified: %s\n", serverportstring);
-      return 1;
-    }
-
-    if (server_info_t* existingServer = findServerInfo(port))
-    {
-      char* authoptionstring = strtok(NULL, ":");
-      client_auth_option* authoption = new client_auth_option;
-      if (!authoption) {
-        fprintf(stderr, "Out of memory");
-        return 1;
-      }
-
-      if (!strcmp(authoptionstring, "require"))
-        *authoption = caRequire;
-      else if (!strcmp(authoptionstring, "request"))
-        *authoption = caRequest;
-      else if (!strcmp(authoptionstring, "none"))
-        *authoption = caNone;
-      else
-      {
-        fprintf(stderr, "Incorrect client auth option modifier for host '%s'", hostname);
-        return 1;
-      }
-
-      any_host_spec_config = true;
-
-      char *hostname_copy = new char[strlen(hostname)+strlen(hostportstring)+2];
-      if (!hostname_copy) {
-        fprintf(stderr, "Out of memory");
-        return 1;
-      }
-
-      strcpy(hostname_copy, hostname);
-      strcat(hostname_copy, ":");
-      strcat(hostname_copy, hostportstring);
-
-      PLHashEntry* entry = PL_HashTableAdd(existingServer->host_clientauth_table, hostname_copy, authoption);
-      if (!entry) {
-        fprintf(stderr, "Out of memory");
-        return 1;
-      }
-    }
-    else
-    {
-      fprintf(stderr, "Server on port %d for client authentication option is not defined, use 'listen' option first", port);
-      return 1;
-    }
-
-    return 0;
-  }
-
   // Configure the NSS certificate database directory
   if (!strcmp(keyword, "certdbdir"))
   {
     nssconfigdir = strtok(NULL, "\n");
     return 0;
   }
 
   printf("Error: keyword \"%s\" unexpected\n", keyword);
@@ -792,38 +628,31 @@ int parseConfigFile(const char* filePath
 
   // Check mandatory items
   if (nssconfigdir.empty())
   {
     printf("Error: missing path to NSS certification database\n,use certdbdir:<path> in the config file\n");
     return 1;
   }
 
-  if (any_host_spec_config && !do_http_proxy)
+  if (any_host_cert_mapping && !do_http_proxy)
   {
-    printf("Warning: any host-specific configurations are ignored, add httpproxy:1 to allow them\n");
+    printf("Warning: any host-specific certificate configurations are ignored, add httpproxy:1 to allow them\n");
   }
 
   return 0;
 }
 
-PRIntn freeHostCertHashItems(PLHashEntry *he, PRIntn i, void *arg)
+PRIntn freeHashItems(PLHashEntry *he, PRIntn i, void *arg)
 {
   delete [] (char*)he->key;
   delete [] (char*)he->value;
   return HT_ENUMERATE_REMOVE;
 }
 
-PRIntn freeClientAuthHashItems(PLHashEntry *he, PRIntn i, void *arg)
-{
-  delete [] (char*)he->key;
-  delete (client_auth_option*)he->value;
-  return HT_ENUMERATE_REMOVE;
-}
-
 int main(int argc, char** argv)
 {
   char* configFilePath;
   if (argc == 1)
     configFilePath = "ssltunnel.cfg";
   else
     configFilePath = argv[1];
 
@@ -840,25 +669,19 @@ int main(int argc, char** argv)
       "       # Forward/proxy all requests in raw to 127.0.0.1:8888.\n"
       "       forward:127.0.0.1:8888\n\n"
       "       # Accept connections on port 4443 or 5678 resp. and authenticate\n"
       "       # to any host ('*') using the 'server cert' or 'server cert 2' resp.\n"
       "       listen:*:4443:server cert\n"
       "       listen:*:5678:server cert 2\n\n"
       "       # Accept connections on port 4443 and authenticate using\n"
       "       # 'a different cert' when target host is 'my.host.name:443'.\n"
-      "       # This only works in httpproxy mode and has higher priority\n"
-      "       # than the previous option.\n"
-      "       listen:my.host.name:443:4443:a different cert\n\n"
-      "       # To make a specific host require or just request a client certificate\n"
-      "       # to authenticate use following options. This can only be used\n"
-      "       # in httpproxy mode and after the 'listen' option has been specified.\n"
-      "       # You also have to specify the tunnel listen port.\n"
-      "       clientauth:requesting-client-cert.host.com:443:4443:request\n"
-      "       clientauth:requiring-client-cert.host.com:443:4443:require\n",
+      "       # This works only in httpproxy mode and has higher priority\n"
+      "       # then the previews option.\n"
+      "       listen:my.host.name:443:4443:a different cert\n",
       configFilePath);
     return 1;
   }
 
   // create a thread pool to handle connections
   threads = PR_CreateThreadPool(std::max<PRInt32>(INITIAL_THREADS,
                                                   servers.size()*2),
                                 std::max<PRInt32>(MAX_THREADS,
@@ -936,17 +759,15 @@ int main(int argc, char** argv)
   PR_DestroyLock(shutdown_lock);
   if (NSS_Shutdown() == SECFailure) {
     fprintf(stderr, "Leaked NSS objects!\n");
   }
   
   for (vector<server_info_t>::iterator it = servers.begin();
        it != servers.end(); it++) 
   {
-    PL_HashTableEnumerateEntries(it->host_cert_table, freeHostCertHashItems, NULL);
-    PL_HashTableEnumerateEntries(it->host_clientauth_table, freeClientAuthHashItems, NULL);
+    PL_HashTableEnumerateEntries(it->host_cert_table, freeHashItems, NULL);
     PL_HashTableDestroy(it->host_cert_table);
-    PL_HashTableDestroy(it->host_clientauth_table);
   }
 
   PR_Cleanup();
   return 0;
 }