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..8fde4950c30aa1f6b97dd4cac12a8ba2cf97d2dc 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 { |
Dmitry Polukhin
2011/05/18 06:50:47
Class name is strange to me. What about OriginVali
Denis Lagno
2011/05/18 11:53:32
Done.
|
+ 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) { |
@@ -99,12 +171,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 |