| Index: chrome/browser/chromeos/web_socket_proxy_controller.cc
|
| diff --git a/chrome/browser/chromeos/web_socket_proxy_controller.cc b/chrome/browser/chromeos/web_socket_proxy_controller.cc
|
| index 33870714b401c1107bd71df9ef20eaef29da9d0c..49db96a9f3025293fb2a4d318036be1c24a10932 100644
|
| --- a/chrome/browser/chromeos/web_socket_proxy_controller.cc
|
| +++ b/chrome/browser/chromeos/web_socket_proxy_controller.cc
|
| @@ -4,19 +4,95 @@
|
|
|
| #include "web_socket_proxy_controller.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #include <netinet/in.h>
|
| #include <sys/wait.h>
|
| #include <unistd.h>
|
|
|
| +#include "base/command_line.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/message_loop.h"
|
| +#include "base/string_tokenizer.h"
|
| #include "base/threading/thread.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/chromeos/web_socket_proxy.h"
|
| +#include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/extensions/extension.h"
|
| #include "content/browser/browser_thread.h"
|
| +#include "content/common/url_constants.h"
|
| +#include "googleurl/src/gurl.h"
|
|
|
| namespace {
|
|
|
| +const char* kWebAppId = "haiffjcadagjlijoggckpgfnoeiflnem";
|
| +
|
| +const char* kAllowedIds[] = {
|
| + kWebAppId
|
| +};
|
| +
|
| +class Clearance {
|
| + public:
|
| + Clearance()
|
| + : allowed_ids_(kAllowedIds, kAllowedIds + arraysize(kAllowedIds)) {
|
| + CommandLine* command_line = CommandLine::ForCurrentProcess();
|
| + DCHECK(command_line);
|
| + std::string allowed_list =
|
| + command_line->GetSwitchValueASCII(switches::kAllowWebSocketProxy);
|
| + if (!allowed_list.empty()) {
|
| + StringTokenizer t(allowed_list, ",");
|
| + while (t.GetNext()) {
|
| + // It must be either extension id or origin.
|
| + if (Extension::IdIsValid(t.token())) {
|
| + allowed_ids_.push_back(t.token());
|
| + } else {
|
| + // It is not extension id, check if it is an origin.
|
| + GURL origin = GURL(t.token()).GetOrigin();
|
| + if (!origin.is_valid()) {
|
| + LOG(ERROR) << "Invalid extension id or origin specified via "
|
| + << switches::kAllowWebSocketProxy << " switch";
|
| + break;
|
| + }
|
| + allowed_origins_.push_back(origin.spec());
|
| + if (origin.SchemeIs(chrome::kExtensionScheme))
|
| + allowed_ids_.push_back(origin.host());
|
| + }
|
| + }
|
| + }
|
| + for (size_t i = 0; i < allowed_ids_.size(); ++i) {
|
| + allowed_origins_.push_back(Extension::GetBaseURLFromExtensionId(
|
| + allowed_ids_[i]).GetOrigin().spec());
|
| + }
|
| + std::sort(allowed_ids_.begin(), allowed_ids_.end());
|
| + allowed_ids_.resize(std::unique(
|
| + allowed_ids_.begin(), allowed_ids_.end()) - allowed_ids_.begin());
|
| + std::sort(allowed_origins_.begin(), allowed_origins_.end());
|
| + allowed_origins_.resize(std::unique(allowed_origins_.begin(),
|
| + allowed_origins_.end()) - allowed_origins_.begin());
|
| + }
|
| +
|
| + bool CheckCredentials(
|
| + const std::string& extension_id,
|
| + const std::string& hostname,
|
| + unsigned short port,
|
| + chromeos::WebSocketProxyController::ConnectionFlags flags) {
|
| + if (flags & chromeos::WebSocketProxyController::TLS_OVER_TCP) {
|
| + NOTIMPLEMENTED();
|
| + return false;
|
| + }
|
| + return std::binary_search(
|
| + allowed_ids_.begin(), allowed_ids_.end(), extension_id);
|
| + }
|
| +
|
| + const std::vector<std::string>& allowed_origins() { return allowed_origins_; }
|
| +
|
| + private:
|
| + std::vector<std::string> allowed_ids_;
|
| + std::vector<std::string> allowed_origins_;
|
| +};
|
| +
|
| +base::LazyInstance<Clearance> g_clearance(base::LINKER_INITIALIZED);
|
| +
|
| class ProxyTask : public Task {
|
| virtual void Run() OVERRIDE;
|
| };
|
| @@ -34,7 +110,7 @@ struct ProxyLifetime {
|
|
|
| volatile bool shutdown_requested;
|
|
|
| - base::Lock shutdown_lock;
|
| + base::Lock lock;
|
| };
|
|
|
| base::LazyInstance<ProxyLifetime> g_proxy_lifetime(base::LINKER_INITIALIZED);
|
| @@ -43,11 +119,6 @@ void ProxyTask::Run() {
|
| LOG(INFO) << "Attempt to run web socket proxy task";
|
| const int kPort = 10101;
|
|
|
| - // Configure allowed origins. Empty vector allows any origin.
|
| - std::vector<std::string> allowed_origins;
|
| - allowed_origins.push_back(
|
| - "chrome-extension://haiffjcadagjlijoggckpgfnoeiflnem");
|
| -
|
| struct sockaddr_in sa;
|
| memset(&sa, 0, sizeof(sa));
|
| sa.sin_family = AF_INET;
|
| @@ -55,9 +126,10 @@ void ProxyTask::Run() {
|
| sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
|
| chromeos::WebSocketProxy* server = new chromeos::WebSocketProxy(
|
| - allowed_origins, reinterpret_cast<sockaddr*>(&sa), sizeof(sa));
|
| + g_clearance.Get().allowed_origins(),
|
| + reinterpret_cast<sockaddr*>(&sa), sizeof(sa));
|
| {
|
| - base::AutoLock alk(g_proxy_lifetime.Get().shutdown_lock);
|
| + base::AutoLock alk(g_proxy_lifetime.Get().lock);
|
| if (g_proxy_lifetime.Get().shutdown_requested)
|
| return;
|
| delete g_proxy_lifetime.Get().server;
|
| @@ -65,7 +137,7 @@ void ProxyTask::Run() {
|
| }
|
| server->Run();
|
| {
|
| - base::AutoLock alk(g_proxy_lifetime.Get().shutdown_lock);
|
| + base::AutoLock alk(g_proxy_lifetime.Get().lock);
|
| delete server;
|
| g_proxy_lifetime.Get().server = NULL;
|
| if (!g_proxy_lifetime.Get().shutdown_requested) {
|
| @@ -80,10 +152,17 @@ void ProxyTask::Run() {
|
| }
|
| }
|
|
|
| +bool operator==(const char* lhs, const std::string& rhs) {
|
| + return rhs == lhs;
|
| +}
|
| +
|
| } // namespace
|
|
|
| namespace chromeos {
|
|
|
| +const char* kAllowedOrigins[] = {
|
| + "chrome-extension://haiffjcadagjlijoggckpgfnoeiflnem"
|
| +};
|
| // static
|
| void WebSocketProxyController::Initiate() {
|
| LOG(INFO) << "WebSocketProxyController initiation";
|
| @@ -99,12 +178,22 @@ bool WebSocketProxyController::IsInitiated() {
|
| void WebSocketProxyController::Shutdown() {
|
| if (IsInitiated()) {
|
| LOG(INFO) << "WebSocketProxyController shutdown";
|
| - base::AutoLock alk(g_proxy_lifetime.Get().shutdown_lock);
|
| + base::AutoLock alk(g_proxy_lifetime.Get().lock);
|
| g_proxy_lifetime.Get().shutdown_requested = true;
|
| if (g_proxy_lifetime.Get().server)
|
| g_proxy_lifetime.Get().server->Shutdown();
|
| }
|
| }
|
|
|
| +// static
|
| +bool WebSocketProxyController::CheckCredentials(
|
| + const std::string& extension_id,
|
| + const std::string& hostname,
|
| + unsigned short port,
|
| + ConnectionFlags flags) {
|
| + return g_clearance.Get().CheckCredentials(
|
| + extension_id, hostname, port, flags);
|
| +}
|
| +
|
| } // namespace chromeos
|
|
|
|
|