Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(664)

Side by Side Diff: chromeos/network/onc/onc_utils.cc

Issue 1228543002: Translate ONC ProxySettings <-> Shill ProxyConfig (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698