зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1100917 - Add config options for SSL3/RC4 only servers to ssltunnel. r=ted
This commit is contained in:
Родитель
b34b31d059
Коммит
c8b6471be5
|
@ -888,6 +888,9 @@ class SSLTunnel:
|
|||
config.write("redirhost:%s:%s:%s:%s\n" %
|
||||
(loc.host, loc.port, self.sslPort, redirhost))
|
||||
|
||||
if option in ('ssl3', 'rc4'):
|
||||
config.write("%s:%s:%s:%s\n" % (option, loc.host, loc.port, self.sslPort))
|
||||
|
||||
def buildConfig(self, locations):
|
||||
"""Create the ssltunnel configuration file"""
|
||||
configFd, self.configFile = tempfile.mkstemp(prefix="ssltunnel", suffix=".cfg")
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nss.h"
|
||||
#include "key.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
#include "plhash.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -152,6 +153,8 @@ typedef struct {
|
|||
PLHashTable* host_cert_table;
|
||||
PLHashTable* host_clientauth_table;
|
||||
PLHashTable* host_redir_table;
|
||||
PLHashTable* host_ssl3_table;
|
||||
PLHashTable* host_rc4_table;
|
||||
} server_info_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -258,7 +261,8 @@ void SignalShutdown()
|
|||
|
||||
bool ReadConnectRequest(server_info_t* server_info,
|
||||
relayBuffer& buffer, int32_t* result, string& certificate,
|
||||
client_auth_option* clientauth, string& host, string& location)
|
||||
client_auth_option* clientauth, string& host, string& location,
|
||||
bool* ssl3, bool* rc4)
|
||||
{
|
||||
if (buffer.present() < 4) {
|
||||
LOG_DEBUG((" !! only %d bytes present in the buffer", (int)buffer.present()));
|
||||
|
@ -307,6 +311,10 @@ bool ReadConnectRequest(server_info_t* server_info,
|
|||
if (redir)
|
||||
location = static_cast<char*>(redir);
|
||||
|
||||
*ssl3 = !!PL_HashTableLookup(server_info->host_ssl3_table, token);
|
||||
|
||||
*rc4 = !!PL_HashTableLookup(server_info->host_rc4_table, token);
|
||||
|
||||
token = strtok2(_caret, "/", &_caret);
|
||||
if (strcmp(token, "HTTP")) {
|
||||
LOG_ERRORD((" not tailed with HTTP but with %s", token));
|
||||
|
@ -317,7 +325,8 @@ bool ReadConnectRequest(server_info_t* server_info,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, string &certificate, client_auth_option clientAuth)
|
||||
bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, const string &certificate,
|
||||
const client_auth_option clientAuth, bool ssl3, bool rc4)
|
||||
{
|
||||
const char* certnick = certificate.empty() ?
|
||||
si->cert_nickname.c_str() : certificate.c_str();
|
||||
|
@ -357,6 +366,30 @@ bool ConfigureSSLServerSocket(PRFileDesc* socket, server_info_t* si, string &cer
|
|||
SSL_OptionSet(ssl_socket, SSL_REQUIRE_CERTIFICATE, clientAuth == caRequire);
|
||||
}
|
||||
|
||||
if (ssl3) {
|
||||
SSLVersionRange range = { SSL_LIBRARY_VERSION_3_0,
|
||||
SSL_LIBRARY_VERSION_3_0 };
|
||||
SSL_VersionRangeSet(ssl_socket, &range);
|
||||
}
|
||||
|
||||
if (rc4) {
|
||||
for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
|
||||
uint16_t cipher_id = SSL_ImplementedCiphers[i];
|
||||
switch (cipher_id) {
|
||||
case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
|
||||
case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
|
||||
case TLS_RSA_WITH_RC4_128_SHA:
|
||||
case TLS_RSA_WITH_RC4_128_MD5:
|
||||
SSL_CipherPrefSet(ssl_socket, cipher_id, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
SSL_CipherPrefSet(ssl_socket, cipher_id, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSL_ResetHandshake(ssl_socket, true);
|
||||
|
||||
return true;
|
||||
|
@ -547,6 +580,8 @@ void HandleConnection(void* data)
|
|||
string locationHeader;
|
||||
client_auth_option clientAuth;
|
||||
string fullHost;
|
||||
bool ssl3 = false;
|
||||
bool rc4 = false;
|
||||
|
||||
LOG_DEBUG(("SSLTUNNEL(%p)): incoming connection csock(0)=%p, ssock(1)=%p\n",
|
||||
static_cast<void*>(data),
|
||||
|
@ -560,7 +595,8 @@ void HandleConnection(void* data)
|
|||
|
||||
if (!do_http_proxy)
|
||||
{
|
||||
if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse, caNone))
|
||||
if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info, certificateToUse, caNone,
|
||||
ssl3, rc4))
|
||||
client_error = true;
|
||||
else if (!ConnectSocket(other_sock, &remote_addr, connect_timeout))
|
||||
client_error = true;
|
||||
|
@ -678,7 +714,8 @@ void HandleConnection(void* data)
|
|||
// We have to accept and handle the initial CONNECT request here
|
||||
int32_t response;
|
||||
if (!connect_accepted && ReadConnectRequest(ci->server_info, buffers[s],
|
||||
&response, certificateToUse, &clientAuth, fullHost, locationHeader))
|
||||
&response, certificateToUse, &clientAuth, fullHost, locationHeader,
|
||||
&ssl3, &rc4))
|
||||
{
|
||||
// Mark this as a proxy-only connection (no SSL) if the CONNECT
|
||||
// request didn't come for port 443 or from any of the server's
|
||||
|
@ -694,6 +731,12 @@ void HandleConnection(void* data)
|
|||
PL_HashTableEnumerateEntries(ci->server_info->host_clientauth_table,
|
||||
match_hostname,
|
||||
&match);
|
||||
PL_HashTableEnumerateEntries(ci->server_info->host_ssl3_table,
|
||||
match_hostname,
|
||||
&match);
|
||||
PL_HashTableEnumerateEntries(ci->server_info->host_rc4_table,
|
||||
match_hostname,
|
||||
&match);
|
||||
ci->http_proxy_only = !match.matched;
|
||||
}
|
||||
else
|
||||
|
@ -829,7 +872,7 @@ void HandleConnection(void* data)
|
|||
LOG_DEBUG((" not updating to SSL based on http_proxy_only for this socket"));
|
||||
}
|
||||
else if (!ConfigureSSLServerSocket(ci->client_sock, ci->server_info,
|
||||
certificateToUse, clientAuth))
|
||||
certificateToUse, clientAuth, ssl3, rc4))
|
||||
{
|
||||
LOG_ERRORD((" failed to config server socket\n"));
|
||||
client_error = true;
|
||||
|
@ -951,6 +994,58 @@ server_info_t* findServerInfo(int portnumber)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PLHashTable* get_ssl3_table(server_info_t* server)
|
||||
{
|
||||
return server->host_ssl3_table;
|
||||
}
|
||||
|
||||
PLHashTable* get_rc4_table(server_info_t* server)
|
||||
{
|
||||
return server->host_rc4_table;
|
||||
}
|
||||
|
||||
int parseWeakCryptoConfig(char* const& keyword, char*& _caret,
|
||||
PLHashTable* (*get_table)(server_info_t*))
|
||||
{
|
||||
char* hostname = strtok2(_caret, ":", &_caret);
|
||||
char* hostportstring = strtok2(_caret, ":", &_caret);
|
||||
char* serverportstring = strtok2(_caret, "\n", &_caret);
|
||||
|
||||
int port = atoi(serverportstring);
|
||||
if (port <= 0) {
|
||||
LOG_ERROR(("Invalid port specified: %s\n", serverportstring));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (server_info_t* existingServer = findServerInfo(port))
|
||||
{
|
||||
any_host_spec_config = true;
|
||||
|
||||
char *hostname_copy = new char[strlen(hostname)+strlen(hostportstring)+2];
|
||||
if (!hostname_copy) {
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
strcpy(hostname_copy, hostname);
|
||||
strcat(hostname_copy, ":");
|
||||
strcat(hostname_copy, hostportstring);
|
||||
|
||||
PLHashEntry* entry = PL_HashTableAdd(get_table(existingServer), hostname_copy, keyword);
|
||||
if (!entry) {
|
||||
LOG_ERROR(("Out of memory"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR(("Server on port %d for redirhost option is not defined, use 'listen' option first", port));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int processConfigLine(char* configLine)
|
||||
{
|
||||
if (*configLine == 0 || *configLine == '#')
|
||||
|
@ -1067,6 +1162,23 @@ int processConfigLine(char* configLine)
|
|||
LOG_ERROR(("Internal, could not create hash table\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
server.host_ssl3_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings,
|
||||
PL_CompareStrings, nullptr, nullptr);;
|
||||
if (!server.host_ssl3_table)
|
||||
{
|
||||
LOG_ERROR(("Internal, could not create hash table\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
server.host_rc4_table = PL_NewHashTable(0, PL_HashString, PL_CompareStrings,
|
||||
PL_CompareStrings, nullptr, nullptr);;
|
||||
if (!server.host_rc4_table)
|
||||
{
|
||||
LOG_ERROR(("Internal, could not create hash table\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
servers.push_back(server);
|
||||
}
|
||||
|
||||
|
@ -1178,6 +1290,14 @@ int processConfigLine(char* configLine)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(keyword, "ssl3")) {
|
||||
return parseWeakCryptoConfig(keyword, _caret, get_ssl3_table);
|
||||
}
|
||||
|
||||
if (!strcmp(keyword, "rc4")) {
|
||||
return parseWeakCryptoConfig(keyword, _caret, get_rc4_table);
|
||||
}
|
||||
|
||||
// Configure the NSS certificate database directory
|
||||
if (!strcmp(keyword, "certdbdir"))
|
||||
{
|
||||
|
@ -1252,6 +1372,18 @@ int freeClientAuthHashItems(PLHashEntry *he, int i, void *arg)
|
|||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
int freeSSL3HashItems(PLHashEntry *he, int i, void *arg)
|
||||
{
|
||||
delete [] (char*)he->key;
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
int freeRC4HashItems(PLHashEntry *he, int i, void *arg)
|
||||
{
|
||||
delete [] (char*)he->key;
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* configFilePath;
|
||||
|
@ -1384,9 +1516,13 @@ int main(int argc, char** argv)
|
|||
PL_HashTableEnumerateEntries(it->host_cert_table, freeHostCertHashItems, nullptr);
|
||||
PL_HashTableEnumerateEntries(it->host_clientauth_table, freeClientAuthHashItems, nullptr);
|
||||
PL_HashTableEnumerateEntries(it->host_redir_table, freeHostRedirHashItems, nullptr);
|
||||
PL_HashTableEnumerateEntries(it->host_ssl3_table, freeSSL3HashItems, nullptr);
|
||||
PL_HashTableEnumerateEntries(it->host_rc4_table, freeRC4HashItems, nullptr);
|
||||
PL_HashTableDestroy(it->host_cert_table);
|
||||
PL_HashTableDestroy(it->host_clientauth_table);
|
||||
PL_HashTableDestroy(it->host_redir_table);
|
||||
PL_HashTableDestroy(it->host_ssl3_table);
|
||||
PL_HashTableDestroy(it->host_rc4_table);
|
||||
}
|
||||
|
||||
PR_Cleanup();
|
||||
|
|
Загрузка…
Ссылка в новой задаче