فهرست منبع

better solution to multiple certificate problem

David Rose 23 سال پیش
والد
کامیت
92a763eee1
2فایلهای تغییر یافته به همراه43 افزوده شده و 28 حذف شده
  1. 35 22
      panda/src/downloader/httpClient.cxx
  2. 8 6
      panda/src/downloader/httpClient.h

+ 35 - 22
panda/src/downloader/httpClient.cxx

@@ -31,7 +31,9 @@
 #endif
 #endif
 
 
 bool HTTPClient::_ssl_initialized = false;
 bool HTTPClient::_ssl_initialized = false;
-SSL_CTX *HTTPClient::_ssl_ctx = NULL;
+
+// Never freed.
+X509_STORE *HTTPClient::_x509_store = NULL;
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -41,8 +43,12 @@ SSL_CTX *HTTPClient::_ssl_ctx = NULL;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 HTTPClient::
 HTTPClient::
 ~HTTPClient() {
 ~HTTPClient() {
-  // Since the context is temporarily shared among all clients.
-  //  SSL_CTX_free(_ssl_ctx);
+  // Before we can free the context, we must remove the X509_STORE
+  // pointer from it, so it won't be destroyed along with it (this
+  // object is shared among all contexts).
+  nassertv(_ssl_ctx->cert_store == _x509_store);
+  _ssl_ctx->cert_store = NULL;
+  SSL_CTX_free(_ssl_ctx);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -126,11 +132,6 @@ make_ctx() {
     initialize_ssl();
     initialize_ssl();
   }
   }
 
 
-  if (_ssl_ctx != (SSL_CTX *)NULL) {
-    // Since the context is temporarily shared among all clients.
-    return;
-  }
-
   _ssl_ctx = SSL_CTX_new(SSLv23_client_method());
   _ssl_ctx = SSL_CTX_new(SSLv23_client_method());
 
 
 #if defined(SSL_097) && !defined(NDEBUG)
 #if defined(SSL_097) && !defined(NDEBUG)
@@ -144,20 +145,32 @@ make_ctx() {
   // Insist on verifying servers if we are configured to.
   // Insist on verifying servers if we are configured to.
   set_verify_ssl(verify_ssl);
   set_verify_ssl(verify_ssl);
 
 
-  // Load in any default certificates listed in the Configrc file.
-  Config::ConfigTable::Symbol cert_files;
-  config_express.GetAll("ssl-certificates", cert_files);
-  
-  // When we use GetAll(), we might inadvertently read duplicate
-  // lines.  Filter them out with a set.
-  pset<string> already_read;
-  
-  Config::ConfigTable::Symbol::iterator si;
-  for (si = cert_files.begin(); si != cert_files.end(); ++si) {
-    string cert_file = (*si).Val();
-    if (already_read.insert(cert_file).second) {
-      Filename filename = Filename::from_os_specific(ExecutionEnvironment::expand_string(cert_file));
-      load_certificates(filename);
+  if (_x509_store != (X509_STORE *)NULL) {
+    // If we've already created an x509 store object, use it for this
+    // context.
+    SSL_CTX_set_cert_store(_ssl_ctx, _x509_store);
+
+  } else {
+    // Create the first x509 store object, and fill it up with our
+    // certificates.
+    _x509_store = X509_STORE_new();
+    SSL_CTX_set_cert_store(_ssl_ctx, _x509_store);
+
+    // Load in any default certificates listed in the Configrc file.
+    Config::ConfigTable::Symbol cert_files;
+    config_express.GetAll("ssl-certificates", cert_files);
+    
+    // When we use GetAll(), we might inadvertently read duplicate
+    // lines.  Filter them out with a set.
+    pset<string> already_read;
+    
+    Config::ConfigTable::Symbol::iterator si;
+    for (si = cert_files.begin(); si != cert_files.end(); ++si) {
+      string cert_file = (*si).Val();
+      if (already_read.insert(cert_file).second) {
+        Filename filename = Filename::from_os_specific(ExecutionEnvironment::expand_string(cert_file));
+        load_certificates(filename);
+      }
     }
     }
   }
   }
 }
 }

+ 8 - 6
panda/src/downloader/httpClient.h

@@ -39,14 +39,18 @@ class Filename;
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : HTTPClient
 //       Class : HTTPClient
 // Description : Handles contacting an HTTP server and retrieving a
 // Description : Handles contacting an HTTP server and retrieving a
-//               document.
+//               document.  Each HTTPClient object represents a
+//               separate context; it is up to the programmer whether
+//               one HTTPClient should be used to retrieve all
+//               documents, or a separate one should be created each
+//               time.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDAEXPRESS HTTPClient {
 class EXPCL_PANDAEXPRESS HTTPClient {
 PUBLISHED:
 PUBLISHED:
   INLINE HTTPClient();
   INLINE HTTPClient();
   INLINE HTTPClient(const HTTPClient &copy);
   INLINE HTTPClient(const HTTPClient &copy);
   INLINE void operator = (const HTTPClient &copy);
   INLINE void operator = (const HTTPClient &copy);
-  INLINE ~HTTPClient();
+  ~HTTPClient();
 
 
   INLINE void set_proxy(const URLSpec &proxy);
   INLINE void set_proxy(const URLSpec &proxy);
   INLINE const URLSpec &get_proxy() const;
   INLINE const URLSpec &get_proxy() const;
@@ -85,12 +89,10 @@ private:
 
 
   URLSpec _proxy;
   URLSpec _proxy;
   bool _verify_ssl;
   bool _verify_ssl;
+  SSL_CTX *_ssl_ctx;
 
 
   static bool _ssl_initialized;
   static bool _ssl_initialized;
-
-  // This is temporarily static, shared among all clients, to work
-  // around the loading certificates problem.
-  static SSL_CTX *_ssl_ctx;
+  static X509_STORE *_x509_store;
 };
 };
 
 
 #include "httpClient.I"
 #include "httpClient.I"