Re-Re-land: Add download_file_types.proto with ascii->binary conversion, as a resource.

This reverts commit 90ade35dd2736cc1fa3eb9fc67e83640345b519b
Adds: -S -s args to /usr/bin/python

BUG=596555

Review URL: https://codereview.chromium.org/1917653002

Cr-Commit-Position: refs/heads/master@{#389612}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index d153f91..64a1fe1 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1032,6 +1032,7 @@
 
   deps = [
     ":chrome_internal_resources_gen",
+    "//chrome/browser/resources/safe_browsing:make_file_types_protobuf",
 
     # Depend only on the generated mojo bindings since we read the .mojom.js
     # file, rather than the whole mojo target which will link the C++ bindings.
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index cbf841f..b39568b 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -110,6 +110,9 @@
       <include name="IDR_DOMAIN_RELIABILITY_INTERNALS_HTML" file="resources\domain_reliability_internals.html" type="BINDATA" />
       <include name="IDR_DOMAIN_RELIABILITY_INTERNALS_CSS" file="resources\domain_reliability_internals.css" type="BINDATA" />
       <include name="IDR_DOMAIN_RELIABILITY_INTERNALS_JS" file="resources\domain_reliability_internals.js" type="BINDATA" />
+      <if expr="not is_android and not is_ios">
+        <include name="IDR_DOWNLOAD_FILE_TYPES_PB" file="${root_gen_dir}\chrome\browser\resources\safe_browsing\download_file_types.pb" use_base_dir="false" type="BINDATA" />
+      </if>
       <if expr="not is_android">
         <include name="IDR_MD_DOWNLOADS_1X_INCOGNITO_MARKER_PNG" file="resources\md_downloads\1x\incognito_marker.png" type="BINDATA" />
         <include name="IDR_MD_DOWNLOADS_2X_INCOGNITO_MARKER_PNG" file="resources\md_downloads\2x\incognito_marker.png" type="BINDATA" />
diff --git a/chrome/browser/resources/safe_browsing/BUILD.gn b/chrome/browser/resources/safe_browsing/BUILD.gn
new file mode 100644
index 0000000..9a039aee
--- /dev/null
+++ b/chrome/browser/resources/safe_browsing/BUILD.gn
@@ -0,0 +1,43 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Generate the binary proto form of "file_types" from the ascii proto.
+action("make_file_types_protobuf") {
+  script = "gen_file_type_proto.py"
+
+  # The output goes in $target_gen_dir since that's where
+  # chrome/browser/browser_resources.grd will look for it.
+
+  input_filename = "download_file_types.asciipb"
+  output_filename = "$target_gen_dir/download_file_types.pb"
+  python_path_root = "$root_build_dir/pyproto"
+  python_path_safe_browsing = "$python_path_root/chrome/common/safe_browsing"
+
+  inputs = [
+    script,
+    input_filename,
+  ]
+
+  # This script requires the generated python proto code
+  deps = [
+    "//chrome/common/safe_browsing:proto",
+    "//third_party/protobuf:py_proto",
+  ]
+
+  outputs = [
+    output_filename,
+  ]
+
+  args = [
+    "-w",
+    "-i",
+    rebase_path(input_filename, root_build_dir),
+    "-o",
+    rebase_path(output_filename, root_build_dir),
+    "-p",
+    rebase_path(python_path_root, root_build_dir),
+    "-p",
+    rebase_path(python_path_safe_browsing, root_build_dir),
+  ]
+}
diff --git a/chrome/browser/resources/safe_browsing/README.md b/chrome/browser/resources/safe_browsing/README.md
new file mode 100644
index 0000000..3d7f2e6
--- /dev/null
+++ b/chrome/browser/resources/safe_browsing/README.md
@@ -0,0 +1,96 @@
+# Behavior of Download File Types in Chrome
+
+This describes how to adjust file-type download behavior in
+Chrome including interactions with Safe Browsing.  The metadata described
+here, and stored in `download_file_types.asciipb`, will be both baked into
+Chrome released and pushable to Chrome between releases. http://crbug.com/596555
+
+Rendered version of this file: https://chromium.googlesource.com/chromium/src/+/master/chrome/browser/resources/safe_browsing/README.md
+
+
+## Procedure for adding a new type
+  * Edit `download_file_types.asciipb`. Update `histograms.xml`
+  * Get it reviewed, submit.
+  * Push via component update (PROCEDURE TBD)
+
+## Guidelines for a DownloadFileType entry:
+See `download_file_types.proto` for all fields.
+
+  * `extension`: Value must be unique within the config. It should be
+    lowercase ASCII and not contain a dot.  If there _is_ a duplicate,
+    first one wins.  Only the `default_file_type` should leave this unset.
+
+  * `uma_value`: Value must be unique and match one in the
+    `SBClientDownloadExtensions` enum in `histograms.xml`.
+
+  * `is_archive`: `True` if this filetype is a container for other files.
+     Leave it unset for `false`.
+
+  * `platform_settings`: (repeated) Must have one entry with an unset
+     `platform` field, and optionally additional entries with overrides
+     for one or more platforms.  An unset `platform` field acts as a
+     default for any platforms that don't have an override.  There should
+     not be two settings with the same `platform`, but if there are,
+     first one wins.  Keep them sorted by platform.
+
+  * `platform_settings.danger_level`: (required)
+    * `NOT_DANGEROUS`: Safe to download and open, even if the download
+       was accidental.
+    * `DANGEROUS`: Always warn the user that this file may harm their
+      computer.  We let them continue or discard the file.  If Safe
+      Browsing returns a SAFE verdict, we still warn the user.
+    * `ALLOW_ON_USER_GESTURE`: Warn the user normally but skip the warning
+      if there was a user gesture or the user visited this site before
+      midnight last night (i.e. is a repeat visit).  If Safe Browsing
+      returns a SAFE verdict for this file, it won't show a warning.
+
+  * `platform_settings.auto_open_hint`: Required.
+    * `ALLOW_AUTO_OPEN`: File type can be opened automatically if the user
+      selected that option from the download tray on a previous download
+      of this type.
+    * `DISALLOW_AUTO_OPEN`:  Never let the file automatically open.
+      Files that should be disallowed from auto-opening include those that
+      execute arbitrary or harmful code with user privileges, or change
+      configuration of the system to cause harmful behavior immediately
+      or at some time in the future. We *do* allow auto-open for files
+      that upon opening sufficiently warn the user about the fact that it
+      was downloaded from the internet and can do damage.  **Note**:
+      Some file types (e.g.: .local and .manifest) aren't dangerous
+      to open.  However, their presence on the file system may cause
+      potentially dangerous changes in behavior for other programs. We
+      allow automatically opening these file types, but always warn when
+      they are downloaded.
+
+  * `platform_settings.ping_setting`:  Required.  This controls what sort
+     of ping is sent to Safe Browsing and if a verdict is checked before
+     the user can access the file.
+    * `SAMPLED_PING`: Don't send a full Safe Browsing ping, but
+       send a no-PII "light-ping" for a random sample of SBER users.
+       This should be the default for unknown types.  The verdict won't
+       be used.
+    * `NO_PING`:  Don’t send any pings.  This file is whitelisted. All
+      NOT_DANGEROUS files should normally use this.
+    * `FULL_PING`: Send full pings and use the verdict. All dangerous
+      file should use this.
+
+  * TODO(nparker): Support this: `platform_settings.unpacker`:
+     optional. Specifies which archive unpacker internal to Chrome
+     should be used.  If potentially dangerous file types are found,
+     Chrome will send a full-ping for the entire file.  Otherwise, it'll
+     follow the ping settings. Can be one of UNPACKER_ZIP or UNPACKER_DMG.
+
+## Guidelines for the top level DownloadFileTypeConfig entry:
+  * `version_id`: Must be increased (+1) every time the file is checked in.
+     Will be logged to UMA.
+
+  * `sampled_ping_probability`: For what fraction of extended-reporting
+    users' downloads with unknown extensions (or
+    ping_setting=SAMPLED_PING) should we send light-pings? [0.0 .. 1.0]
+
+  * `file_type`: The big list of all known file types. Keep them
+     sorted by extension.
+
+  * `default_file_type`: Settings used if a downloaded file is not in
+    the above list.  `extension` is ignored, but other settings are used.
+    The ping_setting should be SAMPLED_PING for all platforms.
+
diff --git a/chrome/browser/resources/safe_browsing/download_file_types.asciipb b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
new file mode 100644
index 0000000..b7f8d70
--- /dev/null
+++ b/chrome/browser/resources/safe_browsing/download_file_types.asciipb
@@ -0,0 +1,44 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# See README.md before editing this file.
+#
+# Placeholder for list of file extensions that the download manager
+# knows about.
+# TODO(nparker): Populate this with full list.
+version_id: 1
+sampled_ping_probability: 0.0
+default_file_type {
+  uma_value: 19
+  platform_settings {
+    danger_level: ALLOW_ON_USER_GESTURE
+    auto_open_hint: DISALLOW_AUTO_OPEN
+    ping_setting: SAMPLED_PING
+  }
+}
+#
+# File types:
+#
+file_types {
+  extension: "exe"
+  uma_value: 777
+  platform_settings {
+    danger_level: ALLOW_ON_USER_GESTURE
+    auto_open_hint: DISALLOW_AUTO_OPEN
+    ping_setting: FULL_PING
+  }
+}
+file_types {
+  extension: "zip"
+  uma_value: 888
+  is_archive: true
+  platform_settings {
+    danger_level: NOT_DANGEROUS
+    auto_open_hint: ALLOW_AUTO_OPEN
+    ping_setting: SAMPLED_PING
+  }
+}
+# file_types {...}
+# file_types {...}
+# file_types {...}
diff --git a/chrome/browser/resources/safe_browsing/gen_file_type_proto.py b/chrome/browser/resources/safe_browsing/gen_file_type_proto.py
new file mode 100755
index 0000000..a6e4fab
--- /dev/null
+++ b/chrome/browser/resources/safe_browsing/gen_file_type_proto.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+ Convert the ASCII download_file_types.asciipb proto into a binary resource.
+"""
+
+import optparse
+import subprocess
+import sys
+
+
+def ConvertProto(opts):
+  # Find the proto code
+  for path in opts.path:
+    # Put the path to our proto libraries in front, so that we don't use system
+    # protobuf.
+    sys.path.insert(1, path)
+
+
+  import download_file_types_pb2 as config_pb2
+  import google.protobuf.text_format as text_format
+
+  # Read the ASCII
+  ifile = open(opts.infile, 'r')
+  ascii_pb_str = ifile.read()
+  ifile.close()
+
+  # Parse it into a structure PB
+  pb = config_pb2.DownloadFileTypeConfig()
+  text_format.Merge(ascii_pb_str, pb)
+
+  # Serialize it
+  binary_pb_str = pb.SerializeToString()
+
+  # Write it to disk
+  open(opts.outfile, 'w').write(binary_pb_str)
+
+
+def main():
+  parser = optparse.OptionParser()
+  # TODO(nparker): Remove this once the bug is fixed.
+  parser.add_option('-w', '--wrap', action="store_true", default=False,
+                     help='Wrap this script in another python '
+                     'execution to disable site-packages.  This is a '
+                     'fix for http://crbug.com/605592')
+  parser.add_option('-i', '--infile',
+                    help='The ASCII DownloadFileType-proto file to read.')
+  parser.add_option('-o', '--outfile',
+                    help='The binary file to write.')
+  parser.add_option('-p', '--path', action="append",
+                    help='Repeat this as needed.  Directory(s) containing ' +
+                    'the download_file_types_pb2.py and ' +
+                    'google.protobuf.text_format modules')
+  (opts, args) = parser.parse_args()
+  if opts.infile is None or opts.outfile is None:
+    parser.print_help()
+    return 1
+
+  if opts.wrap:
+    # Run this script again with different args to the interpreter.
+    command = [sys.executable, '-S', '-s', sys.argv[0]]
+    command += ['-i', opts.infile]
+    command += ['-o', opts.outfile]
+    for path in opts.path:
+      command += ['-p', path]
+    sys.exit(subprocess.call(command))
+
+  try:
+    ConvertProto(opts)
+  except Exception as e:
+    print "ERROR: %s failed to parse ASCII proto\n%s: %s\n" % (
+        sys.argv, opts.infile, str(e))
+    return 1
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index 911d0f5..725df23 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -622,8 +622,8 @@
     },
     {
       # Protobuf compiler / generator for the safebrowsing client
-      # model proto and the client-side detection (csd) request
-      # protocol buffer.
+      # model proto, the client-side detection (csd) request
+      # proto, and the download file types proto.
 
       # GN version: //chrome/common/safe_browsing:proto
       'target_name': 'safe_browsing_proto',
@@ -631,7 +631,8 @@
       'sources': [
         'common/safe_browsing/client_model.proto',
         'common/safe_browsing/crx_info.proto',
-        'common/safe_browsing/csd.proto'
+        'common/safe_browsing/csd.proto',
+        'common/safe_browsing/download_file_types.proto',
       ],
       'variables': {
         'proto_in_dir': 'common/safe_browsing',
diff --git a/chrome/chrome_resources.gyp b/chrome/chrome_resources.gyp
index dc41d41..531ca67 100644
--- a/chrome/chrome_resources.gyp
+++ b/chrome/chrome_resources.gyp
@@ -222,6 +222,9 @@
             }
           ],
         }],
+        ['OS != "android" and OS != "ios"', {
+          'dependencies': [ 'make_file_types_protobuf' ]
+        }],
       ],
       'includes': [ '../build/grit_target.gypi' ],
     },
@@ -293,6 +296,45 @@
         },
       ],
     },
+
+    {
+      # GN version: //chrome/browser/resources/safe_browsing:make_file_types_protobuf
+      # Convert the ascii proto file to a binary resource.
+      'target_name': 'make_file_types_protobuf',
+      'type': 'none',
+      'hard_dependency': 1,
+      'dependencies': [
+        'chrome.gyp:safe_browsing_proto',
+        '<(DEPTH)/third_party/protobuf/protobuf.gyp:py_proto',
+      ],
+      'actions': [
+        {
+          'action_name': 'generate_file_types_protobuf',
+          'variables' : {
+            'script_file':'browser/resources/safe_browsing/gen_file_type_proto.py',
+            'asciipb_file' : 'browser/resources/safe_browsing/download_file_types.asciipb',
+            'output_file' : '<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/safe_browsing/download_file_types.pb',
+          },
+          'inputs': [
+            '<(script_file)',
+            '<(asciipb_file)',
+          ],
+          'outputs': [
+            '<(output_file)',
+          ],
+          'action': [
+            'python',
+            '<(script_file)',
+            '-w',
+            '-i', '<(asciipb_file)',
+            '-o', '<(output_file)',
+            '-p', '<(PRODUCT_DIR)/pyproto',
+            '-p', '<(PRODUCT_DIR)/pyproto/chrome/common/safe_browsing',
+          ],
+          'message': 'Generating download_file_types.pb.',
+        }
+      ],
+    },
     {
       # GN version: //chrome/browser/metrics/variations:chrome_ui_string_overrider_factory_gen_sources
       'target_name': 'make_chrome_ui_string_overrider_factory',
diff --git a/chrome/common/safe_browsing/BUILD.gn b/chrome/common/safe_browsing/BUILD.gn
index 47805eb..600a873 100644
--- a/chrome/common/safe_browsing/BUILD.gn
+++ b/chrome/common/safe_browsing/BUILD.gn
@@ -10,5 +10,6 @@
     "client_model.proto",
     "crx_info.proto",
     "csd.proto",
+    "download_file_types.proto",
   ]
 }
diff --git a/chrome/common/safe_browsing/download_file_types.proto b/chrome/common/safe_browsing/download_file_types.proto
new file mode 100644
index 0000000..8efe589
--- /dev/null
+++ b/chrome/common/safe_browsing/download_file_types.proto
@@ -0,0 +1,65 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+package safe_browsing;
+
+// See //chrome/browser/resources/safe_browsing/README.md for guidelines
+// on how to set fields in this file.
+
+// Next id: 5
+message DownloadFileType {
+  optional string extension = 1;  // required
+  optional int64 uma_value = 2;  // required
+  optional bool is_archive = 3;
+
+  enum DangerLevel {
+    NOT_DANGEROUS = 0;
+    ALLOW_ON_USER_GESTURE = 1;
+    DANGEROUS = 2;
+  }
+
+  enum AutoOpenHint {
+    ALLOW_AUTO_OPEN = 1;
+    DISALLOW_AUTO_OPEN = 2;
+  }
+
+  enum PlatformType {
+    PLATFORM_ANDROID = 1;
+    PLATFORM_CHROME_OS = 2;
+    PLATFORM_LINUX = 3;
+    PLATFORM_MAC = 4;
+    PLATFORM_WINDOWS = 5;
+  }
+
+  enum PingSetting {
+    SAMPLED_PING = 0;
+    NO_PING = 1;
+    FULL_PING = 2;
+  }
+
+  // TODO(nparker): Add a field describing what Chrome-internal unpacker
+  // should be used to scan this file type (DMG or zip are currently supported)
+
+  // Next id: 5
+  message PlatformSettings {
+    optional PlatformType platform = 1;
+    optional DangerLevel danger_level = 2;  // required
+    optional AutoOpenHint auto_open_hint = 3;  // required
+    optional PingSetting ping_setting = 4;  // required
+  };
+
+  repeated PlatformSettings platform_settings = 4; // required >= 1
+};
+
+// Next id: 5
+message DownloadFileTypeConfig {
+  optional uint32 version_id = 1;
+  optional float sampled_ping_probability = 2;
+  repeated DownloadFileType file_types = 3;
+  optional DownloadFileType default_file_type = 4;
+}