| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/web_socket_proxy_controller.h" | 5 #include "chrome/browser/chromeos/web_socket_proxy_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include <netinet/in.h> | 9 #include <netinet/in.h> |
| 10 #include <sys/wait.h> | 10 #include <sys/wait.h> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
| 26 #include "content/public/browser/notification_observer.h" | 26 #include "content/public/browser/notification_observer.h" |
| 27 #include "content/public/browser/notification_registrar.h" | 27 #include "content/public/browser/notification_registrar.h" |
| 28 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
| 29 #include "content/public/common/url_constants.h" | 29 #include "content/public/common/url_constants.h" |
| 30 #include "googleurl/src/gurl.h" | 30 #include "googleurl/src/gurl.h" |
| 31 #include "net/base/network_change_notifier.h" | 31 #include "net/base/network_change_notifier.h" |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 const char* kAllowedIds[] = { | |
| 36 "haiffjcadagjlijoggckpgfnoeiflnem", | |
| 37 "gnedhmakppccajfpfiihfcdlnpgomkcf", | |
| 38 "fjcibdnjlbfnbfdjneajpipnlcppleek", | |
| 39 "okddffdblfhhnmhodogpojmfkjmhinfp", | |
| 40 "pnhechapfaindjhompbnflcldabbghjo" // HTerm App (SSH Client) | |
| 41 }; | |
| 42 | |
| 43 class OriginValidator { | |
| 44 public: | |
| 45 OriginValidator() { | |
| 46 chromeos::FillWithExtensionsIdsWithPrivateAccess(&allowed_ids_); | |
| 47 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 48 DCHECK(command_line); | |
| 49 std::string allowed_list = | |
| 50 command_line->GetSwitchValueASCII(switches::kAllowWebSocketProxy); | |
| 51 if (!allowed_list.empty()) { | |
| 52 StringTokenizer t(allowed_list, ","); | |
| 53 while (t.GetNext()) { | |
| 54 // It must be either extension id or origin. | |
| 55 if (Extension::IdIsValid(t.token())) { | |
| 56 allowed_ids_.push_back(t.token()); | |
| 57 } else { | |
| 58 // It is not extension id, check if it is an origin. | |
| 59 GURL origin = GURL(t.token()).GetOrigin(); | |
| 60 if (!origin.is_valid()) { | |
| 61 LOG(ERROR) << "Invalid extension id or origin specified via " | |
| 62 << switches::kAllowWebSocketProxy << " switch"; | |
| 63 break; | |
| 64 } | |
| 65 allowed_origins_.push_back(origin.spec()); | |
| 66 if (origin.SchemeIs(chrome::kExtensionScheme)) | |
| 67 allowed_ids_.push_back(origin.host()); | |
| 68 } | |
| 69 } | |
| 70 } | |
| 71 for (size_t i = 0; i < allowed_ids_.size(); ++i) { | |
| 72 allowed_origins_.push_back(Extension::GetBaseURLFromExtensionId( | |
| 73 allowed_ids_[i]).GetOrigin().spec()); | |
| 74 } | |
| 75 std::sort(allowed_ids_.begin(), allowed_ids_.end()); | |
| 76 allowed_ids_.resize(std::unique( | |
| 77 allowed_ids_.begin(), allowed_ids_.end()) - allowed_ids_.begin()); | |
| 78 std::sort(allowed_origins_.begin(), allowed_origins_.end()); | |
| 79 allowed_origins_.resize(std::unique(allowed_origins_.begin(), | |
| 80 allowed_origins_.end()) - allowed_origins_.begin()); | |
| 81 } | |
| 82 | |
| 83 bool CheckCredentials( | |
| 84 const std::string& extension_id, | |
| 85 const std::string& hostname, | |
| 86 unsigned short port, | |
| 87 chromeos::WebSocketProxyController::ConnectionFlags flags) { | |
| 88 return std::binary_search( | |
| 89 allowed_ids_.begin(), allowed_ids_.end(), extension_id); | |
| 90 } | |
| 91 | |
| 92 const std::vector<std::string>& allowed_origins() { return allowed_origins_; } | |
| 93 | |
| 94 private: | |
| 95 std::vector<std::string> allowed_ids_; | |
| 96 std::vector<std::string> allowed_origins_; | |
| 97 }; | |
| 98 | |
| 99 base::LazyInstance<OriginValidator> g_validator = LAZY_INSTANCE_INITIALIZER; | |
| 100 | |
| 101 class ProxyLifetime | 35 class ProxyLifetime |
| 102 : public net::NetworkChangeNotifier::OnlineStateObserver, | 36 : public net::NetworkChangeNotifier::OnlineStateObserver, |
| 103 public content::NotificationObserver { | 37 public content::NotificationObserver { |
| 104 public: | 38 public: |
| 105 ProxyLifetime() | 39 ProxyLifetime() |
| 106 : delay_ms_(1000), | 40 : delay_ms_(1000), |
| 107 port_(-1), | 41 port_(-1), |
| 108 shutdown_requested_(false), | 42 shutdown_requested_(false), |
| 109 web_socket_proxy_thread_("Chrome_WebSocketproxyThread") { | 43 web_socket_proxy_thread_("Chrome_WebSocketproxyThread") { |
| 110 DLOG(INFO) << "WebSocketProxyController initiation"; | 44 DLOG(INFO) << "WebSocketProxyController initiation"; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 138 // net::NetworkChangeNotifier::OnlineStateObserver implementation. | 72 // net::NetworkChangeNotifier::OnlineStateObserver implementation. |
| 139 virtual void OnOnlineStateChanged(bool online) OVERRIDE { | 73 virtual void OnOnlineStateChanged(bool online) OVERRIDE { |
| 140 DCHECK(chromeos::WebSocketProxyController::IsInitiated()); | 74 DCHECK(chromeos::WebSocketProxyController::IsInitiated()); |
| 141 base::AutoLock alk(lock_); | 75 base::AutoLock alk(lock_); |
| 142 if (server_) | 76 if (server_) |
| 143 server_->OnNetworkChange(); | 77 server_->OnNetworkChange(); |
| 144 } | 78 } |
| 145 | 79 |
| 146 void ProxyCallback() { | 80 void ProxyCallback() { |
| 147 LOG(INFO) << "Attempt to run web socket proxy task"; | 81 LOG(INFO) << "Attempt to run web socket proxy task"; |
| 148 chromeos::WebSocketProxy* server = new chromeos::WebSocketProxy( | 82 chromeos::WebSocketProxy* server = new chromeos::WebSocketProxy(); |
| 149 g_validator.Get().allowed_origins()); | |
| 150 { | 83 { |
| 151 base::AutoLock alk(lock_); | 84 base::AutoLock alk(lock_); |
| 152 if (shutdown_requested_) | 85 if (shutdown_requested_) |
| 153 return; | 86 return; |
| 154 delete server_; | 87 delete server_; |
| 155 server_ = server; | 88 server_ = server; |
| 156 } | 89 } |
| 157 server->Run(); | 90 server->Run(); |
| 158 { | 91 { |
| 159 base::AutoLock alk(lock_); | 92 base::AutoLock alk(lock_); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 186 friend class chromeos::WebSocketProxyController; | 119 friend class chromeos::WebSocketProxyController; |
| 187 base::Thread web_socket_proxy_thread_; | 120 base::Thread web_socket_proxy_thread_; |
| 188 }; | 121 }; |
| 189 | 122 |
| 190 base::LazyInstance<ProxyLifetime> g_proxy_lifetime = LAZY_INSTANCE_INITIALIZER; | 123 base::LazyInstance<ProxyLifetime> g_proxy_lifetime = LAZY_INSTANCE_INITIALIZER; |
| 191 | 124 |
| 192 } // namespace | 125 } // namespace |
| 193 | 126 |
| 194 namespace chromeos { | 127 namespace chromeos { |
| 195 | 128 |
| 196 void FillWithExtensionsIdsWithPrivateAccess(std::vector<std::string>* ids) { | |
| 197 ids->clear(); | |
| 198 for (size_t i = 0; i < arraysize(kAllowedIds); ++i) | |
| 199 ids->push_back(kAllowedIds[i]); | |
| 200 } | |
| 201 | |
| 202 // static | 129 // static |
| 203 void WebSocketProxyController::Initiate() { | 130 void WebSocketProxyController::Initiate() { |
| 204 g_proxy_lifetime.Get(); | 131 g_proxy_lifetime.Get(); |
| 205 } | 132 } |
| 206 | 133 |
| 207 // static | 134 // static |
| 208 bool WebSocketProxyController::IsInitiated() { | 135 bool WebSocketProxyController::IsInitiated() { |
| 209 return !(g_proxy_lifetime == NULL); | 136 return !(g_proxy_lifetime == NULL); |
| 210 } | 137 } |
| 211 | 138 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 224 DLOG(INFO) << "WebSocketProxyController shutdown"; | 151 DLOG(INFO) << "WebSocketProxyController shutdown"; |
| 225 { | 152 { |
| 226 base::AutoLock alk(g_proxy_lifetime.Get().lock_); | 153 base::AutoLock alk(g_proxy_lifetime.Get().lock_); |
| 227 g_proxy_lifetime.Get().shutdown_requested_ = true; | 154 g_proxy_lifetime.Get().shutdown_requested_ = true; |
| 228 if (g_proxy_lifetime.Get().server_) | 155 if (g_proxy_lifetime.Get().server_) |
| 229 g_proxy_lifetime.Get().server_->Shutdown(); | 156 g_proxy_lifetime.Get().server_->Shutdown(); |
| 230 } | 157 } |
| 231 g_proxy_lifetime.Get().web_socket_proxy_thread_.Stop(); | 158 g_proxy_lifetime.Get().web_socket_proxy_thread_.Stop(); |
| 232 } | 159 } |
| 233 | 160 |
| 234 // static | |
| 235 bool WebSocketProxyController::CheckCredentials( | |
| 236 const std::string& extension_id, | |
| 237 const std::string& hostname, | |
| 238 unsigned short port, | |
| 239 ConnectionFlags flags) { | |
| 240 return g_validator.Get().CheckCredentials( | |
| 241 extension_id, hostname, port, flags); | |
| 242 } | |
| 243 | |
| 244 } // namespace chromeos | 161 } // namespace chromeos |
| OLD | NEW |