diff options
author | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-14 05:26:10 +0000 |
---|---|---|
committer | dkegel@google.com <dkegel@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-14 05:26:10 +0000 |
commit | ee287e40bb740d7238717a97b5f635ae3e68c47a (patch) | |
tree | 4515656a0a870939dbcf6892b48baa02c99c26ca /net/base/ssl_test_util.cc | |
parent | 0afe827a49501c6801c3c9efbbdb1f64aa010beb (diff) | |
download | chromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.zip chromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.tar.gz chromium_src-ee287e40bb740d7238717a97b5f635ae3e68c47a.tar.bz2 |
ssl_client_socket_unittest.cc: launch local server with TestServerLauncher
rather than use bugs.webkit.org, fixes TODO(darin)
Add tests with bad server certs
ssl_client_socket_nss.cc: fix bugs revealed by new tests
tcp_pinger.cc: helper class to do synchronous connect from tests.
Has to work inside ui tests where one can't use TestCompletionCallback.
ssl_test_util: renamed class TestServerLauncher, added Start/Stop methods.
Make part of net.lib to work around link error in test_shell_tests.
url_request_unittest.h: use TestServerLauncher to manage server.
SSL client tests disabled for now on Mac.
BUG=7114
Review URL: http://codereview.chromium.org/16207
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9823 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/ssl_test_util.cc')
-rw-r--r-- | net/base/ssl_test_util.cc | 226 |
1 files changed, 202 insertions, 24 deletions
diff --git a/net/base/ssl_test_util.cc b/net/base/ssl_test_util.cc index d22e4fd..a6ad137 100644 --- a/net/base/ssl_test_util.cc +++ b/net/base/ssl_test_util.cc @@ -5,6 +5,8 @@ #include <string> #include <algorithm> +#include "net/base/ssl_test_util.h" + #include "build/build_config.h" #if defined(OS_WIN) @@ -27,16 +29,15 @@ #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" -#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"; +namespace { #if defined(OS_LINUX) static CERTCertificate* LoadTemporaryCert(const FilePath& filename) { @@ -67,57 +68,231 @@ 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; } - LOG(INFO) << "Loaded temporary certificate " << filename.ToWStringHack(); + // TODO(dkegel): figure out how to get this to only happen once? return cert; } #endif -SSLTestUtil::SSLTestUtil() { - PathService::Get(base::DIR_SOURCE_ROOT, &cert_dir_); - cert_dir_ = cert_dir_.AppendASCII("net"); - cert_dir_ = cert_dir_.AppendASCII("data"); - cert_dir_ = cert_dir_.AppendASCII("ssl"); - cert_dir_ = cert_dir_.AppendASCII("certificates"); +} // 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 +{ + PathService::Get(base::DIR_SOURCE_ROOT, &data_dir_); + data_dir_ = data_dir_.Append(FILE_PATH_LITERAL("net")) + .Append(FILE_PATH_LITERAL("data")) + .Append(FILE_PATH_LITERAL("ssl")); + cert_dir_ = data_dir_.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")); + + FilePath test_data_directory; + PathService::Get(base::DIR_SOURCE_ROOT, &test_data_directory); + test_data_directory = test_data_directory.Append(document_root); #if defined(OS_LINUX) - cert_ = reinterpret_cast<PrivateCERTCertificate*>( + if (!cert_ && !cert_path.value().empty()) { + 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=\"" + test_data_directory.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(test_data_directory.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 (!Wait(host_name, port)) { + LOG(ERROR) << "Failed to connect to server"; + Stop(); + return false; + } + + LOG(INFO) << "Started on port " << port_str; + return true; +} + +bool TestServerLauncher::Wait(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; +} + +void TestServerLauncher::Stop() { + if (!process_handle_) + return; + + base::KillProcess(process_handle_, 1, true); + +#if defined(OS_WIN) + CloseHandle(process_handle_); +#endif + + process_handle_ = NULL; + LOG(INFO) << "Stopped."; } -SSLTestUtil::~SSLTestUtil() { +TestServerLauncher::~TestServerLauncher() { #if defined(OS_LINUX) if (cert_) CERT_DestroyCertificate(reinterpret_cast<CERTCertificate*>(cert_)); #endif + Stop(); } -FilePath SSLTestUtil::GetRootCertPath() { +FilePath TestServerLauncher::GetRootCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("root_ca_cert.crt"); return path; } -FilePath SSLTestUtil::GetOKCertPath() { +FilePath TestServerLauncher::GetOKCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("ok_cert.pem"); return path; } -FilePath SSLTestUtil::GetExpiredCertPath() { +FilePath TestServerLauncher::GetExpiredCertPath() { FilePath path(cert_dir_); path = path.AppendASCII("expired_cert.pem"); return path; } -bool SSLTestUtil::CheckCATrusted() { +bool TestServerLauncher::CheckCATrusted() { // TODO(port): Port either this or LoadTemporaryCert to MacOSX. #if defined(OS_WIN) HCERTSTORE cert_store = CertOpenSystemStore(NULL, L"ROOT"); @@ -146,3 +321,6 @@ bool SSLTestUtil::CheckCATrusted() { #endif return true; } + +} // namespace net + |