195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
76fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.orgimport json
86fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit.format.policy_templates.writers import template_writer
1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgdef GetWriter(config):
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Factory method for creating RegWriter objects.
1401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  See the constructor of TemplateWriter for description of
1501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  arguments.
1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''
1701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  return RegWriter(['win'], config)
1801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass RegWriter(template_writer.TemplateWriter):
2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Class for generating policy example files in .reg format (for Windows).
2201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  The generated files will define all the supported policies with example
2301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  values  set for them. This class is used by PolicyTemplateGenerator to
2401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  write .reg  files.
2501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''
2601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  NEWLINE = '\r\n'
2801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def _EscapeRegString(self, string):
3001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return string.replace('\\', '\\\\').replace('\"', '\\\"')
3101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
320bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def _StartBlock(self, key, suffix, list):
330bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    key = 'HKEY_LOCAL_MACHINE\\' + key
3401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if suffix:
3501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      key = key + '\\' + suffix
360bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    if key != self._last_key.get(id(list), None):
370bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      list.append('')
380bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      list.append('[%s]' % key)
390bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      self._last_key[id(list)] = key
4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def PreprocessPolicies(self, policy_list):
4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return self.FlattenGroupsAndSortPolicies(policy_list,
4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                                             self.GetPolicySortingKey)
4401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
4501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetPolicySortingKey(self, policy):
4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Extracts a sorting key from a policy. These keys can be used for
4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    list.sort() methods to sort policies.
4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    See TemplateWriter.SortPoliciesGroupsFirst for usage.
4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
50786be15cb6c0f7d78f3eab9fda9d4266619ddbf0joaodasilva@chromium.org    is_list = policy['type'] in ('list', 'string-enum-list')
5101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Lists come after regular policies.
5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return (is_list, policy['name'])
5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
540bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def _WritePolicy(self, policy, key, list):
5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    example_value = policy['example_value']
5601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
57e9f965b7a19bfc970bec100fb03e6aa269deb522joaodasilva@chromium.org    if policy['type'] == 'external':
58e9f965b7a19bfc970bec100fb03e6aa269deb522joaodasilva@chromium.org      # This type can only be set through cloud policy.
59e9f965b7a19bfc970bec100fb03e6aa269deb522joaodasilva@chromium.org      return
60786be15cb6c0f7d78f3eab9fda9d4266619ddbf0joaodasilva@chromium.org    elif policy['type'] in ('list', 'string-enum-list'):
610bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      self._StartBlock(key, policy['name'], list)
6201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      i = 1
6301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      for item in example_value:
6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        escaped_str = self._EscapeRegString(item)
650bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org        list.append('"%d"="%s"' % (i, escaped_str))
6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        i = i + 1
6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    else:
680bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      self._StartBlock(key, None, list)
696fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org      if policy['type'] in ('string', 'string-enum', 'dict'):
706fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org        example_value_str = json.dumps(example_value, sort_keys=True)
716fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org        if policy['type'] == 'dict':
726fb6d62a2a05b7a7c268cc4e6bf0452e376e1990joaodasilva@chromium.org          example_value_str = '"%s"' % example_value_str
7301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      elif policy['type'] == 'main':
7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        if example_value == True:
7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          example_value_str = 'dword:00000001'
7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        else:
7701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          example_value_str = 'dword:00000000'
7801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      elif policy['type'] in ('int', 'int-enum'):
7901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        example_value_str = 'dword:%08x' % example_value
8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      else:
8101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        raise Exception('unknown policy type %s:' % policy['type'])
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
830bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org      list.append('"%s"=%s' % (policy['name'], example_value_str))
840bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
850bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def WritePolicy(self, policy):
86740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org    if self.CanBeMandatory(policy):
87740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org      self._WritePolicy(policy,
88740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org                        self.config['win_reg_mandatory_key_name'],
89740badd5e3e44434a9a47b5d16749daac1e8ea80joaodasilva@chromium.org                        self._mandatory)
900bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org
910bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org  def WriteRecommendedPolicy(self, policy):
920bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    self._WritePolicy(policy,
930bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org                      self.config['win_reg_recommended_key_name'],
940bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org                      self._recommended)
9501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def BeginTemplate(self):
9701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
9801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def EndTemplate(self):
10001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    pass
10101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Init(self):
1030bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    self._mandatory = []
1040bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    self._recommended = []
1050bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    self._last_key = {}
10601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetTemplateText(self):
1080bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    prefix = ['Windows Registry Editor Version 5.00']
1090bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    all = prefix + self._mandatory + self._recommended
1100bb959423818266efea82162f48ad83e5eb2e8b2joaodasilva@chromium.org    return self.NEWLINE.join(all)
111