You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2018/09/06 14:45:32 UTC

[trafficserver] branch master updated: Remove ssl_cert_loader. Certifier is more complete version.

This is an automated email from the ASF dual-hosted git repository.

amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 9795337  Remove ssl_cert_loader.  Certifier is more complete version.
9795337 is described below

commit 9795337070795088468faa317f955a645b697211
Author: Susan Hinrichs <sh...@apache.org>
AuthorDate: Tue Sep 4 11:16:43 2018 -0500

    Remove ssl_cert_loader.  Certifier is more complete version.
---
 plugins/Makefile.am                                |   1 -
 plugins/experimental/ssl_cert_loader/Makefile.inc  |  23 -
 .../experimental/ssl_cert_loader/domain-tree.cc    | 200 --------
 plugins/experimental/ssl_cert_loader/domain-tree.h |  98 ----
 .../ssl_cert_loader/ssl-cert-loader.cc             | 555 ---------------------
 .../ssl_cert_loader/ssl_cert_loader.cfg            | 150 ------
 plugins/experimental/ssl_cert_loader/ssl_start.cfg |  72 ---
 7 files changed, 1099 deletions(-)

diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 6115b21..8fa846e 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -75,7 +75,6 @@ include experimental/mp4/Makefile.inc
 include experimental/multiplexer/Makefile.inc
 include experimental/remap_purge/Makefile.inc
 include experimental/server_push_preload/Makefile.inc
-include experimental/ssl_cert_loader/Makefile.inc
 include experimental/sslheaders/Makefile.inc
 include experimental/stale_while_revalidate/Makefile.inc
 include experimental/stream_editor/Makefile.inc
diff --git a/plugins/experimental/ssl_cert_loader/Makefile.inc b/plugins/experimental/ssl_cert_loader/Makefile.inc
deleted file mode 100644
index 194b011..0000000
--- a/plugins/experimental/ssl_cert_loader/Makefile.inc
+++ /dev/null
@@ -1,23 +0,0 @@
-#  Licensed to the Apache Software Foundation (ASF) under one
-#  or more contributor license agreements.  See the NOTICE file
-#  distributed with this work for additional information
-#  regarding copyright ownership.  The ASF licenses this file
-#  to you under the Apache License, Version 2.0 (the
-#  "License"); you may not use this file except in compliance
-#  with the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-pkglib_LTLIBRARIES += experimental/ssl_cert_loader/ssl_cert_loader.la
-
-experimental_ssl_cert_loader_ssl_cert_loader_la_SOURCES = \
-  experimental/ssl_cert_loader/ssl-cert-loader.cc \
-  experimental/ssl_cert_loader/domain-tree.cc
-
-experimental_ssl_cert_loader_ssl_cert_loader_la_LIBADD = $(top_builddir)/lib/tsconfig/libtsconfig.la
diff --git a/plugins/experimental/ssl_cert_loader/domain-tree.cc b/plugins/experimental/ssl_cert_loader/domain-tree.cc
deleted file mode 100644
index b642ed7..0000000
--- a/plugins/experimental/ssl_cert_loader/domain-tree.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-/** @file
-    SSL dynamic certificate loader
-    Loads certificates into a hash table as they are requested
-
-    @section license License
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-*/
-#include <cstdio>
-#include <memory.h>
-#include <cinttypes>
-#include "domain-tree.h"
-
-// return true if comparable.  Return type of compare in relative parameter
-// 0 if eq.  < 0 if node key is broader.  > 0 if parameter key is broader
-bool
-DomainNameTree::DomainNameNode::compare(std::string key, int &relative)
-{
-  size_t star_loc = key.find('*');
-  bool is_wild    = false;
-
-  if (star_loc != std::string::npos) {
-    star_loc++;
-    is_wild = true;
-    key     = key.substr(star_loc);
-  }
-
-  return this->prunedCompare(key, relative, is_wild);
-}
-
-bool
-DomainNameTree::DomainNameNode::prunedCompare(const std::string &key, int &relative, bool is_wild)
-{
-  if (key == this->key) {
-    relative = 0;
-    return true;
-  } else {
-    if (this->is_wild) {
-      size_t loc = key.find(this->key);
-
-      if (this->key == "") { // Match all
-        relative = -1;
-        return true;
-      } else if (loc != std::string::npos) {
-        // node key is in search key
-        if ((key.length() - this->key.length()) == loc) {
-          // And node key is at the end of search key
-          relative = -1;
-          return true;
-        }
-      }
-    }
-    if (is_wild) {
-      if (key == "") { // Match all
-        relative = 1;
-        return true;
-      } else {
-        size_t loc = this->key.find(key);
-
-        if (loc != std::string::npos) {
-          if ((this->key.length() - key.length()) == loc) {
-            relative = 1;
-            return true;
-          }
-        }
-      }
-    }
-  }
-
-  return false;
-}
-
-DomainNameTree::DomainNameNode *
-DomainNameTree::find(std::string key, bool best_match)
-{
-  DomainNameNode *retval = nullptr;
-  DomainNameNode *first  = nullptr;
-  size_t star_loc        = key.find('*');
-  bool is_wild           = false;
-
-  if (star_loc != std::string::npos) {
-    key     = key.substr(star_loc + 1);
-    is_wild = true;
-  }
-
-  bool set_iter                = false;
-  DomainNameNode *current_node = root;
-  std::deque<DomainNameNode *>::iterator sibPtr, endPtr;
-
-  while (current_node != nullptr) {
-    bool partial_match = false;
-    int relative;
-
-    if (current_node->prunedCompare(key, relative, is_wild)) {
-      if (relative == 0) {
-        retval = current_node;
-        if (nullptr == first || retval->order < first->order) {
-          first = retval;
-        }
-        current_node = nullptr;
-        break;
-      } else if (relative < 0) {
-        retval        = current_node;
-        partial_match = true;
-        if (nullptr == first || retval->order < first->order) {
-          first = retval;
-        }
-      }
-    }
-    if (partial_match) {
-      // Check out the children, maybe there is something better there
-      sibPtr   = current_node->children.begin();
-      endPtr   = current_node->children.end();
-      set_iter = true;
-      if (sibPtr == endPtr) {
-        break; // We are done
-      }
-      current_node = *(sibPtr++);
-    } else { // No match here.  Look at next sibling?
-      // Is there another sibling to look at?
-      if (set_iter && sibPtr != endPtr) {
-        current_node = *(sibPtr++);
-      } else { // No more siblings to check, give it up.
-        break;
-      }
-    }
-  }
-
-  return best_match ? retval : first;
-}
-
-DomainNameTree::DomainNameNode *
-DomainNameTree::insert(std::string key, void *payload, int order)
-{
-  TSMutexLock(this->tree_mutex);
-  DomainNameNode *retval = nullptr;
-  DomainNameNode *node   = this->findBestMatch(key);
-  int relative;
-
-  if (node->compare(key, relative)) {
-    size_t star_loc = key.find('*');
-    bool is_wild    = false;
-
-    if (star_loc != std::string::npos) {
-      star_loc++;
-      key     = key.substr(star_loc);
-      is_wild = true;
-    }
-    if (relative < 0) {
-      // Make a new node that is a child of node
-      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);
-
-      new_node->parent = node;
-      node->children.push_back(new_node);
-      retval = new_node;
-    } else if (relative > 0) {
-      // Insert new node as parent of node
-      DomainNameNode *new_node = new DomainNameNode(key, payload, order, is_wild);
-
-      new_node->parent = node->parent;
-      new_node->children.push_back(node);
-      node->parent = new_node;
-
-      // Replace the node with new_node in the child list of the parent;
-      for (std::deque<DomainNameNode *>::iterator iter = new_node->parent->children.begin();
-           iter != new_node->parent->children.end(); ++iter) {
-        if (*(iter) == node) {
-          *(iter) = new_node;
-        }
-      }
-      retval = new_node;
-    } else {
-      // Will not replace in the equal case
-      // Unless this is the root node
-      if (node->key == "" && node->order == 0x7fffffff) {
-        node->key     = key;
-        node->payload = payload;
-        node->order   = order;
-        retval        = node;
-      }
-    }
-  }
-  TSMutexUnlock(this->tree_mutex);
-
-  return retval;
-}
diff --git a/plugins/experimental/ssl_cert_loader/domain-tree.h b/plugins/experimental/ssl_cert_loader/domain-tree.h
deleted file mode 100644
index 4bbde85..0000000
--- a/plugins/experimental/ssl_cert_loader/domain-tree.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/** @file
-
-    Include file for  ...
-
-    @section license License
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-*/
-#include <string>
-#include <deque>
-#include <ts/ts.h>
-
-class DomainNameTree
-{
-public:
-  class DomainNameNode
-  {
-  public:
-    DomainNameNode() : order(-1), payload(nullptr), parent(nullptr), is_wild(false) {}
-    DomainNameNode(std::string key, void *payload, int order, bool is_wild)
-      : key(key), order(order), payload(payload), parent(nullptr), is_wild(is_wild)
-    {
-    }
-
-    DomainNameNode *match(std::string value);
-
-    ~DomainNameNode()
-    {
-      std::deque<DomainNameNode *>::iterator iter = children.begin();
-
-      for (; iter != children.end(); iter++) {
-        delete *iter;
-      }
-    }
-
-    // return true if comparable.  Return type of compare in relative parameter
-    // 0 if eq.  < 0 if node key is broader.  > 0 if parameter key is broader
-    bool compare(std::string key, int &relative);
-    // The wildcard is pruned out of the key
-    bool prunedCompare(const std::string &key, int &relative, bool is_wild);
-    std::string key; // The string trailing the * (if any)
-    int order;       // Track insert order for conflict resolution
-    void *payload;
-    std::deque<DomainNameNode *> children;
-    DomainNameNode *parent;
-    bool is_wild;
-  };
-
-  DomainNameTree()
-  {
-    root          = new DomainNameNode();
-    root->key     = "";
-    root->order   = 0x7FFFFFFF;
-    root->is_wild = true;
-    tree_mutex    = TSMutexCreate();
-  }
-
-  ~DomainNameTree() { delete root; }
-  DomainNameNode *
-  findBestMatch(std::string key)
-  {
-    TSMutexLock(this->tree_mutex);
-    DomainNameNode *retval = this->find(key, true);
-    TSMutexUnlock(this->tree_mutex);
-    return retval;
-  }
-
-  DomainNameNode *
-  findFirstMatch(std::string key)
-  {
-    TSMutexLock(this->tree_mutex);
-    DomainNameNode *retval = this->find(key, false);
-    TSMutexUnlock(this->tree_mutex);
-    return retval;
-  }
-
-  DomainNameNode *find(std::string key, bool best_match);
-  DomainNameNode *insert(std::string key, void *payload, int order);
-
-private:
-  DomainNameNode *root;
-  TSMutex tree_mutex;
-};
diff --git a/plugins/experimental/ssl_cert_loader/ssl-cert-loader.cc b/plugins/experimental/ssl_cert_loader/ssl-cert-loader.cc
deleted file mode 100644
index ef89cfa..0000000
--- a/plugins/experimental/ssl_cert_loader/ssl-cert-loader.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-/** @file
-
-    SSL dynamic certificate loader
-    Loads certificates into a hash table as they are requested
-
-    @section license License
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-*/
-
-#include <cstdio>
-#include <memory.h>
-#include <cinttypes>
-#include <ts/ts.h>
-#include <tsconfig/TsValue.h>
-#include <openssl/ssl.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <getopt.h>
-#include "domain-tree.h"
-
-#include "ts/ink_inet.h"
-#include "ts/ink_config.h"
-#include "ts/IpMap.h"
-
-using ts::config::Configuration;
-using ts::config::Value;
-
-#define PN "ssl-cert-loader"
-#define PCP "[" PN " Plugin] "
-
-namespace
-{
-class CertLookup
-{
-public:
-  DomainNameTree tree;
-  IpMap ipmap;
-} Lookup;
-
-typedef enum {
-  SSL_HOOK_OP_DEFAULT,                     ///< Null / initialization value. Do normal processing.
-  SSL_HOOK_OP_TUNNEL,                      ///< Switch to blind tunnel
-  SSL_HOOK_OP_TERMINATE,                   ///< Termination connection / transaction.
-  SSL_HOOK_OP_LAST = SSL_HOOK_OP_TERMINATE ///< End marker value.
-} SslVConnOp;
-
-class SslEntry
-{
-public:
-  SslEntry() : ctx(nullptr), op(SSL_HOOK_OP_DEFAULT) { this->mutex = TSMutexCreate(); }
-  ~SslEntry() {}
-  SSL_CTX *ctx;
-  SslVConnOp op;
-  // If the CTX is not already created, use these
-  // files to load things up
-  std::string certFileName;
-  std::string keyFileName;
-  TSMutex mutex;
-  std::deque<TSVConn> waitingVConns;
-};
-
-std::string ConfigPath;
-typedef std::pair<IpAddr, IpAddr> IpRange;
-using IpRangeQueue = std::deque<IpRange>;
-
-Configuration Config; // global configuration
-
-void
-Parse_Addr_String(std::string_view const &text, IpRange &range)
-{
-  IpAddr newAddr;
-  // Is there a hyphen?
-  size_t hyphen_pos = text.find('-');
-
-  if (hyphen_pos != std::string_view::npos) {
-    std::string_view addr1 = text.substr(0, hyphen_pos);
-    std::string_view addr2 = text.substr(hyphen_pos + 1);
-    range.first.load(addr1);
-    range.second.load(addr2);
-  } else { // Assume it is a single address
-    newAddr.load(text);
-    range.first  = newAddr;
-    range.second = newAddr;
-  }
-}
-
-int
-Load_Config_File()
-{
-  ts::Rv<Configuration> cv = Configuration::loadFromPath(ConfigPath.c_str());
-
-  if (!cv.isOK()) {
-    char error_buffer[1024];
-
-    cv._errata.write(error_buffer, sizeof(error_buffer), 0, 0, 0, "");
-    TSDebug(PN, "Failed to parse %s as TSConfig format", ConfigPath.c_str());
-    TSError(PCP "Failed to parse %s as TSConfig format", ConfigPath.c_str());
-    TSDebug(PN, "Errors: %s", error_buffer);
-    return -1;
-  }
-  Config = cv;
-
-  return 1;
-}
-
-struct ParsedSslValues {
-  std::string server_priv_key_file;
-  std::string server_name;
-  std::string server_cert_name;
-  std::string action;
-  IpRangeQueue server_ips;
-};
-
-void Parse_Config_Rules(Value &parent, ParsedSslValues &orig_values);
-
-int
-Load_Configuration()
-{
-  int ret = Load_Config_File();
-
-  if (ret != 0) {
-    TSError(PCP "Failed to load the config file, check debug output for errata");
-  }
-
-  Value root = Config.getRoot();
-  Value val  = root["runtime-table-size"];
-  if (val.isLiteral()) {
-    // Not evicting yet
-  }
-  val = root["ssl-server-match"];
-  if (val.isContainer()) {
-    ParsedSslValues values;
-    Parse_Config_Rules(val, values);
-  }
-
-  return 0;
-}
-
-SSL_CTX *
-Load_Certificate(SslEntry const *entry, std::deque<std::string> &names)
-{
-  SSL_CTX *retval = SSL_CTX_new(SSLv23_client_method());
-  X509 *cert      = nullptr;
-
-  if (entry->certFileName.length() > 0) {
-    // Must load the cert file to fetch the names out later
-    BIO *cert_bio = BIO_new_file(entry->certFileName.c_str(), "r");
-    cert          = PEM_read_bio_X509_AUX(cert_bio, nullptr, nullptr, nullptr);
-    BIO_free(cert_bio);
-
-    if (SSL_CTX_use_certificate(retval, cert) < 1) {
-      TSDebug(PN, "Failed to load cert file %s", entry->certFileName.c_str());
-      SSL_CTX_free(retval);
-      return nullptr;
-    }
-  }
-  if (entry->keyFileName.length() > 0) {
-    if (!SSL_CTX_use_PrivateKey_file(retval, entry->keyFileName.c_str(), SSL_FILETYPE_PEM)) {
-      TSDebug(PN, "Failed to load priv key file %s", entry->keyFileName.c_str());
-      SSL_CTX_free(retval);
-      return nullptr;
-    }
-  }
-
-  // Fetch out the names associated with the certificate
-  if (cert != nullptr) {
-    X509_NAME *name = X509_get_subject_name(cert);
-    char subjectCn[256];
-
-    if (X509_NAME_get_text_by_NID(name, NID_commonName, subjectCn, sizeof(subjectCn)) >= 0) {
-      std::string tmp_name(subjectCn);
-      names.push_back(tmp_name);
-    }
-    // Look for alt names
-    GENERAL_NAMES *alt_names = (GENERAL_NAMES *)X509_get_ext_d2i(cert, NID_subject_alt_name, nullptr, nullptr);
-    if (alt_names) {
-      unsigned count = sk_GENERAL_NAME_num(alt_names);
-      for (unsigned i = 0; i < count; i++) {
-        GENERAL_NAME *alt_name = sk_GENERAL_NAME_value(alt_names, i);
-
-        if (alt_name->type == GEN_DNS) {
-          // Current name is a DNS name, let's check it
-          char *name_ptr = (char *)ASN1_STRING_get0_data(alt_name->d.dNSName);
-          std::string tmp_name(name_ptr);
-          names.push_back(tmp_name);
-        }
-      }
-      sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
-    }
-  }
-
-  // Do we need to free cert? Did assigning to SSL_CTX increment its ref count
-  return retval;
-}
-
-/*
- * Load the config information about the terminal config.
- * Only load the certificate if no server name or ip is specified
- */
-SslEntry *
-Load_Certificate_Entry(ParsedSslValues const &values, std::deque<std::string> &names)
-{
-  SslEntry *retval = nullptr;
-  std::string cert_file_path;
-  std::string priv_file_path;
-
-  retval = new SslEntry();
-  if (values.server_cert_name.length() > 0) {
-    if (values.server_cert_name[0] != '/') {
-      cert_file_path = std::string(TSConfigDirGet()) + '/' + values.server_cert_name;
-    } else {
-      cert_file_path = values.server_cert_name;
-    }
-    retval->certFileName = cert_file_path;
-  }
-  if (values.server_priv_key_file.length() > 0) {
-    if (values.server_priv_key_file[0] != '/') {
-      priv_file_path = std::string(TSConfigDirGet()) + '/' + values.server_priv_key_file;
-    } else {
-      priv_file_path = values.server_priv_key_file;
-    }
-    retval->keyFileName = priv_file_path;
-  }
-  // Must go ahead and load the cert to get the names
-  if (values.server_name.length() == 0 && values.server_ips.size() == 0) {
-    retval->ctx = Load_Certificate(retval, names);
-  }
-  if (values.action.length() > 0) {
-    if (values.action == "tunnel") {
-      retval->op = SSL_HOOK_OP_TUNNEL;
-    } else if (values.action == "teriminate") {
-      retval->op = SSL_HOOK_OP_TERMINATE;
-    }
-  }
-
-  return retval;
-}
-
-int Parse_order = 0;
-
-void
-Parse_Config(Value &parent, ParsedSslValues &orig_values)
-{
-  ParsedSslValues cur_values(orig_values);
-  Value val = parent.find("ssl-key-name");
-
-  if (val.hasValue()) {
-    cur_values.server_priv_key_file = std::string(val.getText()._ptr, val.getText()._size);
-  }
-  val = parent.find("server-ip");
-  if (val) {
-    IpRange ipRange;
-    auto txt = val.getText();
-
-    Parse_Addr_String(std::string_view(txt._ptr, txt._size), ipRange);
-    cur_values.server_ips.push_back(ipRange);
-  }
-  val = parent.find("server-name");
-  if (val) {
-    cur_values.server_name = std::string(val.getText()._ptr, val.getText()._size);
-  }
-  val = parent.find("server-cert-name");
-  if (val) {
-    cur_values.server_cert_name = std::string(val.getText()._ptr, val.getText()._size);
-  }
-  val = parent.find("action");
-  if (val) {
-    cur_values.action = std::string(val.getText()._ptr, val.getText()._size);
-  }
-
-  val = parent.find("child-match");
-  if (val) {
-    Parse_Config_Rules(val, cur_values);
-  } else { // We are terminal, enter a match case
-    TSDebug(PN, "Terminal SSL Config: server_priv_key_file=%s server_name=%s server_cert_name=%s action=%s",
-            cur_values.server_priv_key_file.c_str(), cur_values.server_name.c_str(), cur_values.server_cert_name.c_str(),
-            cur_values.action.c_str());
-    // Load the certificate and create a context if appropriate
-    std::deque<std::string> cert_names;
-    SslEntry *entry = Load_Certificate_Entry(cur_values, cert_names);
-
-    if (entry) {
-      bool inserted = false;
-
-      // Store in appropriate table
-      if (cur_values.server_name.length() > 0) {
-        Lookup.tree.insert(cur_values.server_name, entry, Parse_order++);
-        inserted = true;
-      }
-      if (cur_values.server_ips.size() > 0) {
-        for (auto &server_ip : cur_values.server_ips) {
-          IpEndpoint first, second;
-          first.assign(server_ip.first);
-          second.assign(server_ip.second);
-          Lookup.ipmap.fill(&first, &second, entry);
-          char val1[256], val2[256];
-          server_ip.first.toString(val1, sizeof(val1));
-          server_ip.second.toString(val2, sizeof(val2));
-          inserted = true;
-        }
-      }
-
-      if (cert_names.size() > 0) {
-        for (const auto &cert_name : cert_names) {
-          Lookup.tree.insert(cert_name, entry, Parse_order++);
-          inserted = true;
-        }
-      }
-
-      if (!inserted) {
-        delete entry;
-        TSError(PCP "cert_names is empty and entry not otherwise inserted!");
-      }
-    } else {
-      TSError(PCP "failed to load the certificate entry");
-    }
-  }
-}
-
-void
-Parse_Config_Rules(Value &parent, ParsedSslValues &orig_values)
-{
-  for (size_t i = 0; i < parent.childCount(); i++) {
-    Value child = parent[i];
-    Parse_Config(child, orig_values);
-  }
-}
-
-void *
-Load_Certificate_Thread(void *arg)
-{
-  SslEntry *entry = reinterpret_cast<SslEntry *>(arg);
-
-  TSMutexLock(entry->mutex);
-  if (entry->ctx == nullptr) {
-    // Must load certificate
-    std::deque<std::string> cert_names;
-
-    entry->ctx = Load_Certificate(entry, cert_names);
-    while (entry->waitingVConns.begin() != entry->waitingVConns.end()) {
-      TSVConn vc = entry->waitingVConns.back();
-      entry->waitingVConns.pop_back();
-      TSSslConnection sslobj = TSVConnSSLConnectionGet(vc);
-      SSL *ssl               = reinterpret_cast<SSL *>(sslobj);
-      SSL_set_SSL_CTX(ssl, entry->ctx);
-      TSVConnReenable(vc);
-    }
-    TSMutexUnlock(entry->mutex);
-    for (const auto &cert_name : cert_names) {
-      Lookup.tree.insert(cert_name, entry, Parse_order++);
-    }
-  } else {
-    TSMutexUnlock(entry->mutex);
-  }
-
-  return (void *)1;
-}
-
-int
-CB_Life_Cycle(TSCont, TSEvent, void *)
-{
-  // By now the SSL library should have been initialized,
-  // We can safely parse the config file and load the ctx tables
-  Load_Configuration();
-
-  return TS_SUCCESS;
-}
-
-int
-CB_Pre_Accept(TSCont /*contp*/, TSEvent event, void *edata)
-{
-  TSVConn ssl_vc = reinterpret_cast<TSVConn>(edata);
-  IpAddr ip(TSNetVConnLocalAddrGet(ssl_vc));
-  char buff[INET6_ADDRSTRLEN];
-  IpAddr ip_client(TSNetVConnRemoteAddrGet(ssl_vc));
-  char buff2[INET6_ADDRSTRLEN];
-
-  TSDebug(PN, "Pre accept callback %p - event is %s, target address %s, client address %s", ssl_vc,
-          event == TS_EVENT_VCONN_START ? "good" : "bad", ip.toString(buff, sizeof(buff)),
-          ip_client.toString(buff2, sizeof(buff2)));
-
-  // Is there a cert already defined for this IP?
-  //
-  IpEndpoint key_endpoint;
-  key_endpoint.assign(ip);
-  void *payload;
-  if (Lookup.ipmap.contains(&key_endpoint, &payload)) {
-    // Set the stored cert on this SSL object
-    TSSslConnection sslobj = TSVConnSSLConnectionGet(ssl_vc);
-    SSL *ssl               = reinterpret_cast<SSL *>(sslobj);
-    SslEntry *entry        = reinterpret_cast<SslEntry *>(payload);
-    TSMutexLock(entry->mutex);
-    if (entry->op == SSL_HOOK_OP_TUNNEL || entry->op == SSL_HOOK_OP_TERMINATE) {
-      // Push everything to blind tunnel, or terminate
-      if (entry->op == SSL_HOOK_OP_TUNNEL) {
-        TSVConnTunnel(ssl_vc);
-      }
-      TSMutexUnlock(entry->mutex);
-    } else {
-      if (entry->ctx == nullptr) {
-        if (entry->waitingVConns.begin() == entry->waitingVConns.end()) {
-          entry->waitingVConns.push_back(ssl_vc);
-          TSMutexUnlock(entry->mutex);
-
-          TSThreadCreate(Load_Certificate_Thread, entry);
-        } else { // Just add yourself to the queue
-          entry->waitingVConns.push_back(ssl_vc);
-          TSMutexUnlock(entry->mutex);
-        }
-        // Return before we reenable
-        return TS_SUCCESS;
-      } else { // if (entry->ctx != NULL) {
-        SSL_set_SSL_CTX(ssl, entry->ctx);
-        TSDebug(PN, "Replace cert based on IP");
-        TSMutexUnlock(entry->mutex);
-      }
-    }
-  }
-
-  // All done, reactivate things
-  TSVConnReenable(ssl_vc);
-
-  return TS_SUCCESS;
-}
-
-int
-CB_servername(TSCont /*contp*/, TSEvent /*event*/, void *edata)
-{
-  TSVConn ssl_vc         = reinterpret_cast<TSVConn>(edata);
-  TSSslConnection sslobj = TSVConnSSLConnectionGet(ssl_vc);
-  SSL *ssl               = reinterpret_cast<SSL *>(sslobj);
-  const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
-
-  TSDebug(PN, "SNI callback %s", servername);
-  if (servername != nullptr) {
-    // Is there a certificated loaded up for this name
-    DomainNameTree::DomainNameNode *node = Lookup.tree.findFirstMatch(servername);
-    if (node != nullptr && node->payload != nullptr) {
-      SslEntry *entry = reinterpret_cast<SslEntry *>(node->payload);
-      if (entry->op == SSL_HOOK_OP_TUNNEL || entry->op == SSL_HOOK_OP_TERMINATE) {
-        // Push everything to blind tunnel
-        if (entry->op == SSL_HOOK_OP_TUNNEL) {
-          TSVConnTunnel(ssl_vc);
-        }
-        // Make sure we stop out of the SNI callback
-        // So return before re-enabling the SSL connection
-        return TS_SUCCESS;
-      }
-      TSMutexLock(entry->mutex);
-      if (entry->ctx == nullptr) {
-        // Spawn off a thread to load a potentially expensive certificate
-        if (entry->waitingVConns.begin() == entry->waitingVConns.end()) {
-          entry->waitingVConns.push_back(ssl_vc);
-          TSMutexUnlock(entry->mutex);
-          TSThreadCreate(Load_Certificate_Thread, entry);
-        } else { // Just add yourself to the queue
-          entry->waitingVConns.push_back(ssl_vc);
-          TSMutexUnlock(entry->mutex);
-        }
-        // Won't reenable until the certificate has been loaded
-        return TS_SUCCESS;
-      } else { // if (entry->ctx != NULL) {
-        SSL_set_SSL_CTX(ssl, entry->ctx);
-        TSDebug(PN, "Replace cert based on name %s", servername);
-      }
-      TSMutexUnlock(entry->mutex);
-    }
-  }
-  // All done, reactivate things
-  TSVConnReenable(ssl_vc);
-
-  return TS_SUCCESS;
-}
-
-} // namespace
-
-// Called by ATS as our initialization point
-void
-TSPluginInit(int argc, const char *argv[])
-{
-  bool success = false;
-  TSPluginRegistrationInfo info;
-  TSCont cb_pa                         = nullptr; // pre-accept callback continuation
-  TSCont cb_lc                         = nullptr; // life cycle callback continuuation
-  TSCont cb_sni                        = nullptr; // SNI callback continuuation
-  static const struct option longopt[] = {
-    {const_cast<char *>("config"), required_argument, nullptr, 'c'},
-    {nullptr, no_argument, nullptr, '\0'},
-  };
-
-  info.plugin_name   = const_cast<char *>("SSL Certificate Loader");
-  info.vendor_name   = const_cast<char *>("Network Geographics");
-  info.support_email = const_cast<char *>("shinrich@network-geographics.com");
-
-  int opt = 0;
-  while (opt >= 0) {
-    opt = getopt_long(argc, (char *const *)argv, "c:", longopt, nullptr);
-    switch (opt) {
-    case 'c':
-      ConfigPath = optarg;
-      ConfigPath = std::string(TSConfigDirGet()) + '/' + std::string(optarg);
-      break;
-    }
-  }
-  if (ConfigPath.length() == 0) {
-    static const char *const DEFAULT_CONFIG_PATH = "ssl_start.cfg";
-    ConfigPath                                   = std::string(TSConfigDirGet()) + '/' + std::string(DEFAULT_CONFIG_PATH);
-    TSDebug(PN, "No config path set in arguments, using default: %s", DEFAULT_CONFIG_PATH);
-  }
-
-  if (TS_SUCCESS != TSPluginRegister(&info)) {
-    TSError(PCP "registration failed");
-  } else if (TSTrafficServerVersionGetMajor() < 5) {
-    TSError(PCP "requires Traffic Server 5.0 or later");
-  } else if (nullptr == (cb_pa = TSContCreate(&CB_Pre_Accept, TSMutexCreate()))) {
-    TSError(PCP "Failed to pre-accept callback");
-  } else if (nullptr == (cb_lc = TSContCreate(&CB_Life_Cycle, TSMutexCreate()))) {
-    TSError(PCP "Failed to lifecycle callback");
-  } else if (nullptr == (cb_sni = TSContCreate(&CB_servername, TSMutexCreate()))) {
-    TSError(PCP "Failed to create SNI callback");
-  } else {
-    TSLifecycleHookAdd(TS_LIFECYCLE_PORTS_INITIALIZED_HOOK, cb_lc);
-    TSHttpHookAdd(TS_VCONN_START_HOOK, cb_pa);
-    TSHttpHookAdd(TS_SSL_SNI_HOOK, cb_sni);
-    success = true;
-  }
-
-  if (!success) {
-    if (cb_pa) {
-      TSContDestroy(cb_pa);
-    }
-    if (cb_lc) {
-      TSContDestroy(cb_lc);
-    }
-    TSError(PCP "not initialized");
-  }
-  TSDebug(PN, "Plugin %s", success ? "online" : "offline");
-
-  return;
-}
diff --git a/plugins/experimental/ssl_cert_loader/ssl_cert_loader.cfg b/plugins/experimental/ssl_cert_loader/ssl_cert_loader.cfg
deleted file mode 100644
index 20b1d1b..0000000
--- a/plugins/experimental/ssl_cert_loader/ssl_cert_loader.cfg
+++ /dev/null
@@ -1,150 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Describe how proxy should deal with the handshake process of SSL
-// connections passing though.
-version = "0.1";
-
-// Once the certificate load table surpasses this limit
-// Start evicting already loaded certificates
-runtime-table-size = "10000";
-
-// By default the proxy will participate in the handshake, so it needs
-// to have a certificate that it uses to handshake with the client, and
-// potentially another certificate to handshake with the origin server
-// In this case, the config must specify both the matching traffic conditions
-// and the connection attributes (certificates, tickets, etc).
-
-// Alternatively the proxy could be directed to get out of the way and
-// blind tunnel the SSL connection.  There are no options to set in this
-// case.  Only specify the matching traffic.
-
-// There are two rule lists.  One that matches on characteristics of the
-// origin server.
-// Another that matches on characteristics of the client.
-
-// The attributes specified by matches in both rule lists will be used
-// to process the connection.  If either rule list specifies a "tunnel" action
-// the connection will be blind tunneled. If either rule specifies a "deny"
-// action, the handshake processing will stop
-
-// Each rule list  will be evaluated in order and stop on a match
-
-ssl-server-match =
-(
-  { server-ip = "192.168.56.0-192.168.56.255";
-    action="proxy"; /* Default if no action is specified */
-    server-cert = "server1.pem";
-    ssl-key-name = "privkey.pem";
-    ssl-ticket-key-name = ( "ticket-key.blob", "ticket-key-old.blob" );
-    child-match =
-      // Doing something different for a couple servers in the range
-      { server-ip = "192.168.56.45";
-        server-cert = "server11.pem";
-      },
-      { server-ip = "192.168.56.46";
-        server-cert = "server12.pem";
-      },
-    );
-  },
-  { server-name = "example.com";
-    server-cert = "server2.pem";
-    ssl-key-name = "privkey.pem";
-  },
-  {
-    /* Could include characteristics of the offered ciphers in
-       evaluating the actions */
-    offered-cipher-constraint = {
-      compare-op = "not-include";
-      ciphers = ("3DES", "null");
-    };
-    server-cert = "server6.pem";
-    ssl-key-name = "privkey.pem";
-  },
-
-  {
-    /* Default, if no server-ip or server-name is specified,
-       use the name in the certificate */
-    server-name = "@";
-    action="proxy";
-    server-cert = "server3.pem";
-    ssl-key-name = "privkey.pem";
-  },
-  {
-    /* With the defaults, devolves to the base case of the
-       ssl_multicert.config */
-    server-cert = "server5.pem";
-    ssl-key-name = "privkey.pem";
-  },
-  /* You can specify the SSL options (non matching state)
-     in a separate entry and refer to it.  Anything specified
-     directly in the match rule will override the ssl-options
-  */
-  { server-ip = "192.168.100.0-192.168.100.100";
-    ssl-options = <ssl-actions.ssl-info-1>;
-  },
-  { server-ip = "192.168.110.0-192.168.110.100";
-    ssl-options = <ssl-actions.ssl-info-1>;
-  },
-  { server-name = "*.yahoo.com";
-    action="tunnel";
-  },
-  /* All other traffic should be blind tunneled */
-  { server-ip = "0.0.0.0-255.255.255.255";
-    action = "tunnel";
-  }
-);
-
-ssl-client-match:
-(
-  // In all cases, use the same cipher-suites
-  { use-client-cipher-suite = < cipher-suites.ecdhe >;
-    child-match =
-    (
-      /* Traffic from lab should be blind tunneled */
-      { client-ip = ("10.10.10.0-10.10.10.255", "10.10.50.152");
-        action = "tunnel";
-      }
-      /* Clients from the office must use an authorized client certificate
-         Proxy must verify.  Must specify cert to use with origin server */
-      { client-ip = "10.10.20.0-10.10.20.255";
-        client-cert = "valid";
-        /* Specify, or rely on your system settings for cert verification */
-        ssl-signer-cert-name = "signers.pem";
-        client-cert-name = "client1.pem";
-        priv-key-name = "client-priv-key.pem";
-      },
-      /* Clients from the other office are not yet set up with client
-         certs.  But must provide client certs for the origin server */
-      { client-ip = "10.10.30.0-10.10.30.255";
-        /* Could be present or not, don't care, this is the default
-           Other options are valid, present, or none
-         */
-        client-cert = "unknown";
-        client-cert-name = "client1.pem";
-        priv-key-name = "client-priv-key.pem";
-      },
-  }
-);
-
-
-ssl-actions  =
-{
-  ssl-info-1 = {
-    server-cert = "server4.pem";
-    ssl-key-name = "privkey.pem";
-  };
-};
diff --git a/plugins/experimental/ssl_cert_loader/ssl_start.cfg b/plugins/experimental/ssl_cert_loader/ssl_start.cfg
deleted file mode 100644
index 48525bd..0000000
--- a/plugins/experimental/ssl_cert_loader/ssl_start.cfg
+++ /dev/null
@@ -1,72 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Describe how proxy should deal with the handshake process of SSL
-// connections passing though.
-version = "0.1"
-
-// Once the certificate load table surpasses this limit
-// Start evicting already loaded certificates
-runtime-table-size = "10000"
-
-// By default the proxy will participate in the handshake, so it needs
-// to have a certificate that it uses to handshake with the client, and
-// potentially another certificate to handshake with the origin server
-// In this case, the config must specify both the matching traffic conditions
-// and the connection attributes (certificates, tickets, etc).
-
-// Alternatively the proxy could be directed to get out of the way and
-// blind tunnel the SSL connection.  There are no options to set in this
-// case.  Only specify the matching traffic.
-
-// There are two rule lists.  One that matches on characteristics of the
-// origin server.
-// Another that matches on characteristics of the client.
-
-// The attributes specified by matches in both rule lists will be used
-// to process the connection.  If either rule list specifies a "tunnel" action
-// the connection will be blind tunneled. If either rule specifies a "deny"
-// action, the handshake processing will stop
-
-// Each rule list  will be evaluated in order and stop on a match
-
-ssl-server-match =
-(
-  // Using the same private key for all of my certs
-  { ssl-key-name = "privkey.pem";
-    child-match =
-    (
-      { server-ip = "107.23.60.186";
-        action = "tunnel"
-      },
-      { server-cert-name = "safelyfiled.pem";
-        server-name = "safelyfiled.com"
-      },
-      { server-cert-name = "asba.pem"
-      },
-      { server-name = "www.yahoo.com";
-        server-cert-name = "asba.pem"
-      },
-      { server-cert-name = "buseyil.pem"
-      },
-      { server-cert-name = "busey.pem"
-      },
-      { server-cert-name = "wildgoogle.pem"
-      }
-    );
-  }
-)
-