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

Side by Side Diff: tools/origin_trials/validate_subdomain_origin/validate_subdomain_origin.cc

Issue 2456053004: Validate origins when generating subdomain tokens (Closed)
Patch Set: Fix android_cronet build error Created 4 years 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
« no previous file with comments | « tools/origin_trials/validate_subdomain_origin/test_validate.py ('k') | url/features.gni » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <iostream>
9 #include <string>
10
11 #include "base/command_line.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/strings/string_piece.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
16 #include "net/base/url_util.h"
17 #include "url/gurl.h"
18
19 using net::registry_controlled_domains::GetCanonicalHostRegistryLength;
20 using net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES;
21 using net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES;
22 using net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES;
23
24 // Return codes used by this utility.
25 static const int kStatusValid = 0;
26 static const int kStatusInvalidOrigin = 1;
27 static const int kStatusInPublicSuffixList = 2;
28 static const int kStatusError = 3;
29 static const int kStatusIPAddress = 4;
30
31 // Causes the app to suppress logging/verbose output
32 static const char kOptionQuiet[] = "quiet";
33
34 void PrintHelp() {
35 std::cerr
36 << "Usage:\n"
37 " validate_subdomain_origin [--quiet] <origin>\n"
38 " Checks that the origin can be used in a token that matches\n"
39 " subdomains, returning 0 when the origin is valid for such use.\n"
40 " The origin may be specified as an url (e.g. "
41 "'https://example.com'),\n"
42 " or as bare hostname (e.g. 'example.com').\n"
43 " The caller is responsible for ensuring that a well-formed "
44 "origin\n"
45 " is provided, there are no checks for correctness.\n"
46 " Pass \"--quiet\" to suppress any output.\n";
47 }
48
49 void PrintValidHost(const base::StringPiece origin) {
50 std::cout << "validate_subdomain_origin: Valid origin - " << origin
51 << std::endl;
52 }
53
54 void PrintIPAddressNotSupported(const base::StringPiece origin) {
55 std::cout << "validate_subdomain_origin: Origin is an IP address - "
56 << origin << std::endl;
57 }
58
59 void PrintInvalidUrl(const base::StringPiece origin) {
60 std::cout << "validate_subdomain_origin: Invalid url format for origin - "
61 << origin << std::endl;
62 }
63
64 void PrintInvalidOrigin(const base::StringPiece origin) {
65 std::cout << "validate_subdomain_origin: Invalid origin - " << origin
66 << std::endl;
67 }
68
69 void PrintInPublicSuffixList(const base::StringPiece origin) {
70 std::cout << "validate_subdomain_origin: Origin in Public Suffix List - "
71 << origin << std::endl;
72 }
73
74 int CheckOrigin(const base::StringPiece origin, bool verbose) {
75 base::StringPiece host;
76 std::unique_ptr<std::string> canon_host = nullptr;
77
78 // Validate the origin, which may be provided as an url (with scheme prefix),
79 // or just as a hostname. Regardless of format, if the origin is identified
80 // as an IP address, that is valid for subdomain tokens.
81 GURL gurl(origin);
82 if (gurl.is_valid()) {
83 if (gurl.HostIsIPAddress()) {
84 if (verbose) {
85 PrintIPAddressNotSupported(origin);
86 }
87 return kStatusIPAddress;
88 }
89 host = gurl.host_piece();
90 } else {
91 // Doesn't look like an url, try the origin as a hostname
92 url::CanonHostInfo host_info;
93 canon_host = base::MakeUnique<std::string>(
94 net::CanonicalizeHost(origin, &host_info));
95 if (canon_host->empty()) {
96 if (verbose) {
97 PrintInvalidOrigin(origin);
98 }
99 return kStatusInvalidOrigin;
100 }
101 if (host_info.IsIPAddress()) {
102 if (verbose) {
103 PrintIPAddressNotSupported(origin);
104 }
105 return kStatusIPAddress;
106 }
107 host.set(canon_host->c_str());
108 }
109
110 size_t registry_length = GetCanonicalHostRegistryLength(
111 host, INCLUDE_UNKNOWN_REGISTRIES, INCLUDE_PRIVATE_REGISTRIES);
112
113 if (registry_length > 0) {
114 // Host has at least one subcomponent (e.g. a.b), and the host is not just
115 // a registry (e.g. co.uk).
116 if (verbose) {
117 PrintValidHost(origin);
118 }
119 return kStatusValid;
120 }
121
122 // If registry length is 0, then the host may be a registry, or it has no
123 // subcomponents. If there are subcomponents, the host must be a registry,
124 // which makes it invalid.
125 if (host.find('.') != std::string::npos) {
126 if (verbose) {
127 PrintInPublicSuffixList(origin);
128 }
129 return kStatusInPublicSuffixList;
130 }
131
132 // There are no subcomponents, but still don't know if this a registry
133 // (e.g. host = "com"), or a private/internal address (e.g. host = "bar").
134 // Test by adding a subcomponent, and re-checking the registry. In this case,
135 // exclude unknown registries. That means that "prefix.com" will match the
136 // "com" registry, and return a non-zero length. Conversely, "prefix.bar" will
137 // not match any known registry, and return a zero length.
138 std::string test_host("prefix.");
139 test_host.append(host.as_string());
140
141 size_t test_registry_length = GetCanonicalHostRegistryLength(
142 test_host, EXCLUDE_UNKNOWN_REGISTRIES, INCLUDE_PRIVATE_REGISTRIES);
143 if (test_registry_length > 0) {
144 if (verbose) {
145 PrintInPublicSuffixList(origin);
146 }
147 return kStatusInPublicSuffixList;
148 }
149
150 if (verbose) {
151 PrintValidHost(origin);
152 }
153 return kStatusValid;
154 }
155
156 int main(int argc, const char* argv[]) {
157 base::CommandLine::Init(argc, argv);
158 const base::CommandLine& parsed_command_line =
159 *base::CommandLine::ForCurrentProcess();
160 const base::CommandLine::StringVector& args = parsed_command_line.GetArgs();
161 bool quiet = parsed_command_line.HasSwitch(kOptionQuiet);
162 if (args.size() == 1) {
163 #if defined(OS_WIN)
164 std::string origin = base::UTF16ToUTF8(args[0]);
165 return CheckOrigin(origin, !quiet);
166 #else
167 return CheckOrigin(args[0], !quiet);
168 #endif
169 }
170
171 PrintHelp();
172 return kStatusError;
173 }
OLDNEW
« no previous file with comments | « tools/origin_trials/validate_subdomain_origin/test_validate.py ('k') | url/features.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698