1 // Copyright (c) 2015 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 #ifndef COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_COMMON_NAME_MISMATCH_HANDLER_H_
6 #define COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_COMMON_NAME_MISMATCH_HANDLER_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/sequence_checker.h"
17 #include "base/time/time.h"
18 #include "services/network/public/mojom/url_response_head.mojom-forward.h"
19 #include "url/gurl.h"
20 
21 namespace net {
22 struct RedirectInfo;
23 }  // namespace net
24 
25 namespace network {
26 class SharedURLLoaderFactory;
27 class SimpleURLLoader;
28 }  // namespace network
29 
30 // This class handles errors due to common name mismatches
31 // (|ERR_CERT_COMMON_NAME_INVALID|) and helps remediate them by suggesting
32 // alternative URLs that may be what the user intended to load.
33 class CommonNameMismatchHandler {
34  public:
35   enum SuggestedUrlCheckResult {
36     // The request succeeds with good response code i.e. URL exists and its
37     // certificate is valid.
38     SUGGESTED_URL_AVAILABLE,
39     // Suggested URL is either not available or has a bad certificate.
40     SUGGESTED_URL_NOT_AVAILABLE
41   };
42 
43   enum TestingState {
44     NOT_TESTING,
45     // Disables the actual request to the |suggested_url|.
46     IGNORE_REQUESTS_FOR_TESTING
47   };
48 
49   typedef base::OnceCallback<void(SuggestedUrlCheckResult result,
50                                   const GURL& suggested_url)>
51       CheckUrlCallback;
52 
53   CommonNameMismatchHandler(
54       const GURL& request_url,
55       scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
56   ~CommonNameMismatchHandler();
57 
58   // Performs a network request to suggested URL. After completion, runs the
59   // |callback|.
60   void CheckSuggestedUrl(const GURL& url, CheckUrlCallback callback);
61 
62   // Determines if, for |request_url| serving a certificate that is valid for
63   // the domain names |dns_names|, there is a name that the certificate is
64   // valid for that closely matches the original name in |request_url|. If
65   // so, returns true, and sets |*suggested_url| to a URL that is unlikely
66   // to cause an ERR_CERT_COMMON_NAME_INVALID error.
67   static bool GetSuggestedUrl(const GURL& request_url,
68                               const std::vector<std::string>& dns_names,
69                               GURL* suggested_url);
70 
71   // Used in tests, to disable the request to |suggested_url|.
72   // If |testing_state| is IGNORE_REQUESTS_FOR_TESTING, then the
73   // callback won't get called.
set_state_for_testing(TestingState testing_state)74   static void set_state_for_testing(TestingState testing_state) {
75     testing_state_ = testing_state;
76   }
77 
78   // Cancels the request to |suggested_url|
79   void Cancel();
80 
81  private:
82   void OnSimpleLoaderHandler(const GURL& final_url,
83                              const network::mojom::URLResponseHead* head);
84   void OnSimpleLoaderRedirect(
85       const net::RedirectInfo& redirect_info,
86       const network::mojom::URLResponseHead& response_head,
87       std::vector<std::string>* to_be_removed_headers);
88   void OnSimpleLoaderResponseStarted(
89       const GURL& final_url,
90       const network::mojom::URLResponseHead& response_head);
91   void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body);
92 
93   // Returns true if the check is currently running.
94   bool IsCheckingSuggestedUrl() const;
95 
96   static TestingState testing_state_;
97   const GURL request_url_;
98   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
99   GURL check_url_;
100   CheckUrlCallback check_url_callback_;
101   std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
102 
103   SEQUENCE_CHECKER(sequence_checker_);
104 
105   DISALLOW_COPY_AND_ASSIGN(CommonNameMismatchHandler);
106 };
107 
108 #endif  // COMPONENTS_SECURITY_INTERSTITIALS_CONTENT_COMMON_NAME_MISMATCH_HANDLER_H_
109