diff options
Diffstat (limited to 'net/base')
-rw-r--r-- | net/base/ssl_client_socket_nss.cc | 53 | ||||
-rw-r--r-- | net/base/ssl_client_socket_nss.h | 18 | ||||
-rw-r--r-- | net/base/ssl_client_socket_unittest.cc | 158 | ||||
-rw-r--r-- | net/base/ssl_test_util.cc | 240 | ||||
-rw-r--r-- | net/base/ssl_test_util.h | 85 |
5 files changed, 99 insertions, 455 deletions
diff --git a/net/base/ssl_client_socket_nss.cc b/net/base/ssl_client_socket_nss.cc index f67c246..5c33dc8 100644 --- a/net/base/ssl_client_socket_nss.cc +++ b/net/base/ssl_client_socket_nss.cc @@ -23,6 +23,21 @@ static const int kRecvBufferSize = 4096; +namespace { + +// NSS calls this if an incoming certificate is invalid. +SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket) { + PRErrorCode err = PR_GetError(); + LOG(INFO) << "server certificate is invalid; NSS error code " << err; + // Return SECSuccess to override the problem, + // or SECFailure to let the original function fail + // Chromium wants it to fail here, and may retry it later. + LOG(WARNING) << "TODO(dkegel): return SECFailure here"; + return SECSuccess; +} + +} // anonymous namespace + namespace net { // State machines are easier to debug if you log state transitions. @@ -64,8 +79,6 @@ int NetErrorFromNSPRError(PRErrorCode err) { case SEC_ERROR_REVOKED_KEY: return ERR_CERT_REVOKED; case SEC_ERROR_UNKNOWN_ISSUER: - case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_UNTRUSTED_ISSUER: return ERR_CERT_AUTHORITY_INVALID; default: { @@ -106,7 +119,7 @@ SSLClientSocketNSS::SSLClientSocketNSS(ClientSocket* transport_socket, user_callback_(NULL), user_buf_(NULL), user_buf_len_(0), - server_cert_error_(0), + server_cert_status_(0), completed_handshake_(false), next_state_(STATE_NONE), nss_fd_(NULL), @@ -229,12 +242,9 @@ void SSLClientSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { << " for cipherSuite " << channel_info.cipherSuite; } } - if (server_cert_error_ != net::OK) - ssl_info->SetCertError(server_cert_error_); - X509Certificate::OSCertHandle nss_cert = SSL_PeerCertificate(nss_fd_); - if (nss_cert) - ssl_info->cert = X509Certificate::CreateFromHandle(nss_cert, - X509Certificate::SOURCE_FROM_NETWORK); + ssl_info->cert_status = server_cert_status_; + // TODO(port): implement X509Certificate so we can set the cert field! + // CERTCertificate *nssCert = SSL_PeerCertificate(nss_fd_); LeaveFunction(""); } @@ -391,19 +401,6 @@ int SSLClientSocketNSS::DoConnect() { return transport_->Connect(&io_callback_); } -// static -// NSS calls this if an incoming certificate is invalid. -SECStatus SSLClientSocketNSS::OwnBadCertHandler(void* arg, PRFileDesc* socket) { - SSLClientSocketNSS* that = reinterpret_cast<SSLClientSocketNSS*>(arg); - PRErrorCode prerr = PR_GetError(); - that->server_cert_error_ = NetErrorFromNSPRError(prerr); - LOG(INFO) << "server certificate is invalid; NSS error code " << prerr - << ", net error " << that->server_cert_error_; - // Return SECSuccess to override the problem. - // Chromium wants it to succeed here, and may abort the connection later. - return SECSuccess; -} - int SSLClientSocketNSS::DoConnectComplete(int result) { EnterFunction(result); if (result < 0) @@ -482,7 +479,7 @@ int SSLClientSocketNSS::DoConnectComplete(int result) { if (rv != SECSuccess) return ERR_UNEXPECTED; - rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, this); + rv = SSL_BadCertHook(nss_fd_, OwnBadCertHandler, NULL); if (rv != SECSuccess) return ERR_UNEXPECTED; @@ -503,10 +500,11 @@ int SSLClientSocketNSS::DoHandshakeRead() { int rv = SSL_ForceHandshake(nss_fd_); if (rv == SECSuccess) { - net_error = server_cert_error_; + net_error = OK; // there's a callback for this, too completed_handshake_ = true; - // Done! + // Indicate we're ready to handle I/O. Badly named? + GotoState(STATE_NONE); } else { PRErrorCode prerr = PR_GetError(); net_error = NetErrorFromNSPRError(prerr); @@ -515,9 +513,10 @@ int SSLClientSocketNSS::DoHandshakeRead() { if (net_error == ERR_IO_PENDING) { GotoState(STATE_HANDSHAKE_READ); } else { - server_cert_error_ = net_error; + server_cert_status_ = MapNetErrorToCertStatus(net_error); LOG(ERROR) << "handshake failed; NSS error code " << prerr - << ", net_error " << net_error; + << ", net_error " << net_error << ", server_cert_status " + << server_cert_status_; } } diff --git a/net/base/ssl_client_socket_nss.h b/net/base/ssl_client_socket_nss.h index b16557c..5015e1e 100644 --- a/net/base/ssl_client_socket_nss.h +++ b/net/base/ssl_client_socket_nss.h @@ -5,13 +5,15 @@ #ifndef NET_BASE_SSL_CLIENT_SOCKET_NSS_H_ #define NET_BASE_SSL_CLIENT_SOCKET_NSS_H_ -#include <nspr.h> -#include <nss.h> +#include "build/build_config.h" + +#include <prio.h> +#include "net/base/nss_memio.h" + #include <string> #include "base/scoped_ptr.h" #include "net/base/completion_callback.h" -#include "net/base/nss_memio.h" #include "net/base/ssl_client_socket.h" #include "net/base/ssl_config_service.h" @@ -58,9 +60,6 @@ class SSLClientSocketNSS : public SSLClientSocket { void BufferSendComplete(int result); void BufferRecvComplete(int result); - // nss calls this on error. We pass 'this' as the first argument. - static SECStatus OwnBadCertHandler(void* arg, PRFileDesc* socket); - CompletionCallbackImpl<SSLClientSocketNSS> buffer_send_callback_; CompletionCallbackImpl<SSLClientSocketNSS> buffer_recv_callback_; bool transport_send_busy_; @@ -77,8 +76,7 @@ class SSLClientSocketNSS : public SSLClientSocket { char* user_buf_; int user_buf_len_; - // Set when handshake finishes. Value is net error code, see net_errors.h - int server_cert_error_; + int server_cert_status_; bool completed_handshake_; @@ -93,10 +91,10 @@ class SSLClientSocketNSS : public SSLClientSocket { }; State next_state_; - // The NSS SSL state machine + /* The NSS SSL state machine */ PRFileDesc* nss_fd_; - // Buffers for the network end of the SSL state machine + /* Buffers for the network end of the SSL state machine */ memio_Private* nss_bufs_; static bool nss_options_initialized_; diff --git a/net/base/ssl_client_socket_unittest.cc b/net/base/ssl_client_socket_unittest.cc index 4710151..faf5a4a 100644 --- a/net/base/ssl_client_socket_unittest.cc +++ b/net/base/ssl_client_socket_unittest.cc @@ -10,7 +10,6 @@ #include "net/base/net_errors.h" #include "net/base/ssl_client_socket.h" #include "net/base/ssl_config_service.h" -#include "net/base/ssl_test_util.h" #include "net/base/tcp_client_socket.h" #include "net/base/test_completion_callback.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,74 +22,41 @@ const net::SSLConfig kDefaultSSLConfig; class SSLClientSocketTest : public PlatformTest { public: SSLClientSocketTest() - : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { - } - - void StartOKServer() { - bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, - server_.kHostName, server_.kOKHTTPSPort, - FilePath(), server_.GetOKCertPath()); - ASSERT_TRUE(success); - } - - void StartMismatchedServer() { - bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, - server_.kMismatchedHostName, server_.kOKHTTPSPort, - FilePath(), server_.GetOKCertPath()); - ASSERT_TRUE(success); - } - - void StartExpiredServer() { - bool success = server_.Start(net::TestServerLauncher::ProtoHTTP, - server_.kHostName, server_.kBadHTTPSPort, - FilePath(), server_.GetExpiredCertPath()); - ASSERT_TRUE(success); + : host_mapper_(new net::RuleBasedHostMapper()), + scoped_host_mapper_(host_mapper_.get()), + socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { + // TODO(darin): kill this exception once we have a way to test out the + // TCPClientSocket class using loopback connections. + host_mapper_->AddRule("bugs.webkit.org", "bugs.webkit.org"); } protected: + scoped_refptr<net::RuleBasedHostMapper> host_mapper_; + net::ScopedHostMapper scoped_host_mapper_; net::ClientSocketFactory* socket_factory_; - net::TestServerLauncher server_; }; //----------------------------------------------------------------------------- -#if defined(OS_MACOSX) -#define MAYBE_Connect DISABLED_Connect -#define MAYBE_ConnectExpired DISABLED_ConnectExpired -#define MAYBE_ConnectMismatched DISABLED_ConnectMismatched -#define MAYBE_Read DISABLED_Read -#define MAYBE_Read_SmallChunks DISABLED_Read_SmallChunks -#define MAYBE_Read_Interrupted DISABLED_Read_Interrupted -#else -#define MAYBE_Connect Connect -#define MAYBE_ConnectExpired ConnectExpired -#define MAYBE_ConnectMismatched ConnectMismatched -#define MAYBE_Read Read -#define MAYBE_Read_SmallChunks Read_SmallChunks -#define MAYBE_Read_Interrupted Read_Interrupted -#endif - -TEST_F(SSLClientSocketTest, MAYBE_Connect) { - StartOKServer(); - +// bug 1354783 +TEST_F(SSLClientSocketTest, DISABLED_Connect) { net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, - &addr, NULL); + std::string hostname = "bugs.webkit.org"; + int rv = resolver.Resolve(hostname, 443, &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kHostName, kDefaultSSLConfig)); + hostname, kDefaultSSLConfig)); EXPECT_FALSE(sock->IsConnected()); rv = sock->Connect(&callback); if (rv != net::OK) { ASSERT_EQ(net::ERR_IO_PENDING, rv); - EXPECT_FALSE(sock->IsConnected()); rv = callback.WaitForResult(); EXPECT_EQ(net::OK, rv); @@ -102,79 +68,14 @@ TEST_F(SSLClientSocketTest, MAYBE_Connect) { EXPECT_FALSE(sock->IsConnected()); } -TEST_F(SSLClientSocketTest, MAYBE_ConnectExpired) { - StartExpiredServer(); - +// bug 1354783 +TEST_F(SSLClientSocketTest, DISABLED_Read) { net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - int rv = resolver.Resolve(server_.kHostName, server_.kBadHTTPSPort, - &addr, NULL); - EXPECT_EQ(net::OK, rv); - - scoped_ptr<net::SSLClientSocket> sock( - socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kHostName, kDefaultSSLConfig)); - - EXPECT_FALSE(sock->IsConnected()); - - rv = sock->Connect(&callback); - if (rv != net::OK) { - ASSERT_EQ(net::ERR_IO_PENDING, rv); - EXPECT_FALSE(sock->IsConnected()); - - rv = callback.WaitForResult(); - EXPECT_EQ(net::ERR_CERT_DATE_INVALID, rv); - } - - EXPECT_TRUE(sock->IsConnected()); -} - -TEST_F(SSLClientSocketTest, MAYBE_ConnectMismatched) { - StartMismatchedServer(); - - net::AddressList addr; - net::HostResolver resolver; - TestCompletionCallback callback; - - int rv = resolver.Resolve(server_.kMismatchedHostName, server_.kOKHTTPSPort, - &addr, NULL); - EXPECT_EQ(net::OK, rv); - - scoped_ptr<net::SSLClientSocket> sock( - socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kMismatchedHostName, kDefaultSSLConfig)); - - EXPECT_FALSE(sock->IsConnected()); - - rv = sock->Connect(&callback); - if (rv != net::ERR_CERT_COMMON_NAME_INVALID) { - ASSERT_EQ(net::ERR_IO_PENDING, rv); - EXPECT_FALSE(sock->IsConnected()); - - rv = callback.WaitForResult(); - EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, rv); - } - - // The Windows code happens to keep the connection - // open now in spite of an error. The designers of - // this API intended to also allow the connection - // to be closed on error, in which case the caller - // should call ReconnectIgnoringLastError, but - // that's currently unimplemented. - EXPECT_TRUE(sock->IsConnected()); -} - -TEST_F(SSLClientSocketTest, MAYBE_Read) { - StartOKServer(); - - net::AddressList addr; - net::HostResolver resolver; - TestCompletionCallback callback; - - int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, - &addr, &callback); + std::string hostname = "bugs.webkit.org"; + int rv = resolver.Resolve(hostname, 443, &addr, &callback); EXPECT_EQ(net::ERR_IO_PENDING, rv); rv = callback.WaitForResult(); @@ -182,8 +83,7 @@ TEST_F(SSLClientSocketTest, MAYBE_Read) { scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kHostName, - kDefaultSSLConfig)); + hostname, kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { @@ -217,20 +117,19 @@ TEST_F(SSLClientSocketTest, MAYBE_Read) { } } -TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) { - StartOKServer(); - +// bug 1354783 +TEST_F(SSLClientSocketTest, DISABLED_Read_SmallChunks) { net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, - &addr, NULL); + std::string hostname = "bugs.webkit.org"; + int rv = resolver.Resolve(hostname, 443, &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kHostName, kDefaultSSLConfig)); + hostname, kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { @@ -263,20 +162,19 @@ TEST_F(SSLClientSocketTest, MAYBE_Read_SmallChunks) { } } -TEST_F(SSLClientSocketTest, MAYBE_Read_Interrupted) { - StartOKServer(); - +// bug 1354783 +TEST_F(SSLClientSocketTest, DISABLED_Read_Interrupted) { net::AddressList addr; net::HostResolver resolver; TestCompletionCallback callback; - int rv = resolver.Resolve(server_.kHostName, server_.kOKHTTPSPort, - &addr, NULL); + std::string hostname = "bugs.webkit.org"; + int rv = resolver.Resolve(hostname, 443, &addr, NULL); EXPECT_EQ(net::OK, rv); scoped_ptr<net::SSLClientSocket> sock( socket_factory_->CreateSSLClientSocket(new net::TCPClientSocket(addr), - server_.kHostName, kDefaultSSLConfig)); + hostname, kDefaultSSLConfig)); rv = sock->Connect(&callback); if (rv != net::OK) { diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc index 46b241f..d22e4fd 100644 --- a/net/base/ssl_test_util.cc +++ b/net/base/ssl_test_util.cc @@ -5,8 +5,6 @@ #include <string> #include <algorithm> -#include "net/base/ssl_test_util.h" - #include "build/build_config.h" #if defined(OS_WIN) @@ -29,15 +27,16 @@ #include "base/file_util.h" #include "base/logging.h" #include "base/path_service.h" -#include "base/platform_thread.h" -#include "base/string_util.h" -#include "net/base/tcp_pinger.h" -#include "net/base/host_resolver.h" -#include "net/base/tcp_client_socket.h" -#include "net/base/test_completion_callback.h" -#include "testing/platform_test.h" -namespace { +#include "net/base/ssl_test_util.h" + +// static +const char SSLTestUtil::kHostName[] = "127.0.0.1"; +const int SSLTestUtil::kOKHTTPSPort = 9443; +const int SSLTestUtil::kBadHTTPSPort = 9666; + +// The issuer name of the cert that should be trusted for the test to work. +const wchar_t SSLTestUtil::kCertIssuerName[] = L"Test CA"; #if defined(OS_LINUX) static CERTCertificate* LoadTemporaryCert(const FilePath& filename) { @@ -68,247 +67,57 @@ static CERTCertificate* LoadTemporaryCert(const FilePath& filename) { rv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust); if (rv != SECSuccess) { - LOG(ERROR) << "Can't change trust for certificate " + LOG(ERROR) << "Can't change trust for certificate " << filename.ToWStringHack(); CERT_DestroyCertificate(cert); return NULL; } - // TODO(dkegel): figure out how to get this to only happen once? + LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack(); return cert; } #endif -} // namespace - -namespace net { - -// static -const char TestServerLauncher::kHostName[] = "127.0.0.1"; -const char TestServerLauncher::kMismatchedHostName[] = "localhost"; -const int TestServerLauncher::kOKHTTPSPort = 9443; -const int TestServerLauncher::kBadHTTPSPort = 9666; - -// The issuer name of the cert that should be trusted for the test to work. -const wchar_t TestServerLauncher::kCertIssuerName[] = L"Test CA"; - -TestServerLauncher::TestServerLauncher() : process_handle_(NULL) -#if defined(OS_LINUX) -, cert_(NULL) -#endif -{ +SSLTestUtil::SSLTestUtil() { PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); - cert_dir_ = cert_dir_.Append(FILE_PATH_LITERAL("net")) - .Append(FILE_PATH_LITERAL("data")) - .Append(FILE_PATH_LITERAL("ssl")) - .Append(FILE_PATH_LITERAL("certificates")); -} - -namespace { - -void AppendToPythonPath(FilePath dir) { - // Do nothing if dir already on path. - -#if defined(OS_WIN) - const wchar_t kPythonPath[] = L"PYTHONPATH"; - // FIXME(dkegel): handle longer PYTHONPATH variables - wchar_t oldpath[4096]; - if (GetEnvironmentVariable(kPythonPath, oldpath, sizeof(oldpath)) == 0) { - SetEnvironmentVariableW(kPythonPath, dir.value().c_str()); - } else if (!wcsstr(oldpath, dir.value().c_str())) { - std::wstring newpath(oldpath); - newpath.append(L":"); - newpath.append(dir.value()); - SetEnvironmentVariableW(kPythonPath, newpath.c_str()); - } -#elif defined(OS_POSIX) - const char kPythonPath[] = "PYTHONPATH"; - const char* oldpath = getenv(kPythonPath); - if (!oldpath) { - setenv(kPythonPath, dir.value().c_str(), 1); - } else if (!strstr(oldpath, dir.value().c_str())) { - std::string newpath(oldpath); - newpath.append(":"); - newpath.append(dir.value()); - setenv(kPythonPath, newpath.c_str(), 1); - } -#endif -} - -} // end namespace - -void TestServerLauncher::SetPythonPath() { - FilePath third_party_dir; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &third_party_dir)); - third_party_dir = third_party_dir.Append(FILE_PATH_LITERAL("third_party")); - - AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("tlslite"))); - AppendToPythonPath(third_party_dir.Append(FILE_PATH_LITERAL("pyftpdlib"))); -} - -bool TestServerLauncher::Start(Protocol protocol, - const std::string& host_name, int port, - const FilePath& document_root, - const FilePath& cert_path) { - if (!TestServerLauncher::CheckCATrusted()) - return false; - - std::string port_str = IntToString(port); - - // Get path to python server script - FilePath testserver_path; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &testserver_path)) - return false; - testserver_path = testserver_path - .Append(FILE_PATH_LITERAL("net")) - .Append(FILE_PATH_LITERAL("tools")) - .Append(FILE_PATH_LITERAL("testserver")) - .Append(FILE_PATH_LITERAL("testserver.py")); - - PathService::Get(base::DIR_SOURCE_ROOT, &document_root_dir_); - document_root_dir_ = document_root_dir_.Append(document_root); + cert_dir_ = cert_dir_.AppendASCII("net"); + cert_dir_ = cert_dir_.AppendASCII("data"); + cert_dir_ = cert_dir_.AppendASCII("ssl"); + cert_dir_ = cert_dir_.AppendASCII("certificates"); #if defined(OS_LINUX) - if (!cert_ && !cert_path.value().empty()) { - cert_ = reinterpret_cast<PrivateCERTCertificate*>( + cert_ = reinterpret_cast<PrivateCERTCertificate*>( LoadTemporaryCert(GetRootCertPath())); - DCHECK(cert_); - } + DCHECK(cert_); #endif - - SetPythonPath(); - -#if defined(OS_WIN) - // Get path to python interpreter - if (!PathService::Get(base::DIR_SOURCE_ROOT, &python_runtime_)) - return false; - python_runtime_ = python_runtime_ - .Append(FILE_PATH_LITERAL("third_party")) - .Append(FILE_PATH_LITERAL("python_24")) - .Append(FILE_PATH_LITERAL("python.exe")); - - std::wstring command_line = - L"\"" + python_runtime_.ToWStringHack() + L"\" " + - L"\"" + testserver_path.ToWStringHack() + - L"\" --port=" + UTF8ToWide(port_str) + - L" --data-dir=\"" + document_root_dir_.ToWStringHack() + L"\""; - if (protocol == ProtoFTP) - command_line.append(L" -f"); - if (!cert_path.value().empty()) { - command_line.append(L" --https=\""); - command_line.append(cert_path.ToWStringHack()); - command_line.append(L"\""); - } - - if (!base::LaunchApp(command_line, false, true, &process_handle_)) { - LOG(ERROR) << "Failed to launch " << command_line; - return false; - } -#elif defined(OS_POSIX) - std::vector<std::string> command_line; - command_line.push_back("python"); - command_line.push_back(WideToUTF8(testserver_path.ToWStringHack())); - command_line.push_back("--port=" + port_str); - command_line.push_back("--data-dir=" + - WideToUTF8(document_root_dir_.ToWStringHack())); - if (protocol == ProtoFTP) - command_line.push_back("-f"); - if (!cert_path.value().empty()) - command_line.push_back("--https=" + WideToUTF8(cert_path.ToWStringHack())); - - base::file_handle_mapping_vector no_mappings; - LOG(INFO) << "Trying to launch " << command_line[0] << " ..."; - if (!base::LaunchApp(command_line, no_mappings, false, &process_handle_)) { - LOG(ERROR) << "Failed to launch " << command_line[0] << " ..."; - return false; - } -#endif - - // Let the server start, then verify that it's up. - // Our server is Python, and takes about 500ms to start - // up the first time, and about 200ms after that. - if (!WaitToStart(host_name, port)) { - LOG(ERROR) << "Failed to connect to server"; - Stop(); - return false; - } - - LOG(INFO) << "Started on port " << port_str; - return true; } -bool TestServerLauncher::WaitToStart(const std::string& host_name, int port) { - // Verify that the webserver is actually started. - // Otherwise tests can fail if they run faster than Python can start. - net::AddressList addr; - net::HostResolver resolver; - int rv = resolver.Resolve(host_name, port, &addr, NULL); - if (rv != net::OK) - return false; - - net::TCPPinger pinger(addr); - rv = pinger.Ping(); - return rv == net::OK; -} - -bool TestServerLauncher::WaitToFinish(int timeout_ms) { - if (!process_handle_) - return true; - - bool ret = base::WaitForSingleProcess(process_handle_, timeout_ms); - if (ret) { - base::CloseProcessHandle(process_handle_); - process_handle_ = NULL; - LOG(INFO) << "Finished."; - } else { - LOG(INFO) << "Timed out."; - } - return ret; -} - -bool TestServerLauncher::Stop() { - if (!process_handle_) - return true; - - bool ret = base::KillProcess(process_handle_, 1, true); - if (ret) { - base::CloseProcessHandle(process_handle_); - process_handle_ = NULL; - LOG(INFO) << "Stopped."; - } else { - LOG(INFO) << "Kill failed?"; - } - - return ret; -} - -TestServerLauncher::~TestServerLauncher() { +SSLTestUtil::~SSLTestUtil() { #if defined(OS_LINUX) if (cert_) CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_)); #endif - Stop(); } -FilePath TestServerLauncher::GetRootCertPath() { +FilePath SSLTestUtil::GetRootCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("root_ca_cert.crt"); return path; } -FilePath TestServerLauncher::GetOKCertPath() { +FilePath SSLTestUtil::GetOKCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("ok_cert.pem"); return path; } -FilePath TestServerLauncher::GetExpiredCertPath() { +FilePath SSLTestUtil::GetExpiredCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("expired_cert.pem"); return path; } -bool TestServerLauncher::CheckCATrusted() { +bool SSLTestUtil::CheckCATrusted() { // TODO(port): Port either this or LoadTemporaryCert to MacOSX. #if defined(OS_WIN) HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT"); @@ -337,6 +146,3 @@ bool TestServerLauncher::CheckCATrusted() { #endif return true; } - -} // namespace net - diff --git a/net/base/ssl_test_util.h b/net/base/ssl_test_util.h index 9340126..9daa4cc 100644 --- a/net/base/ssl_test_util.h +++ b/net/base/ssl_test_util.h @@ -5,106 +5,49 @@ #ifndef NET_BASE_SSL_TEST_UTIL_H_ #define NET_BASE_SSL_TEST_UTIL_H_ -#include <string> +#include "build/build_config.h" #include "base/file_path.h" -#include "base/process_util.h" -#include "base/ref_counted.h" -#include "build/build_config.h" -// TODO(dkegel): share this between net/base and +// TODO(dkegel): share this between net/base and // chrome/browser without putting it in net.lib -namespace net { +class SSLTestUtil { + public: + SSLTestUtil(); -// This object bounds the lifetime of an external python-based HTTP/HTTPS/FTP -// server that can provide various responses useful for testing. -// A few basic convenience methods are provided, but no -// URL handling methods (those belong at a higher layer, e.g. in -// url_request_unittest.h). + ~SSLTestUtil(); -class TestServerLauncher { - public: - TestServerLauncher(); - - virtual ~TestServerLauncher(); - - enum Protocol { - ProtoHTTP, ProtoFTP - }; - - // Start src/net/tools/testserver/testserver.py and - // ask it to serve the given protocol. - // If protocol is HTTP, and cert_path is not empty, serves HTTPS. - // Returns true on success, false if files not found or root cert - // not trusted. - bool Start(Protocol protocol, - const std::string& host_name, int port, - const FilePath& document_root, - const FilePath& cert_path); - - // Stop the server started by Start(). - bool Stop(); - - // If you access the server's Kill url, it will exit by itself - // without a call to Stop(). - // WaitToFinish is handy in that case. - // It returns true if the server exited cleanly. - bool WaitToFinish(int milliseconds); - - // Paths to a good, an expired, and an invalid server certificate - // (use as arguments to Start()). - FilePath GetOKCertPath(); - FilePath GetExpiredCertPath(); + FilePath GetRootCertPath(); - FilePath GetDocumentRootPath() { return document_root_dir_; } + FilePath GetOKCertPath(); - // Issuer name of the root cert that should be trusted for the test to work. - static const wchar_t kCertIssuerName[]; + FilePath GetExpiredCertPath(); // Hostname to use for test server static const char kHostName[]; - // Different hostname to use for test server (that still resolves to same IP) - static const char kMismatchedHostName[]; - // Port to use for test server static const int kOKHTTPSPort; // Port to use for bad test server static const int kBadHTTPSPort; - private: - // Wait a while for the server to start, return whether - // we were able to make a connection to it. - bool WaitToStart(const std::string& host_name, int port); - - // Append to PYTHONPATH so Python can find pyftpdlib and tlslite. - void SetPythonPath(); - - // Path to our test root certificate. - FilePath GetRootCertPath(); + // Issuer name of the cert that should be trusted for the test to work. + static const wchar_t kCertIssuerName[]; // Returns false if our test root certificate is not trusted. bool CheckCATrusted(); - FilePath document_root_dir_; - + private: FilePath cert_dir_; - FilePath python_runtime_; - - base::ProcessHandle process_handle_; - #if defined(OS_LINUX) struct PrivateCERTCertificate; PrivateCERTCertificate *cert_; #endif - DISALLOW_COPY_AND_ASSIGN(TestServerLauncher); + DISALLOW_COPY_AND_ASSIGN(SSLTestUtil); }; -} - -#endif // NET_BASE_SSL_TEST_UTIL_H_ - +#endif // NET_BASE_SSL_TEST_UTIL_H_ |