onc_translation_tables.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// Use of this source code is governed by a BSD-style license that can be
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o// found in the LICENSE file.
4f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
5efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o#include "chromeos/network/onc/onc_translation_tables.h"
6543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o#include <cstddef>
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o
9543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o#include "base/logging.h"
10f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o#include "components/onc/onc_constants.h"
11f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o#include "third_party/cros_system_api/dbus/service_constants.h"
12f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
13f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'onamespace chromeos {
14f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'onamespace onc {
15f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
16f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// CertificatePattern is converted with function CreateUIData(...) to UIData
17f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// stored in Shill.
18f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o//
19f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// Proxy settings are converted to Shill by function
20f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o// ConvertOncProxySettingsToProxyConfig(...).
21f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
22f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'onamespace {
23f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
24f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'oconst FieldTranslationEntry eap_fields[] = {
25f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kAnonymousIdentity, shill::kEapAnonymousIdentityProperty},
26f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kIdentity, shill::kEapIdentityProperty},
27f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // This field is converted during translation, see onc_translator_*.
28f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // { ::onc::eap::kInner, shill::kEapPhase2AuthProperty },
29f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
30f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // This field is converted during translation, see onc_translator_*.
31f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // { ::onc::eap::kOuter, shill::kEapMethodProperty },
32f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kPassword, shill::kEapPasswordProperty},
33f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kSaveCredentials, shill::kSaveCredentialsProperty},
34f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kServerCAPEMs, shill::kEapCaCertPemProperty},
35f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::eap::kUseSystemCAs, shill::kEapUseSystemCasProperty},
36f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    {NULL}};
37f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
38f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'oconst FieldTranslationEntry ipsec_fields[] = {
39f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // Ignored by Shill, not necessary to synchronize.
40f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // { ::onc::ipsec::kAuthenticationType, shill::kL2tpIpsecAuthenticationType
41f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // },
42f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::ipsec::kGroup, shill::kL2tpIpsecTunnelGroupProperty},
43f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // Ignored by Shill, not necessary to synchronize.
44f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // { ::onc::ipsec::kIKEVersion, shill::kL2tpIpsecIkeVersion },
45f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::ipsec::kPSK, shill::kL2tpIpsecPskProperty},
46f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
47f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::ipsec::kServerCAPEMs, shill::kL2tpIpsecCaCertPemProperty},
48f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    {NULL}};
49f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
50f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'oconst FieldTranslationEntry xauth_fields[] = {
51f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::vpn::kPassword, shill::kL2tpIpsecXauthPasswordProperty},
52f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::vpn::kUsername, shill::kL2tpIpsecXauthUserProperty},
53f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    {NULL}};
54f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
55f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'oconst FieldTranslationEntry l2tp_fields[] = {
56f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::vpn::kPassword, shill::kL2tpIpsecPasswordProperty},
57f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // We don't synchronize l2tp's SaveCredentials field for now, as Shill
58f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // doesn't
59f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // support separate settings for ipsec and l2tp.
60f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    // { ::onc::vpn::kSaveCredentials, &kBoolSignature },
61f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::vpn::kUsername, shill::kL2tpIpsecUserProperty}, {NULL}};
62f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o
63f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'oconst FieldTranslationEntry openvpn_fields[] = {
64f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kAuth, shill::kOpenVPNAuthProperty},
65f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kAuthNoCache, shill::kOpenVPNAuthNoCacheProperty},
66f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kAuthRetry, shill::kOpenVPNAuthRetryProperty},
67f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kCipher, shill::kOpenVPNCipherProperty},
68f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kCompLZO, shill::kOpenVPNCompLZOProperty},
69f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kCompNoAdapt, shill::kOpenVPNCompNoAdaptProperty},
70f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o    { ::onc::openvpn::kIgnoreDefaultRoute,
71f61fc0b5d98ef2455252d596e7b20131526d6762Theodore Ts'o      shill::kOpenVPNIgnoreDefaultRouteProperty},
72    { ::onc::openvpn::kKeyDirection, shill::kOpenVPNKeyDirectionProperty},
73    { ::onc::openvpn::kNsCertType, shill::kOpenVPNNsCertTypeProperty},
74    { ::onc::vpn::kPassword, shill::kOpenVPNPasswordProperty},
75    { ::onc::openvpn::kPort, shill::kOpenVPNPortProperty},
76    { ::onc::openvpn::kProto, shill::kOpenVPNProtoProperty},
77    { ::onc::openvpn::kPushPeerInfo, shill::kOpenVPNPushPeerInfoProperty},
78    { ::onc::openvpn::kRemoteCertEKU, shill::kOpenVPNRemoteCertEKUProperty},
79    // This field is converted during translation, see onc_translator_*.
80    // { ::onc::openvpn::kRemoteCertKU, shill::kOpenVPNRemoteCertKUProperty },
81    { ::onc::openvpn::kRemoteCertTLS, shill::kOpenVPNRemoteCertTLSProperty},
82    { ::onc::openvpn::kRenegSec, shill::kOpenVPNRenegSecProperty},
83    { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
84    { ::onc::openvpn::kServerCAPEMs, shill::kOpenVPNCaCertPemProperty},
85    { ::onc::openvpn::kServerPollTimeout,
86      shill::kOpenVPNServerPollTimeoutProperty},
87    { ::onc::openvpn::kShaper, shill::kOpenVPNShaperProperty},
88    { ::onc::openvpn::kStaticChallenge, shill::kOpenVPNStaticChallengeProperty},
89    { ::onc::openvpn::kTLSAuthContents, shill::kOpenVPNTLSAuthContentsProperty},
90    { ::onc::openvpn::kTLSRemote, shill::kOpenVPNTLSRemoteProperty},
91    { ::onc::vpn::kUsername, shill::kOpenVPNUserProperty},
92    { ::onc::openvpn::kVerifyHash, shill::kOpenVPNVerifyHashProperty},
93    {NULL}};
94
95const FieldTranslationEntry verify_x509_fields[] = {
96    { ::onc::verify_x509::kName, shill::kOpenVPNVerifyX509NameProperty},
97    { ::onc::verify_x509::kType, shill::kOpenVPNVerifyX509TypeProperty},
98    {NULL}};
99
100const FieldTranslationEntry vpn_fields[] = {
101    { ::onc::vpn::kAutoConnect, shill::kAutoConnectProperty},
102    { ::onc::vpn::kHost, shill::kProviderHostProperty},
103    // This field is converted during translation, see onc_translator_*.
104    // { ::onc::vpn::kType, shill::kProviderTypeProperty },
105    {NULL}};
106
107const FieldTranslationEntry wifi_fields[] = {
108    { ::onc::wifi::kAutoConnect, shill::kAutoConnectProperty},
109    { ::onc::wifi::kBSSID, shill::kWifiBSsid},
110    { ::onc::wifi::kFrequency, shill::kWifiFrequency},
111    { ::onc::wifi::kFrequencyList, shill::kWifiFrequencyListProperty},
112    { ::onc::wifi::kHiddenSSID, shill::kWifiHiddenSsid},
113    { ::onc::wifi::kPassphrase, shill::kPassphraseProperty},
114    // This field is converted during translation, see onc_translator_*.
115    // { ::onc::wifi::kSSID, shill::kWifiHexSsid},
116    // This field is converted during translation, see onc_translator_*.
117    // { ::onc::wifi::kSecurity, shill::kSecurityProperty },
118    { ::onc::wifi::kSignalStrength, shill::kSignalStrengthProperty},
119    {NULL}};
120
121const FieldTranslationEntry cellular_apn_fields[] = {
122    { ::onc::cellular_apn::kName, shill::kApnProperty},
123    { ::onc::cellular_apn::kUsername, shill::kApnUsernameProperty},
124    { ::onc::cellular_apn::kPassword, shill::kApnPasswordProperty},
125    { ::onc::cellular_apn::kLocalizedName, shill::kApnLocalizedNameProperty},
126    { ::onc::cellular_apn::kLanguage, shill::kApnLanguageProperty},
127    {NULL}};
128
129const FieldTranslationEntry cellular_found_network_fields[] = {
130    { ::onc::cellular_found_network::kNetworkId, shill::kNetworkIdProperty},
131    { ::onc::cellular_found_network::kStatus, shill::kStatusProperty},
132    { ::onc::cellular_found_network::kTechnology, shill::kTechnologyProperty},
133    { ::onc::cellular_found_network::kShortName, shill::kShortNameProperty},
134    { ::onc::cellular_found_network::kLongName, shill::kLongNameProperty},
135    {NULL}};
136
137const FieldTranslationEntry cellular_provider_fields[] = {
138    { ::onc::cellular_provider::kCode, shill::kOperatorCodeKey},
139    { ::onc::cellular_provider::kCountry, shill::kOperatorCountryKey},
140    { ::onc::cellular_provider::kName, shill::kOperatorNameKey},
141    {NULL}};
142
143const FieldTranslationEntry sim_lock_status_fields[] = {
144    { ::onc::sim_lock_status::kLockEnabled, shill::kSIMLockEnabledProperty},
145    { ::onc::sim_lock_status::kLockType, shill::kSIMLockTypeProperty},
146    { ::onc::sim_lock_status::kRetriesLeft, shill::kSIMLockRetriesLeftProperty},
147    {NULL}};
148
149// This must only contain Service properties and not Device properties.
150// For Device properties see kCellularDeviceTable.
151const FieldTranslationEntry cellular_fields[] = {
152    { ::onc::cellular::kActivationType, shill::kActivationTypeProperty},
153    { ::onc::cellular::kActivationState, shill::kActivationStateProperty},
154    { ::onc::cellular::kNetworkTechnology, shill::kNetworkTechnologyProperty},
155    { ::onc::cellular::kRoamingState, shill::kRoamingStateProperty},
156    {NULL}};
157
158const FieldTranslationEntry network_fields[] = {
159    { ::onc::network_config::kGUID, shill::kGuidProperty},
160    { ::onc::network_config::kConnectable, shill::kConnectableProperty },
161    { ::onc::network_config::kErrorState, shill::kErrorProperty },
162
163    // Shill doesn't allow setting the name for non-VPN networks.
164    // Name is conditionally translated, see onc_translator_*.
165    // { ::onc::network_config::kName, shill::kNameProperty },
166
167    // Type is converted during translation, see onc_translator_*.
168    // { ::onc::network_config::kType, shill::kTypeProperty },
169
170    // These fields are converted during translation, see
171    // onc_translator_shill_to_onc.cc. They are only converted when going from
172    // Shill->ONC, and ignored otherwise.
173    // { ::onc::network_config::kConnectionState, shill::kStateProperty },
174    // { ::onc::network_config::kMacAddress, shill::kAddressProperty },
175    {NULL}};
176
177const FieldTranslationEntry ipconfig_fields[] = {
178    { ::onc::ipconfig::kIPAddress, shill::kAddressProperty},
179    { ::onc::ipconfig::kGateway, shill::kGatewayProperty},
180    { ::onc::ipconfig::kRoutingPrefix, shill::kPrefixlenProperty},
181    { ::onc::ipconfig::kNameServers, shill::kNameServersProperty},
182    // This field is converted during translation, see ShillToONCTranslator::
183    // TranslateIPConfig. It is only converted from Shill->ONC.
184    // { ::onc::ipconfig::kType, shill::kMethodProperty},
185    {NULL}};
186
187struct OncValueTranslationEntry {
188  const OncValueSignature* onc_signature;
189  const FieldTranslationEntry* field_translation_table;
190};
191
192const OncValueTranslationEntry onc_value_translation_table[] = {
193  { &kEAPSignature, eap_fields },
194  { &kIPsecSignature, ipsec_fields },
195  { &kL2TPSignature, l2tp_fields },
196  { &kXAUTHSignature, xauth_fields },
197  { &kOpenVPNSignature, openvpn_fields },
198  { &kVerifyX509Signature, verify_x509_fields },
199  { &kVPNSignature, vpn_fields },
200  { &kWiFiSignature, wifi_fields },
201  { &kWiFiWithStateSignature, wifi_fields },
202  { &kCellularApnSignature, cellular_apn_fields },
203  { &kCellularFoundNetworkSignature, cellular_found_network_fields },
204  { &kCellularProviderSignature, cellular_provider_fields },
205  { &kSIMLockStatusSignature, sim_lock_status_fields },
206  { &kCellularSignature, cellular_fields },
207  { &kCellularWithStateSignature, cellular_fields },
208  { &kNetworkWithStateSignature, network_fields },
209  { &kNetworkConfigurationSignature, network_fields },
210  { &kIPConfigSignature, ipconfig_fields },
211  { NULL }
212};
213
214struct NestedShillDictionaryEntry {
215  const OncValueSignature* onc_signature;
216  // NULL terminated list of Shill property keys.
217  const char* const* shill_property_path;
218};
219
220const char* cellular_apn_property_path_entries[] = {
221  shill::kCellularApnProperty,
222  NULL
223};
224
225const NestedShillDictionaryEntry nested_shill_dictionaries[] = {
226  { &kCellularApnSignature, cellular_apn_property_path_entries },
227  { NULL }
228};
229
230}  // namespace
231
232const StringTranslationEntry kNetworkTypeTable[] = {
233    // This mapping is ensured in the translation code.
234    //  { network_type::kEthernet, shill::kTypeEthernet },
235    //  { network_type::kEthernet, shill::kTypeEthernetEap },
236    { ::onc::network_type::kWiFi, shill::kTypeWifi},
237    { ::onc::network_type::kWimax, shill::kTypeWimax},
238    { ::onc::network_type::kCellular, shill::kTypeCellular},
239    { ::onc::network_type::kVPN, shill::kTypeVPN},
240    {NULL}};
241
242const StringTranslationEntry kVPNTypeTable[] = {
243    { ::onc::vpn::kTypeL2TP_IPsec, shill::kProviderL2tpIpsec},
244    { ::onc::vpn::kOpenVPN, shill::kProviderOpenVpn}, {NULL}};
245
246// The first matching line is chosen.
247const StringTranslationEntry kWiFiSecurityTable[] = {
248    { ::onc::wifi::kSecurityNone, shill::kSecurityNone},
249    { ::onc::wifi::kWEP_PSK, shill::kSecurityWep},
250    { ::onc::wifi::kWPA_PSK, shill::kSecurityPsk},
251    { ::onc::wifi::kWPA_EAP, shill::kSecurity8021x},
252    { ::onc::wifi::kWPA_PSK, shill::kSecurityRsn},
253    { ::onc::wifi::kWPA_PSK, shill::kSecurityWpa},
254    {NULL}};
255
256const StringTranslationEntry kEAPOuterTable[] = {
257    { ::onc::eap::kPEAP, shill::kEapMethodPEAP},
258    { ::onc::eap::kEAP_TLS, shill::kEapMethodTLS},
259    { ::onc::eap::kEAP_TTLS, shill::kEapMethodTTLS},
260    { ::onc::eap::kLEAP, shill::kEapMethodLEAP},
261    {NULL}};
262
263// Translation of the EAP.Inner field in case of EAP.Outer == PEAP
264const StringTranslationEntry kEAP_PEAP_InnerTable[] = {
265    { ::onc::eap::kMD5, shill::kEapPhase2AuthPEAPMD5},
266    { ::onc::eap::kMSCHAPv2, shill::kEapPhase2AuthPEAPMSCHAPV2}, {NULL}};
267
268// Translation of the EAP.Inner field in case of EAP.Outer == TTLS
269const StringTranslationEntry kEAP_TTLS_InnerTable[] = {
270    { ::onc::eap::kMD5, shill::kEapPhase2AuthTTLSMD5},
271    { ::onc::eap::kMSCHAPv2, shill::kEapPhase2AuthTTLSMSCHAPV2},
272    { ::onc::eap::kPAP, shill::kEapPhase2AuthTTLSPAP},
273    {NULL}};
274
275// This must contain only Shill Device properties and no Service properties.
276// For Service properties see cellular_fields.
277const FieldTranslationEntry kCellularDeviceTable[] = {
278    // This field is converted during translation, see onc_translator_*.
279    // { ::onc::cellular::kAPNList, shill::kCellularApnListProperty},
280    { ::onc::cellular::kAllowRoaming, shill::kCellularAllowRoamingProperty},
281    { ::onc::cellular::kCarrier, shill::kCarrierProperty},
282    { ::onc::cellular::kESN, shill::kEsnProperty},
283    { ::onc::cellular::kFamily, shill::kTechnologyFamilyProperty},
284    { ::onc::cellular::kFirmwareRevision, shill::kFirmwareRevisionProperty},
285    // This field is converted during translation, see onc_translator_*.
286    // { ::onc::cellular::kFoundNetworks, shill::kFoundNetworksProperty},
287    { ::onc::cellular::kHardwareRevision, shill::kHardwareRevisionProperty},
288    { ::onc::cellular::kHomeProvider, shill::kHomeProviderProperty},
289    { ::onc::cellular::kICCID, shill::kIccidProperty},
290    { ::onc::cellular::kIMEI, shill::kImeiProperty},
291    { ::onc::cellular::kIMSI, shill::kImsiProperty},
292    { ::onc::cellular::kManufacturer, shill::kManufacturerProperty},
293    { ::onc::cellular::kMDN, shill::kMdnProperty},
294    { ::onc::cellular::kMEID, shill::kMeidProperty},
295    { ::onc::cellular::kMIN, shill::kMinProperty},
296    { ::onc::cellular::kModelID, shill::kModelIDProperty},
297    { ::onc::cellular::kPRLVersion, shill::kPRLVersionProperty},
298    { ::onc::cellular::kProviderRequiresRoaming,
299      shill::kProviderRequiresRoamingProperty},
300    { ::onc::cellular::kSelectedNetwork, shill::kSelectedNetworkProperty},
301    // This field is converted during translation, see onc_translator_*.
302    // { ::onc::cellular::kSIMLockStatus, shill::kSIMLockStatusProperty},
303    { ::onc::cellular::kSIMPresent, shill::kSIMPresentProperty},
304    { ::onc::cellular::kSupportedCarriers, shill::kSupportedCarriersProperty},
305    { ::onc::cellular::kSupportNetworkScan, shill::kSupportNetworkScanProperty},
306    {NULL}};
307
308const FieldTranslationEntry* GetFieldTranslationTable(
309    const OncValueSignature& onc_signature) {
310  for (const OncValueTranslationEntry* it = onc_value_translation_table;
311       it->onc_signature != NULL; ++it) {
312    if (it->onc_signature == &onc_signature)
313      return it->field_translation_table;
314  }
315  return NULL;
316}
317
318std::vector<std::string> GetPathToNestedShillDictionary(
319    const OncValueSignature& onc_signature) {
320  std::vector<std::string> shill_property_path;
321  for (const NestedShillDictionaryEntry* it = nested_shill_dictionaries;
322       it->onc_signature != NULL; ++it) {
323    if (it->onc_signature == &onc_signature) {
324      for (const char* const* key = it->shill_property_path; *key != NULL;
325           ++key) {
326        shill_property_path.push_back(std::string(*key));
327      }
328      break;
329    }
330  }
331  return shill_property_path;
332}
333
334bool GetShillPropertyName(const std::string& onc_field_name,
335                          const FieldTranslationEntry table[],
336                          std::string* shill_property_name) {
337  for (const FieldTranslationEntry* it = table;
338       it->onc_field_name != NULL; ++it) {
339    if (it->onc_field_name != onc_field_name)
340      continue;
341    *shill_property_name = it->shill_property_name;
342    return true;
343  }
344  return false;
345}
346
347bool TranslateStringToShill(const StringTranslationEntry table[],
348                            const std::string& onc_value,
349                            std::string* shill_value) {
350  for (int i = 0; table[i].onc_value != NULL; ++i) {
351    if (onc_value != table[i].onc_value)
352      continue;
353    *shill_value = table[i].shill_value;
354    return true;
355  }
356  LOG(ERROR) << "Value '" << onc_value << "' cannot be translated to Shill";
357  return false;
358}
359
360bool TranslateStringToONC(const StringTranslationEntry table[],
361                          const std::string& shill_value,
362                          std::string* onc_value) {
363  for (int i = 0; table[i].shill_value != NULL; ++i) {
364    if (shill_value != table[i].shill_value)
365      continue;
366    *onc_value = table[i].onc_value;
367    return true;
368  }
369  LOG(ERROR) << "Value '" << shill_value << "' cannot be translated to ONC";
370  return false;
371}
372
373}  // namespace onc
374}  // namespace chromeos
375