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

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: Use net/ parsing, update OWNERS 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_config.h"
29 #include "net/proxy/proxy_server.h"
25 30
26 using namespace ::onc; 31 using namespace ::onc;
27 32
28 namespace chromeos { 33 namespace chromeos {
29 namespace onc { 34 namespace onc {
30 35
31 namespace { 36 namespace {
32 37
33 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC"; 38 const char kUnableToDecrypt[] = "Unable to decrypt encrypted ONC";
34 const char kUnableToDecode[] = "Unable to decode encrypted ONC"; 39 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; 736 property_basename = property_key;
732 recommended_property_key = ::onc::kRecommended; 737 recommended_property_key = ::onc::kRecommended;
733 } 738 }
734 739
735 const base::ListValue* recommended_keys = nullptr; 740 const base::ListValue* recommended_keys = nullptr;
736 return (onc->GetList(recommended_property_key, &recommended_keys) && 741 return (onc->GetList(recommended_property_key, &recommended_keys) &&
737 recommended_keys->Find(base::StringValue(property_basename)) != 742 recommended_keys->Find(base::StringValue(property_basename)) !=
738 recommended_keys->end()); 743 recommended_keys->end());
739 } 744 }
740 745
746 namespace {
747
748 const char kSchemeFtp[] = "ftp";
749 const char kSchemeHttp[] = "http";
750 const char kSchemeHttps[] = "https";
751 const char kSchemeSocks[] = "socks";
jochen (gone - plz use gerrit) 2015/07/08 13:20:15 please don't redefine but use the proper constants
stevenjb 2015/07/08 16:26:14 Done.
752
753 net::ProxyServer ConvertOncProxyLocationToHostPort(
754 net::ProxyServer::Scheme default_proxy_scheme,
755 const base::DictionaryValue& onc_proxy_location) {
756 std::string host;
757 onc_proxy_location.GetStringWithoutPathExpansion(::onc::proxy::kHost, &host);
758 // Parse |host| according to the format [<scheme>"://"]<server>[":"<port>].
759 net::ProxyServer proxy_server =
760 net::ProxyServer::FromURI(host, default_proxy_scheme);
761 int port = 0;
762 onc_proxy_location.GetIntegerWithoutPathExpansion(::onc::proxy::kPort, &port);
763
764 // Replace the port parsed from |host| by the provided |port|.
765 return net::ProxyServer(
766 proxy_server.scheme(),
767 net::HostPortPair(proxy_server.host_port_pair().host(),
768 static_cast<uint16>(port)));
769 }
770
771 void AppendProxyServerForScheme(const base::DictionaryValue& onc_manual,
772 const std::string& onc_scheme,
773 std::string* spec) {
774 const base::DictionaryValue* onc_proxy_location = nullptr;
775 if (!onc_manual.GetDictionaryWithoutPathExpansion(onc_scheme,
776 &onc_proxy_location)) {
777 return;
778 }
779
780 net::ProxyServer::Scheme default_proxy_scheme = net::ProxyServer::SCHEME_HTTP;
781 std::string url_scheme;
782 if (onc_scheme == ::onc::proxy::kFtp) {
783 url_scheme = kSchemeFtp;
784 } else if (onc_scheme == ::onc::proxy::kHttp) {
785 url_scheme = kSchemeHttp;
786 } else if (onc_scheme == ::onc::proxy::kHttps) {
787 url_scheme = kSchemeHttps;
788 } else if (onc_scheme == ::onc::proxy::kSocks) {
789 default_proxy_scheme = net::ProxyServer::SCHEME_SOCKS4;
790 url_scheme = kSchemeSocks;
791 } else {
792 NOTREACHED();
793 }
794
795 net::ProxyServer proxy_server = ConvertOncProxyLocationToHostPort(
796 default_proxy_scheme, *onc_proxy_location);
797
798 ProxyConfigDictionary::EncodeAndAppendProxyServer(url_scheme, proxy_server,
799 spec);
800 }
801
802 net::ProxyBypassRules ConvertOncExcludeDomainsToBypassRules(
803 const base::ListValue& onc_exclude_domains) {
804 net::ProxyBypassRules rules;
805 for (base::ListValue::const_iterator it = onc_exclude_domains.begin();
806 it != onc_exclude_domains.end(); ++it) {
807 std::string rule;
808 (*it)->GetAsString(&rule);
809 rules.AddRuleFromString(rule);
810 }
811 return rules;
812 }
813
814 void SetProxyForScheme(const net::ProxyConfig::ProxyRules& proxy_rules,
815 const std::string& scheme,
816 const std::string& onc_scheme,
817 base::DictionaryValue* dict) {
818 const net::ProxyList* proxy_list = nullptr;
819 if (proxy_rules.type == net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY) {
820 proxy_list = &proxy_rules.single_proxies;
821 } else {
822 proxy_list = proxy_rules.MapUrlSchemeToProxyList(scheme);
pneubeck (no reviews) 2015/07/08 06:52:48 according to the documentation, this should not be
stevenjb 2015/07/08 16:26:14 I added an explicit test here.
823 }
824 if (!proxy_list || proxy_list->IsEmpty())
825 return;
826 const net::ProxyServer& server = proxy_list->Get();
827 scoped_ptr<base::DictionaryValue> url_dict(new base::DictionaryValue);
828 std::string host = server.host_port_pair().host();
829 // Special case: Include the scheme for socks5 only.
830 if (server.scheme() == net::ProxyServer::SCHEME_SOCKS5)
pneubeck (no reviews) 2015/07/08 06:52:48 i think you should handle all non-default schemes
stevenjb 2015/07/08 16:26:14 So, there is no "SchemeToString" function, and eff
pneubeck (no reviews) 2015/07/09 07:16:12 sadly... the net/proxy code hides this conversion
stevenjb 2015/07/09 18:24:28 My head is starting to hurt. I am looking at the c
pneubeck (no reviews) 2015/07/10 07:20:42 I'm not sure where you see a contradiction.
eroman 2015/07/13 20:08:38 There are a few factors at play here with regards
831 host = "socks5://" + host;
832 url_dict->SetStringWithoutPathExpansion(::onc::proxy::kHost, host);
833 url_dict->SetIntegerWithoutPathExpansion(::onc::proxy::kPort,
834 server.host_port_pair().port());
835 dict->SetWithoutPathExpansion(onc_scheme, url_dict.release());
836 }
837
838 } // namespace
839
840 scoped_ptr<base::DictionaryValue> ConvertOncProxySettingsToProxyConfig(
841 const base::DictionaryValue& onc_proxy_settings) {
842 std::string type;
843 onc_proxy_settings.GetStringWithoutPathExpansion(::onc::proxy::kType, &type);
844 scoped_ptr<base::DictionaryValue> proxy_dict;
845
846 if (type == ::onc::proxy::kDirect) {
847 proxy_dict.reset(ProxyConfigDictionary::CreateDirect());
848 } else if (type == ::onc::proxy::kWPAD) {
849 proxy_dict.reset(ProxyConfigDictionary::CreateAutoDetect());
850 } else if (type == ::onc::proxy::kPAC) {
851 std::string pac_url;
852 onc_proxy_settings.GetStringWithoutPathExpansion(::onc::proxy::kPAC,
853 &pac_url);
854 GURL url(pac_url);
855 DCHECK(url.is_valid()) << "Invalid URL in ProxySettings.PAC";
856 proxy_dict.reset(ProxyConfigDictionary::CreatePacScript(url.spec(), false));
857 } else if (type == ::onc::proxy::kManual) {
858 const base::DictionaryValue* manual_dict = nullptr;
859 onc_proxy_settings.GetDictionaryWithoutPathExpansion(::onc::proxy::kManual,
860 &manual_dict);
861 std::string manual_spec;
862 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kFtp, &manual_spec);
863 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kHttp, &manual_spec);
864 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kSocks,
865 &manual_spec);
866 AppendProxyServerForScheme(*manual_dict, ::onc::proxy::kHttps,
867 &manual_spec);
868
869 const base::ListValue* exclude_domains = nullptr;
870 net::ProxyBypassRules bypass_rules;
871 if (onc_proxy_settings.GetListWithoutPathExpansion(
872 ::onc::proxy::kExcludeDomains, &exclude_domains)) {
873 bypass_rules.AssignFrom(
874 ConvertOncExcludeDomainsToBypassRules(*exclude_domains));
875 }
876 proxy_dict.reset(ProxyConfigDictionary::CreateFixedServers(
877 manual_spec, bypass_rules.ToString()));
878 } else {
879 NOTREACHED();
880 }
881 return proxy_dict.Pass();
882 }
883
884 scoped_ptr<base::DictionaryValue> ConvertProxyConfigToOncProxySettings(
885 const base::DictionaryValue& proxy_config_value) {
886 // Create a ProxyConfigDictionary from the DictionaryValue.
887 scoped_ptr<ProxyConfigDictionary> proxy_config(
888 new ProxyConfigDictionary(&proxy_config_value));
889
890 // Create the result DictionaryValue and populate it.
891 scoped_ptr<base::DictionaryValue> proxy_settings(new base::DictionaryValue);
892 ProxyPrefs::ProxyMode mode;
893 if (!proxy_config->GetMode(&mode))
894 return nullptr;
895 switch (mode) {
896 case ProxyPrefs::MODE_DIRECT: {
897 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType,
898 ::onc::proxy::kDirect);
899 break;
900 }
901 case ProxyPrefs::MODE_AUTO_DETECT: {
902 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType,
903 ::onc::proxy::kWPAD);
904 break;
905 }
906 case ProxyPrefs::MODE_PAC_SCRIPT: {
907 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kType,
908 ::onc::proxy::kPAC);
909 std::string pac_url;
910 proxy_config->GetPacUrl(&pac_url);
911 proxy_settings->SetStringWithoutPathExpansion(::onc::proxy::kPAC,
912 pac_url);
913 break;
914 }
915 case ProxyPrefs::MODE_FIXED_SERVERS: {
916 proxy_settings->SetString(::onc::proxy::kType, ::onc::proxy::kManual);
917 scoped_ptr<base::DictionaryValue> manual(new base::DictionaryValue);
918 std::string proxy_rules_string;
919 if (proxy_config->GetProxyServer(&proxy_rules_string)) {
920 net::ProxyConfig::ProxyRules proxy_rules;
921 proxy_rules.ParseFromString(proxy_rules_string);
922 SetProxyForScheme(proxy_rules, kSchemeFtp, ::onc::proxy::kFtp,
923 manual.get());
924 SetProxyForScheme(proxy_rules, kSchemeHttp, ::onc::proxy::kHttp,
925 manual.get());
926 SetProxyForScheme(proxy_rules, kSchemeHttps, ::onc::proxy::kHttps,
927 manual.get());
928 SetProxyForScheme(proxy_rules, kSchemeSocks, ::onc::proxy::kSocks,
929 manual.get());
930 }
931 proxy_settings->SetWithoutPathExpansion(::onc::proxy::kManual,
932 manual.release());
933
934 // Convert the 'bypass_list' string into dictionary entries.
935 std::string bypass_rules_string;
936 if (proxy_config->GetBypassList(&bypass_rules_string)) {
937 net::ProxyBypassRules bypass_rules;
938 bypass_rules.ParseFromString(bypass_rules_string);
939 scoped_ptr<base::ListValue> exclude_domains(new base::ListValue);
940 for (const net::ProxyBypassRules::Rule* rule : bypass_rules.rules())
941 exclude_domains->AppendString(rule->ToString());
942 if (!exclude_domains->empty()) {
943 proxy_settings->SetWithoutPathExpansion(::onc::proxy::kExcludeDomains,
944 exclude_domains.release());
945 }
946 }
947 break;
948 }
949 default: {
950 LOG(ERROR) << "Unexpected proxy mode in Shill config: " << mode;
951 return nullptr;
952 }
953 }
954 return proxy_settings.Pass();
955 }
956
741 } // namespace onc 957 } // namespace onc
742 } // namespace chromeos 958 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698