Chromium Code Reviews| 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 "chromeos/network/onc/onc_utils.h" | 5 #include "chromeos/network/onc/onc_utils.h" | 
| 6 | 6 | 
| 7 #include "base/base64.h" | 7 #include "base/base64.h" | 
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" | 
| 9 #include "base/logging.h" | 9 #include "base/logging.h" | 
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" | 
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" | 
| 12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" | 
| 13 #include "base/values.h" | 13 #include "base/values.h" | 
| 14 #include "chromeos/network/network_event_log.h" | 14 #include "chromeos/network/network_event_log.h" | 
| 15 #include "chromeos/network/onc/onc_mapper.h" | 15 #include "chromeos/network/onc/onc_mapper.h" | 
| 16 #include "chromeos/network/onc/onc_signature.h" | 16 #include "chromeos/network/onc/onc_signature.h" | 
| 17 #include "chromeos/network/onc/onc_utils.h" | 17 #include "chromeos/network/onc/onc_utils.h" | 
| 18 #include "chromeos/network/onc/onc_validator.h" | 18 #include "chromeos/network/onc/onc_validator.h" | 
| 19 #include "components/device_event_log/device_event_log.h" | 19 #include "components/device_event_log/device_event_log.h" | 
| 20 #include "components/proxy_config/proxy_config_dictionary.h" | |
| 20 #include "crypto/encryptor.h" | 21 #include "crypto/encryptor.h" | 
| 21 #include "crypto/hmac.h" | 22 #include "crypto/hmac.h" | 
| 22 #include "crypto/symmetric_key.h" | 23 #include "crypto/symmetric_key.h" | 
| 24 #include "net/base/host_port_pair.h" | |
| 23 #include "net/cert/pem_tokenizer.h" | 25 #include "net/cert/pem_tokenizer.h" | 
| 24 #include "net/cert/x509_certificate.h" | 26 #include "net/cert/x509_certificate.h" | 
| 27 #include "net/proxy/proxy_bypass_rules.h" | |
| 28 #include "net/proxy/proxy_server.h" | |
| 25 | 29 | 
| 26 using namespace ::onc; | 30 using namespace ::onc; | 
| 27 | 31 | 
| 28 namespace chromeos { | 32 namespace chromeos { | 
| 29 namespace onc { | 33 namespace onc { | 
| 30 | 34 | 
| 31 namespace { | 35 namespace { | 
| 32 | 36 | 
| 33 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC"; | 37 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC"; | 
| 34 const char kUnableToDecode[] = "Unable to decode encrypted ONC"; | 38 const char kUnableToDecode[] = "Unable to decode encrypted ONC"; | 
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 731 property_basename = property_key; | 735 property_basename = property_key; | 
| 732 recommended_property_key = ::onc::kRecommended; | 736 recommended_property_key = ::onc::kRecommended; | 
| 733 } | 737 } | 
| 734 | 738 | 
| 735 const base::ListValue* recommended_keys = nullptr; | 739 const base::ListValue* recommended_keys = nullptr; | 
| 736 return (onc->GetList(recommended_property_key, &recommended_keys) && | 740 return (onc->GetList(recommended_property_key, &recommended_keys) && | 
| 737 recommended_keys->Find(base::StringValue(property_basename)) != | 741 recommended_keys->Find(base::StringValue(property_basename)) != | 
| 738 recommended_keys->end()); | 742 recommended_keys->end()); | 
| 739 } | 743 } | 
| 740 | 744 | 
| 745 namespace { | |
| 746 | |
| 747 const char kSchemeFtp[] = "ftp"; | |
| 748 const char kSchemeHttp[] = "http"; | |
| 749 const char kSchemeHttps[] = "https"; | |
| 750 const char kSchemeSocks[] = "socks"; | |
| 751 | |
| 752 net::ProxyServer ConvertOncProxyLocationToHostPort( | |
| 753 net::ProxyServer::Scheme default_proxy_scheme, | |
| 754 const base::DictionaryValue& onc_proxy_location) { | |
| 755 std::string host; | |
| 756 onc_proxy_location.GetStringWithoutPathExpansion(::onc::proxy::kHost, &host); | |
| 757 // Parse |host| according to the format [<scheme>"://"]<server>[":"<port>]. | |
| 758 net::ProxyServer proxy_server = | |
| 759 net::ProxyServer::FromURI(host, default_proxy_scheme); | |
| 760 int port = 0; | |
| 761 onc_proxy_location.GetIntegerWithoutPathExpansion(::onc::proxy::kPort, &port); | |
| 762 | |
| 763 // Replace the port parsed from |host| by the provided |port|. | |
| 764 return net::ProxyServer( | |
| 765 proxy_server.scheme(), | |
| 766 net::HostPortPair(proxy_server.host_port_pair().host(), | |
| 767 static_cast<uint16>(port))); | |
| 768 } | |
| 769 | |
| 770 void AppendProxyServerForScheme(const base::DictionaryValue& onc_manual, | |
| 771 const std::string& onc_scheme, | |
| 772 std::string* spec) { | |
| 773 const base::DictionaryValue* onc_proxy_location = nullptr; | |
| 774 if (!onc_manual.GetDictionaryWithoutPathExpansion(onc_scheme, | |
| 775 &onc_proxy_location)) { | |
| 776 return; | |
| 777 } | |
| 778 | |
| 779 net::ProxyServer::Scheme default_proxy_scheme = net::ProxyServer::SCHEME_HTTP; | |
| 780 std::string url_scheme; | |
| 781 if (onc_scheme == ::onc::proxy::kFtp) { | |
| 782 url_scheme = kSchemeFtp; | |
| 783 } else if (onc_scheme == ::onc::proxy::kHttp) { | |
| 784 url_scheme = kSchemeHttp; | |
| 785 } else if (onc_scheme == ::onc::proxy::kHttps) { | |
| 786 url_scheme = kSchemeHttps; | |
| 787 } else if (onc_scheme == ::onc::proxy::kSocks) { | |
| 788 default_proxy_scheme = net::ProxyServer::SCHEME_SOCKS4; | |
| 789 url_scheme = kSchemeSocks; | |
| 790 } else { | |
| 791 NOTREACHED(); | |
| 792 } | |
| 793 | |
| 794 net::ProxyServer proxy_server = ConvertOncProxyLocationToHostPort( | |
| 795 default_proxy_scheme, *onc_proxy_location); | |
| 796 | |
| 797 ProxyConfigDictionary::EncodeAndAppendProxyServer(url_scheme, proxy_server, | |
| 798 spec); | |
| 799 } | |
| 800 | |
| 801 net::ProxyBypassRules ConvertOncExcludeDomainsToBypassRules( | |
| 802 const base::ListValue& onc_exclude_domains) { | |
| 803 net::ProxyBypassRules rules; | |
| 804 for (base::ListValue::const_iterator it = onc_exclude_domains.begin(); | |
| 805 it != onc_exclude_domains.end(); ++it) { | |
| 806 std::string rule; | |
| 807 (*it)->GetAsString(&rule); | |
| 808 rules.AddRuleFromString(rule); | |
| 809 } | |
| 810 return rules; | |
| 811 } | |
| 812 | |
| 813 } // namespace | |
| 814 | |
| 815 scoped_ptr<base::DictionaryValue> ConvertOncProxySettingsToProxyConfig( | |
| 816 const base::DictionaryValue& onc_proxy_settings) { | |
| 817 std::string type; | |
| 818 onc_proxy_settings.GetStringWithoutPathExpansion(::onc::proxy::kType, &type); | |
| 819 scoped_ptr<base::DictionaryValue> proxy_dict; | |
| 820 | |
| 821 if (type == ::onc::proxy::kDirect) { | |
| 822 proxy_dict.reset(ProxyConfigDictionary::CreateDirect()); | |
| 823 } else if (type == ::onc::proxy::kWPAD) { | |
| 824 proxy_dict.reset(ProxyConfigDictionary::CreateAutoDetect()); | |
| 825 } else if (type == ::onc::proxy::kPAC) { | |
| 826 std::string pac_url; | |
| 827 onc_proxy_settings.GetStringWithoutPathExpansion(::onc::proxy::kPAC, | |
| 828 &pac_url); | |
| 829 GURL url(pac_url); | |
| 830 DCHECK(url.is_valid()) | |
| 831 << "PAC field is invalid for this ProxySettings.Type"; | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
i think this error message is wrong.
should instea
 
stevenjb
2015/07/07 18:30:36
Done.
 
 | |
| 832 proxy_dict.reset(ProxyConfigDictionary::CreatePacScript(url.spec(), false)); | |
| 833 } else if (type == ::onc::proxy::kManual) { | |
| 834 const base::DictionaryValue* manual_dict = nullptr; | |
| 835 onc_proxy_settings.GetDictionaryWithoutPathExpansion(::onc::proxy::kManual, | |
| 836 &manual_dict); | |
| 837 std::string manual_spec; | |
| 838 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kFtp, &manual_spec); | |
| 839 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kHttp, &manual_spec); | |
| 840 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kSocks, | |
| 841 &manual_spec); | |
| 842 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kHttps, | |
| 843 &manual_spec); | |
| 844 | |
| 845 const base::ListValue* exclude_domains = nullptr; | |
| 846 net::ProxyBypassRules bypass_rules; | |
| 847 if (onc_proxy_settings.GetListWithoutPathExpansion( | |
| 848 ::onc::proxy::kExcludeDomains, &exclude_domains)) { | |
| 849 bypass_rules.AssignFrom( | |
| 850 ConvertOncExcludeDomainsToBypassRules(*exclude_domains)); | |
| 851 } | |
| 852 proxy_dict.reset(ProxyConfigDictionary::CreateFixedServers( | |
| 853 manual_spec, bypass_rules.ToString())); | |
| 854 } else { | |
| 855 NOTREACHED(); | |
| 856 } | |
| 857 return proxy_dict.Pass(); | |
| 858 } | |
| 859 | |
| 860 scoped_ptr<base::DictionaryValue> ConvertProxyConfigToOncProxySettings( | |
| 861 const base::DictionaryValue& proxy_config_value) { | |
| 862 // Create a ProxyConfigDictionary from the DictionaryValye. | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
Valye -> Value
 
stevenjb
2015/07/07 18:30:36
Done.
 
 | |
| 863 scoped_ptr<ProxyConfigDictionary> proxy_config( | |
| 864 new ProxyConfigDictionary(&proxy_config_value)); | |
| 865 | |
| 866 // Create the result DictionaryValue and populate it. | |
| 867 scoped_ptr<base::DictionaryValue> proxy_settings(new base::DictionaryValue); | |
| 868 ProxyPrefs::ProxyMode mode; | |
| 869 if (!proxy_config->GetMode(&mode)) | |
| 870 return nullptr; | |
| 871 switch (mode) { | |
| 872 case ProxyPrefs::MODE_DIRECT: { | |
| 873 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType, | |
| 874 ::onc::proxy::kDirect); | |
| 875 break; | |
| 876 } | |
| 877 case ProxyPrefs::MODE_AUTO_DETECT: { | |
| 878 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType, | |
| 879 ::onc::proxy::kWPAD); | |
| 880 break; | |
| 881 } | |
| 882 case ProxyPrefs::MODE_PAC_SCRIPT: { | |
| 883 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType, | |
| 884 ::onc::proxy::kPAC); | |
| 885 std::string pac_url; | |
| 886 proxy_config->GetPacUrl(&pac_url); | |
| 887 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kPAC, | |
| 888 pac_url); | |
| 889 break; | |
| 890 } | |
| 891 case ProxyPrefs::MODE_FIXED_SERVERS: { | |
| 892 proxy_settings->SetString(::onc::proxy::kType, ::onc::proxy::kManual); | |
| 893 // Convert the 'server' string into dictionary entries. | |
| 894 std::string servers_string; | |
| 895 proxy_config->GetProxyServer(&servers_string); | |
| 896 std::vector<std::string> servers; | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
instead of the following parsing you could instead
 
stevenjb
2015/07/07 18:30:36
I wasn't aware of ProxyRules, I think that is a be
 
 | |
| 897 Tokenize(servers_string, ";", &servers); | |
| 898 if (!servers.empty()) { | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:48
according to the ONC spec the Manual subdictionary
 
stevenjb
2015/07/07 18:30:36
Check with who? :P I will always add it.
 
 | |
| 899 scoped_ptr<base::DictionaryValue> manual(new base::DictionaryValue); | |
| 900 for (std::string server : servers) { | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
const&
 
stevenjb
2015/07/07 18:30:36
Acknowledged.
 
 | |
| 901 size_t index = server.find_first_of('='); | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
optional nit: 'const size_t'
 
stevenjb
2015/07/07 18:30:36
Acknowledged.
 
 | |
| 902 std::string scheme = server.substr(0, index); | |
| 903 std::string url = server.substr(index + 1); | |
| 904 std::string onc_scheme; | |
| 905 std::string default_prefix = scheme; | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
the default prefix for everything but Socks is  ne
 
stevenjb
2015/07/07 18:30:36
Acknowledged.
 
 | |
| 906 if (scheme == kSchemeFtp) { | |
| 907 onc_scheme = ::onc::proxy::kFtp; | |
| 908 } else if (scheme == kSchemeHttp) { | |
| 909 onc_scheme = ::onc::proxy::kHttp; | |
| 910 } else if (scheme == kSchemeHttps) { | |
| 911 onc_scheme = ::onc::proxy::kHttps; | |
| 912 } else if (scheme == kSchemeSocks) { | |
| 913 onc_scheme = ::onc::proxy::kSocks; | |
| 914 default_prefix = "socks4"; | |
| 915 } | |
| 916 if (!onc_scheme.empty()) { | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:48
onc_scheme.empty() seems to be a severe error that
 
stevenjb
2015/07/07 18:30:36
Acknowledged.
 
 | |
| 917 // If the prefix matches the default prefix for the scheme, skip it. | |
| 918 default_prefix += "://"; | |
| 919 if (url.substr(0, default_prefix.length()) == default_prefix) | |
| 920 url = url.substr(default_prefix.length()); | |
| 921 index = url.find_last_of(':'); | |
| 922 std::string host = url.substr(0, index); | |
| 923 std::string port_str = url.substr(index + 1); | |
| 924 int port = 0; | |
| 925 base::StringToInt(port_str, &port); | |
| 926 scoped_ptr<base::DictionaryValue> url_dict( | |
| 927 new base::DictionaryValue); | |
| 928 url_dict->SetStringWithoutPathExpansion(::onc::proxy::kHost, host); | |
| 929 url_dict->SetIntegerWithoutPathExpansion(::onc::proxy::kPort, port); | |
| 930 manual->SetWithoutPathExpansion(onc_scheme, url_dict.release()); | |
| 931 } | |
| 932 } | |
| 933 proxy_settings->SetWithoutPathExpansion(::onc::proxy::kManual, | |
| 934 manual.release()); | |
| 935 } | |
| 936 | |
| 937 // Convert the 'bypass_list' string into dictionary entries. | |
| 938 std::string bypass_list_string; | |
| 939 proxy_config->GetBypassList(&bypass_list_string); | |
| 940 std::vector<std::string> bypass_list; | |
| 941 Tokenize(bypass_list_string, ";", &bypass_list); | |
| 942 scoped_ptr<base::ListValue> exclude_domains(new base::ListValue); | |
| 943 for (std::string entry : bypass_list) | |
| 
 
pneubeck (no reviews)
2015/07/07 10:18:47
const&
 
stevenjb
2015/07/07 18:30:36
Using ProxyBypassRules now.
 
 | |
| 944 exclude_domains->AppendString(entry); | |
| 945 if (!exclude_domains->empty()) { | |
| 946 proxy_settings->SetWithoutPathExpansion(::onc::proxy::kExcludeDomains, | |
| 947 exclude_domains.release()); | |
| 948 } | |
| 949 break; | |
| 950 } | |
| 951 default: { | |
| 952 LOG(ERROR) << "Unexpected proxy mode in Shill config: " << mode; | |
| 953 return nullptr; | |
| 954 } | |
| 955 } | |
| 956 return proxy_settings.Pass(); | |
| 957 } | |
| 958 | |
| 741 } // namespace onc | 959 } // namespace onc | 
| 742 } // namespace chromeos | 960 } // namespace chromeos | 
| OLD | NEW |