Browse Source

add ssl-cipher-list

David Rose 22 years ago
parent
commit
62a3e02bb6

+ 4 - 0
panda/src/downloader/config_downloader.cxx

@@ -78,6 +78,10 @@ config_downloader.GetBool("early-random-seed", true);
 const bool verify_ssl =
 config_downloader.GetBool("verify-ssl", true);
 
+// This is the default value for HTTPClient::set_cipher_list().
+const string ssl_cipher_list =
+config_downloader.GetString("ssl-cipher-list", "DEFAULT");
+
 // This specifies the proxy that we will contact for all HTTP
 // connections that don't specify otherwise.
 const string http_proxy =

+ 1 - 0
panda/src/downloader/config_downloader.h

@@ -42,6 +42,7 @@ extern const int patcher_buffer_size;
 
 extern const bool early_random_seed;
 extern const bool verify_ssl;
+extern const string ssl_cipher_list;
 extern const string http_proxy;
 extern const string http_direct_hosts;
 extern const string http_proxy_username;

+ 46 - 2
panda/src/downloader/httpChannel.cxx

@@ -736,8 +736,8 @@ run_connecting_wait() {
     return false;
   }
 
-  if (downloader_cat.is_debug()) {
-    downloader_cat.debug()
+  if (downloader_cat.is_spam()) {
+    downloader_cat.spam()
       << "waiting to connect to " << _request.get_url().get_server_and_port() << ".\n";
   }
   fd_set wset;
@@ -1135,6 +1135,39 @@ run_setup_ssl() {
   _sbio = BIO_new_ssl(_client->get_ssl_ctx(), true);
   BIO_push(_sbio, *_bio);
 
+  SSL *ssl;
+  BIO_get_ssl(_sbio, &ssl);
+  nassertr(ssl != (SSL *)NULL, false);
+  string cipher_list = _client->get_cipher_list();
+  if (downloader_cat.is_debug()) {
+    downloader_cat.debug()
+      << "Setting ssl-cipher-list '" << cipher_list << "'\n";
+  }
+  int result = SSL_set_cipher_list(ssl, cipher_list.c_str());
+  if (result == 0) {
+    downloader_cat.error()
+      << "Invalid cipher list: '" << cipher_list << "'\n";
+#ifdef REPORT_OPENSSL_ERRORS
+    ERR_print_errors_fp(stderr);
+#endif
+    _state = S_failure;
+    return false;
+  }
+
+  if (downloader_cat.is_spam()) {
+    downloader_cat.spam()
+      << "SSL Ciphers available:\n";
+    const char *name;
+    int pri = 0;
+    name = SSL_get_cipher_list(ssl, pri);
+    while (name != NULL) {
+      downloader_cat.spam()
+        << "  " << pri + 1 << ". " << name << "\n";
+      pri++;
+      name = SSL_get_cipher_list(ssl, pri);
+    }
+  }
+
   if (downloader_cat.is_debug()) {
     downloader_cat.debug()
       << "performing SSL handshake\n";
@@ -1176,6 +1209,17 @@ run_ssl_handshake() {
     SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
   }
 
+  SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
+  if (cipher == (SSL_CIPHER *)NULL) {
+    downloader_cat.warning()
+      << "No current cipher on SSL connection.\n";
+  } else {
+    if (downloader_cat.debug()) {
+      downloader_cat.debug()
+        << "Using cipher " << SSL_CIPHER_get_name(cipher) << "\n";
+    }
+  }
+
   // Now that we've made an SSL handshake, we can use the SSL bio to
   // do all of our communication henceforth.
   _bio->set_bio(_sbio);

+ 28 - 0
panda/src/downloader/httpClient.I

@@ -69,3 +69,31 @@ get_verify_ssl() const {
   return _verify_ssl;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: HTTPClient::set_cipher_list
+//       Access: Published
+//  Description: Specifies the set of ciphers that are to be made
+//               available for SSL connections.  This is a string as
+//               described in the ciphers(1) man page of the OpenSSL
+//               documentation (or see
+//               http://www.openssl.org/docs/apps/ciphers.html ).  If
+//               this is not specified, the default is provided by the
+//               Config file.  You may also specify "DEFAULT" to use
+//               the built-in OpenSSL default value.
+////////////////////////////////////////////////////////////////////
+INLINE void HTTPClient::
+set_cipher_list(const string &cipher_list) {
+  _cipher_list = cipher_list;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: HTTPClient::get_cipher_list
+//       Access: Published
+//  Description: Returns the set of ciphers as set by
+//               set_cipher_list().  See set_cipher_list().
+////////////////////////////////////////////////////////////////////
+INLINE const string &HTTPClient::
+get_cipher_list() const {
+  return _cipher_list;
+}
+

+ 2 - 0
panda/src/downloader/httpClient.cxx

@@ -109,6 +109,8 @@ HTTPClient() {
     set_username("*proxy", "", http_proxy_username);
   }
 
+  set_cipher_list(ssl_cipher_list);
+
   {
     // Also load in the general usernames.
     Config::ConfigTable::Symbol http_usernames;

+ 4 - 0
panda/src/downloader/httpClient.h

@@ -98,6 +98,9 @@ PUBLISHED:
   INLINE void set_verify_ssl(VerifySSL verify_ssl);
   INLINE VerifySSL get_verify_ssl() const;
 
+  INLINE void set_cipher_list(const string &cipher_list);
+  INLINE const string &get_cipher_list() const;
+
   bool add_expected_server(const string &server_attributes);
   void clear_expected_servers();
 
@@ -141,6 +144,7 @@ private:
 
   HTTPEnum::HTTPVersion _http_version;
   VerifySSL _verify_ssl;
+  string _cipher_list;
 
   typedef pmap<string, string> Usernames;
   Usernames _usernames;