onc_utils.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
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 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/net/onc_utils.h" 6 7#include "base/logging.h" 8#include "base/values.h" 9#include "chrome/browser/chromeos/login/user.h" 10#include "chrome/browser/chromeos/login/user_manager.h" 11#include "chrome/browser/chromeos/ui_proxy_config.h" 12#include "chrome/browser/prefs/proxy_config_dictionary.h" 13#include "chromeos/network/onc/onc_utils.h" 14#include "net/base/host_port_pair.h" 15#include "net/proxy/proxy_bypass_rules.h" 16#include "net/proxy/proxy_server.h" 17#include "url/gurl.h" 18 19namespace chromeos { 20namespace onc { 21 22namespace { 23 24net::ProxyServer ConvertOncProxyLocationToHostPort( 25 net::ProxyServer::Scheme default_proxy_scheme, 26 const base::DictionaryValue& onc_proxy_location) { 27 std::string host; 28 onc_proxy_location.GetStringWithoutPathExpansion(onc::proxy::kHost, &host); 29 // Parse |host| according to the format [<scheme>"://"]<server>[":"<port>]. 30 net::ProxyServer proxy_server = 31 net::ProxyServer::FromURI(host, default_proxy_scheme); 32 int port = 0; 33 onc_proxy_location.GetIntegerWithoutPathExpansion(onc::proxy::kPort, &port); 34 35 // Replace the port parsed from |host| by the provided |port|. 36 return net::ProxyServer( 37 proxy_server.scheme(), 38 net::HostPortPair(proxy_server.host_port_pair().host(), 39 static_cast<uint16>(port))); 40} 41 42void AppendProxyServerForScheme( 43 const base::DictionaryValue& onc_manual, 44 const std::string& onc_scheme, 45 std::string* spec) { 46 const base::DictionaryValue* onc_proxy_location = NULL; 47 if (!onc_manual.GetDictionaryWithoutPathExpansion(onc_scheme, 48 &onc_proxy_location)) { 49 return; 50 } 51 52 net::ProxyServer::Scheme default_proxy_scheme = net::ProxyServer::SCHEME_HTTP; 53 std::string url_scheme; 54 if (onc_scheme == proxy::kFtp) { 55 url_scheme = "ftp"; 56 } else if (onc_scheme == proxy::kHttp) { 57 url_scheme = "http"; 58 } else if (onc_scheme == proxy::kHttps) { 59 url_scheme = "https"; 60 } else if (onc_scheme == proxy::kSocks) { 61 default_proxy_scheme = net::ProxyServer::SCHEME_SOCKS4; 62 url_scheme = "socks"; 63 } else { 64 NOTREACHED(); 65 } 66 67 net::ProxyServer proxy_server = ConvertOncProxyLocationToHostPort( 68 default_proxy_scheme, *onc_proxy_location); 69 70 UIProxyConfig::EncodeAndAppendProxyServer(url_scheme, proxy_server, spec); 71} 72 73net::ProxyBypassRules ConvertOncExcludeDomainsToBypassRules( 74 const base::ListValue& onc_exclude_domains) { 75 net::ProxyBypassRules rules; 76 for (base::ListValue::const_iterator it = onc_exclude_domains.begin(); 77 it != onc_exclude_domains.end(); ++it) { 78 std::string rule; 79 (*it)->GetAsString(&rule); 80 rules.AddRuleFromString(rule); 81 } 82 return rules; 83} 84 85} // namespace 86 87scoped_ptr<base::DictionaryValue> ConvertOncProxySettingsToProxyConfig( 88 const base::DictionaryValue& onc_proxy_settings) { 89 std::string type; 90 onc_proxy_settings.GetStringWithoutPathExpansion(proxy::kType, &type); 91 scoped_ptr<DictionaryValue> proxy_dict; 92 93 if (type == proxy::kDirect) { 94 proxy_dict.reset(ProxyConfigDictionary::CreateDirect()); 95 } else if (type == proxy::kWPAD) { 96 proxy_dict.reset(ProxyConfigDictionary::CreateAutoDetect()); 97 } else if (type == proxy::kPAC) { 98 std::string pac_url; 99 onc_proxy_settings.GetStringWithoutPathExpansion(proxy::kPAC, &pac_url); 100 GURL url(pac_url); 101 DCHECK(url.is_valid()) 102 << "PAC field is invalid for this ProxySettings.Type"; 103 proxy_dict.reset(ProxyConfigDictionary::CreatePacScript(url.spec(), 104 false)); 105 } else if (type == proxy::kManual) { 106 const base::DictionaryValue* manual_dict = NULL; 107 onc_proxy_settings.GetDictionaryWithoutPathExpansion(proxy::kManual, 108 &manual_dict); 109 std::string manual_spec; 110 AppendProxyServerForScheme(*manual_dict, proxy::kFtp, &manual_spec); 111 AppendProxyServerForScheme(*manual_dict, proxy::kHttp, &manual_spec); 112 AppendProxyServerForScheme(*manual_dict, proxy::kSocks, &manual_spec); 113 AppendProxyServerForScheme(*manual_dict, proxy::kHttps, &manual_spec); 114 115 const base::ListValue* exclude_domains = NULL; 116 net::ProxyBypassRules bypass_rules; 117 if (onc_proxy_settings.GetListWithoutPathExpansion(proxy::kExcludeDomains, 118 &exclude_domains)) { 119 bypass_rules.AssignFrom( 120 ConvertOncExcludeDomainsToBypassRules(*exclude_domains)); 121 } 122 proxy_dict.reset(ProxyConfigDictionary::CreateFixedServers( 123 manual_spec, bypass_rules.ToString())); 124 } else { 125 NOTREACHED(); 126 } 127 return proxy_dict.Pass(); 128} 129 130namespace { 131 132// This class defines which string placeholders of ONC are replaced by which 133// user attribute. 134class UserStringSubstitution : public chromeos::onc::StringSubstitution { 135 public: 136 explicit UserStringSubstitution(const chromeos::User* user) : user_(user) {} 137 virtual ~UserStringSubstitution() {} 138 139 virtual bool GetSubstitute(const std::string& placeholder, 140 std::string* substitute) const OVERRIDE { 141 if (placeholder == chromeos::onc::substitutes::kLoginIDField) 142 *substitute = user_->GetAccountName(false); 143 else if (placeholder == chromeos::onc::substitutes::kEmailField) 144 *substitute = user_->email(); 145 else 146 return false; 147 return true; 148 } 149 150 private: 151 const chromeos::User* user_; 152 153 DISALLOW_COPY_AND_ASSIGN(UserStringSubstitution); 154}; 155 156const chromeos::User* GetLoggedInUserByHash(const std::string& userhash) { 157 const chromeos::UserList& users = 158 chromeos::UserManager::Get()->GetLoggedInUsers(); 159 for (chromeos::UserList::const_iterator it = users.begin(); it != users.end(); 160 ++it) { 161 if ((*it)->username_hash() == userhash) 162 return *it; 163 } 164 return NULL; 165} 166 167} // namespace 168 169void ExpandStringPlaceholdersInNetworksForUser( 170 const std::string& hashed_username, 171 base::ListValue* network_configs) { 172 const chromeos::User* user = GetLoggedInUserByHash(hashed_username); 173 DCHECK(user); 174 UserStringSubstitution substitution(user); 175 chromeos::onc::ExpandStringsInNetworks(substitution, network_configs); 176} 177 178} // namespace onc 179} // namespace chromeos 180