system-proxy: Secure system credentials
Currently System-proxy sends the policy set credentials with every
connect request to a remote proxy. Since less secure authentication
schemes send the credentials in clear to the proxy, an attacker can
easily obtain the policy set credentials.
To protect against a downgrade attack, this CL restricts the auth
schemes for which the policy set credentials can be applied.
BUG=chromium:1132247
TEST=HttpServerProxyConnectJobTest.PolicyAuth*
Change-Id: I17e2d3e38b1560f0fadf347657bd3f4b6e1bae09
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2483831
Tested-by: Andreea-Elena Costinas <acostinas@google.com>
Commit-Queue: Andreea-Elena Costinas <acostinas@google.com>
Reviewed-by: Pavol Marko <pmarko@chromium.org>
diff --git a/system-proxy/server_proxy.cc b/system-proxy/server_proxy.cc
index 13ea7cb..3cef840 100644
--- a/system-proxy/server_proxy.cc
+++ b/system-proxy/server_proxy.cc
@@ -9,11 +9,14 @@
#include <utility>
#include <vector>
+#include <curl/curl.h>
+
#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/callback_helpers.h>
#include <base/posix/eintr_wrapper.h>
#include <base/files/file_util.h>
+#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/threading/thread.h>
#include <base/threading/thread_task_runner_handle.h>
@@ -23,6 +26,7 @@
#include <chromeos/patchpanel/socket_forwarder.h>
#include "bindings/worker_common.pb.h"
+#include "system-proxy/http_util.h"
#include "system-proxy/protobuf_util.h"
#include "system-proxy/proxy_connect_job.h"
@@ -48,6 +52,27 @@
/* encodeSpaceAsPlus= */ false);
}
+// Converts the list of proxy authentication schemes in string format to the
+// curl bit-mask format.
+int64_t GetAuthSchemes(
+ const google::protobuf::RepeatedPtrField<std::string>& auth_schemes) {
+ if (auth_schemes.empty())
+ return CURLAUTH_ANY;
+ // Convert auth schemes to curl format.
+ int64_t curl_scheme = CURLAUTH_NEGOTIATE;
+ // Auth scheme is case insensitive, see
+ // https://tools.ietf.org/html/rfc7235#section-2.1
+ for (auto const& scheme : auth_schemes) {
+ const std::string lower_scheme = base::ToLowerASCII(scheme);
+ if (lower_scheme == "basic")
+ curl_scheme |= CURLAUTH_BASIC;
+ if (lower_scheme == "digest")
+ curl_scheme |= CURLAUTH_DIGEST;
+ if (lower_scheme == "ntlm")
+ curl_scheme |= CURLAUTH_NTLM;
+ }
+ return curl_scheme;
+}
} // namespace
ServerProxy::ServerProxy(base::OnceClosure quit_closure)
@@ -167,6 +192,8 @@
AuthCredentialsProvided(auth_key, std::string());
}
} else {
+ system_credentials_auth_schemes_ = GetAuthSchemes(
+ config.credentials().policy_credentials_auth_schemes());
system_credentials_ = credentials;
}
}
@@ -256,6 +283,7 @@
listening_fd_->Accept((struct sockaddr*)&client_src, &sockaddr_len)) {
auto connect_job = std::make_unique<ProxyConnectJob>(
std::move(client_conn), system_credentials_,
+ system_credentials_auth_schemes_,
base::BindOnce(&ServerProxy::ResolveProxy, base::Unretained(this)),
base::BindRepeating(&ServerProxy::AuthenticationRequired,
base::Unretained(this)),