Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/privet_http_impl.h" | 5 #include "chrome/browser/local_discovery/privet_http_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/command_line.h" | |
| 11 #include "base/location.h" | 12 #include "base/location.h" |
| 12 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 13 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
| 17 #include "chrome/browser/local_discovery/privet_constants.h" | 18 #include "chrome/browser/local_discovery/privet_constants.h" |
| 18 #include "chrome/common/chrome_content_client.h" | 19 #include "chrome/common/chrome_content_client.h" |
| 20 #include "chrome/common/chrome_switches.h" | |
| 19 #include "chrome/common/cloud_print/cloud_print_constants.h" | 21 #include "chrome/common/cloud_print/cloud_print_constants.h" |
| 20 #include "net/base/url_util.h" | 22 #include "net/base/url_util.h" |
| 21 #include "net/cert/cert_verifier.h" | 23 #include "net/cert/cert_verifier.h" |
| 22 #include "net/cert/cert_verify_result.h" | 24 #include "net/cert/cert_verify_result.h" |
| 23 #include "net/url_request/url_request_context.h" | 25 #include "net/url_request/url_request_context.h" |
| 24 #include "net/url_request/url_request_context_builder.h" | 26 #include "net/url_request/url_request_context_builder.h" |
| 25 #include "url/gurl.h" | 27 #include "url/gurl.h" |
| 26 | 28 |
| 27 #if defined(ENABLE_PRINT_PREVIEW) | 29 #if defined(ENABLE_PRINT_PREVIEW) |
| 28 #include "chrome/browser/local_discovery/pwg_raster_converter.h" | 30 #include "chrome/browser/local_discovery/pwg_raster_converter.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 const std::string& query_params) { | 82 const std::string& query_params) { |
| 81 GURL url(kUrlPlaceHolder); | 83 GURL url(kUrlPlaceHolder); |
| 82 GURL::Replacements replacements; | 84 GURL::Replacements replacements; |
| 83 replacements.SetPathStr(path); | 85 replacements.SetPathStr(path); |
| 84 if (!query_params.empty()) { | 86 if (!query_params.empty()) { |
| 85 replacements.SetQueryStr(query_params); | 87 replacements.SetQueryStr(query_params); |
| 86 } | 88 } |
| 87 return url.ReplaceComponents(replacements); | 89 return url.ReplaceComponents(replacements); |
| 88 } | 90 } |
| 89 | 91 |
| 90 // Used before we have any certificate fingerprint. | 92 // Class verifies certificate by its fingerprint received using different |
| 91 class FailingCertVerifier : public net::CertVerifier { | 93 // channel. It's the only know information about device with self-signed |
| 92 public: | 94 // certificate. |
| 93 int Verify(net::X509Certificate* cert, | |
| 94 const std::string& hostname, | |
| 95 const std::string& ocsp_response, | |
| 96 int flags, | |
| 97 net::CRLSet* crl_set, | |
| 98 net::CertVerifyResult* verify_result, | |
| 99 const net::CompletionCallback& callback, | |
| 100 scoped_ptr<Request>* out_req, | |
| 101 const net::BoundNetLog& net_log) override { | |
| 102 verify_result->verified_cert = cert; | |
| 103 verify_result->cert_status = net::CERT_STATUS_INVALID; | |
| 104 return net::ERR_CERT_INVALID; | |
| 105 } | |
| 106 }; | |
| 107 | |
| 108 // Used before when we have the certificate fingerprint. | |
| 109 // Privet v3 devices should supports https but with self-signed sertificates. | |
| 110 // So normal validation is not usefull. | |
| 111 // Before using https Privet v3 pairing generates same secret on device and | |
| 112 // client side Spake2 on insecure channel. Than device sends fingerprint | |
| 113 // to client using same insecure channel. fingerprint is signed with the secret | |
| 114 // generated before. | |
| 115 // More info on pairing: | |
| 116 // https://developers.google.com/cloud-devices/v1/reference/local-api/pairing_st art | |
| 117 class FingerprintVerifier : public net::CertVerifier { | 95 class FingerprintVerifier : public net::CertVerifier { |
| 118 public: | 96 public: |
| 119 explicit FingerprintVerifier( | 97 explicit FingerprintVerifier( |
| 120 const net::SHA256HashValue& certificate_fingerprint) | 98 const net::SHA256HashValue& certificate_fingerprint) |
| 121 : certificate_fingerprint_(certificate_fingerprint) {} | 99 : certificate_fingerprint_(certificate_fingerprint) {} |
| 122 | 100 |
| 123 int Verify(net::X509Certificate* cert, | 101 int Verify(net::X509Certificate* cert, |
| 124 const std::string& hostname, | 102 const std::string& hostname, |
| 125 const std::string& ocsp_response, | 103 const std::string& ocsp_response, |
| 126 int flags, | 104 int flags, |
| 127 net::CRLSet* crl_set, | 105 net::CRLSet* crl_set, |
| 128 net::CertVerifyResult* verify_result, | 106 net::CertVerifyResult* verify_result, |
| 129 const net::CompletionCallback& callback, | 107 const net::CompletionCallback& callback, |
| 130 scoped_ptr<Request>* out_req, | 108 scoped_ptr<Request>* out_req, |
| 131 const net::BoundNetLog& net_log) override { | 109 const net::BoundNetLog& net_log) override { |
| 132 // Mark certificat as invalid as we didn't check that. | 110 // Mark certificate as invalid as we didn't check it. |
| 111 verify_result->Reset(); | |
| 133 verify_result->verified_cert = cert; | 112 verify_result->verified_cert = cert; |
| 134 verify_result->cert_status = net::CERT_STATUS_INVALID; | 113 verify_result->cert_status = net::CERT_STATUS_INVALID; |
| 135 | 114 |
| 136 auto fingerprint = | 115 auto fingerprint = |
| 137 net::X509Certificate::CalculateFingerprint256(cert->os_cert_handle()); | 116 net::X509Certificate::CalculateFingerprint256(cert->os_cert_handle()); |
| 138 | 117 |
| 139 return certificate_fingerprint_.Equals(fingerprint) ? net::OK | 118 return certificate_fingerprint_.Equals(fingerprint) ? net::OK |
| 140 : net::ERR_CERT_INVALID; | 119 : net::ERR_CERT_INVALID; |
| 141 } | 120 } |
| 142 | 121 |
| 143 private: | 122 private: |
| 144 net::SHA256HashValue certificate_fingerprint_; | 123 net::SHA256HashValue certificate_fingerprint_; |
| 145 | 124 |
| 146 DISALLOW_COPY_AND_ASSIGN(FingerprintVerifier); | 125 DISALLOW_COPY_AND_ASSIGN(FingerprintVerifier); |
| 147 }; | 126 }; |
| 148 | 127 |
| 149 class PrivetContextGetter : public net::URLRequestContextGetter { | 128 class PrivetContextGetter : public net::URLRequestContextGetter { |
| 150 public: | 129 public: |
| 151 PrivetContextGetter( | 130 PrivetContextGetter( |
| 152 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner, | 131 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner, |
| 153 const net::SHA256HashValue& certificate_fingerprint) | 132 const net::SHA256HashValue& certificate_fingerprint) |
| 154 : verifier_(new FingerprintVerifier(certificate_fingerprint)), | 133 : verifier_(new FingerprintVerifier(certificate_fingerprint)), |
| 155 net_task_runner_(net_task_runner) {} | 134 net_task_runner_(net_task_runner) { |
| 156 | 135 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 157 // Don't allow any https without fingerprint. Device with valid certificate | 136 switches::kEnablePrivetV3)); |
| 158 // may be different from the one which user is trying to pair. | 137 } |
| 159 explicit PrivetContextGetter( | |
| 160 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner) | |
| 161 : verifier_(new FailingCertVerifier()), | |
| 162 net_task_runner_(net_task_runner) {} | |
| 163 | 138 |
| 164 net::URLRequestContext* GetURLRequestContext() override { | 139 net::URLRequestContext* GetURLRequestContext() override { |
| 140 DCHECK(net_task_runner_->BelongsToCurrentThread()); | |
| 165 if (!context_) { | 141 if (!context_) { |
| 166 net::URLRequestContextBuilder builder; | 142 net::URLRequestContextBuilder builder; |
| 167 builder.set_proxy_service(net::ProxyService::CreateDirect()); | 143 builder.set_proxy_service(net::ProxyService::CreateDirect()); |
| 168 builder.SetSpdyAndQuicEnabled(false, false); | 144 builder.SetSpdyAndQuicEnabled(false, false); |
| 169 builder.DisableHttpCache(); | 145 builder.DisableHttpCache(); |
| 170 builder.SetCertVerifier(verifier_.Pass()); | 146 builder.SetCertVerifier(verifier_.Pass()); |
| 171 builder.set_user_agent(::GetUserAgent()); | 147 builder.set_user_agent(::GetUserAgent()); |
| 172 context_ = builder.Build(); | 148 context_ = builder.Build(); |
| 173 } | 149 } |
| 174 return context_.get(); | 150 return context_.get(); |
| 175 } | 151 } |
| 176 | 152 |
| 177 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() | 153 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() |
| 178 const override { | 154 const override { |
| 179 return net_task_runner_; | 155 return net_task_runner_; |
| 180 } | 156 } |
| 181 | 157 |
| 182 protected: | 158 protected: |
| 183 ~PrivetContextGetter() override = default; | 159 ~PrivetContextGetter() override { |
| 160 DCHECK(net_task_runner_->BelongsToCurrentThread()); | |
| 161 } | |
| 184 | 162 |
| 185 private: | 163 private: |
| 186 scoped_ptr<net::CertVerifier> verifier_; | 164 scoped_ptr<net::CertVerifier> verifier_; |
| 187 scoped_ptr<net::URLRequestContext> context_; | 165 scoped_ptr<net::URLRequestContext> context_; |
| 188 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner_; | 166 scoped_refptr<base::SingleThreadTaskRunner> net_task_runner_; |
| 189 | 167 |
| 190 DISALLOW_COPY_AND_ASSIGN(PrivetContextGetter); | 168 DISALLOW_COPY_AND_ASSIGN(PrivetContextGetter); |
| 191 }; | 169 }; |
| 192 | 170 |
| 193 } // namespace | 171 } // namespace |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 } | 602 } |
| 625 | 603 |
| 626 url_fetcher_ = | 604 url_fetcher_ = |
| 627 privet_client_->CreateURLFetcher(url, net::URLFetcher::POST, this); | 605 privet_client_->CreateURLFetcher(url, net::URLFetcher::POST, this); |
| 628 | 606 |
| 629 if (!use_pdf_) { | 607 if (!use_pdf_) { |
| 630 url_fetcher_->SetUploadFilePath(kPrivetContentTypePWGRaster, | 608 url_fetcher_->SetUploadFilePath(kPrivetContentTypePWGRaster, |
| 631 pwg_file_path_); | 609 pwg_file_path_); |
| 632 } else { | 610 } else { |
| 633 // TODO(noamsml): Move to file-based upload data? | 611 // TODO(noamsml): Move to file-based upload data? |
| 634 std::string data_str((const char*)data_->front(), data_->size()); | 612 std::string data_str((const char*)data_->front(), data_->size()); |
|
Ryan Sleevi
2015/10/30 23:17:27
STYLE: This violates the style-guide rules on cast
Vitaly Buka (NO REVIEWS)
2015/10/31 03:55:35
Done.
| |
| 635 url_fetcher_->SetUploadData(kPrivetContentTypePDF, data_str); | 613 url_fetcher_->SetUploadData(kPrivetContentTypePDF, data_str); |
| 636 } | 614 } |
| 637 | 615 |
| 638 url_fetcher_->Start(); | 616 url_fetcher_->Start(); |
| 639 } | 617 } |
| 640 | 618 |
| 641 void PrivetLocalPrintOperationImpl::StartPrinting() { | 619 void PrivetLocalPrintOperationImpl::StartPrinting() { |
| 642 if (has_extended_workflow_ && jobid_.empty()) { | 620 if (has_extended_workflow_ && jobid_.empty()) { |
| 643 DoCreatejob(); | 621 DoCreatejob(); |
| 644 } else { | 622 } else { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 | 770 |
| 793 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( | 771 void PrivetLocalPrintOperationImpl::SetPWGRasterConverterForTesting( |
| 794 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { | 772 scoped_ptr<PWGRasterConverter> pwg_raster_converter) { |
| 795 pwg_raster_converter_ = pwg_raster_converter.Pass(); | 773 pwg_raster_converter_ = pwg_raster_converter.Pass(); |
| 796 } | 774 } |
| 797 #endif // ENABLE_PRINT_PREVIEW | 775 #endif // ENABLE_PRINT_PREVIEW |
| 798 | 776 |
| 799 PrivetHTTPClientImpl::PrivetHTTPClientImpl( | 777 PrivetHTTPClientImpl::PrivetHTTPClientImpl( |
| 800 const std::string& name, | 778 const std::string& name, |
| 801 const net::HostPortPair& host_port, | 779 const net::HostPortPair& host_port, |
| 802 net::URLRequestContextGetter* request_context) | 780 const scoped_refptr<net::URLRequestContextGetter>& context_getter) |
| 803 : PrivetHTTPClientImpl(name, | 781 : name_(name), context_getter_(context_getter), host_port_(host_port) {} |
| 804 host_port, | |
| 805 request_context->GetNetworkTaskRunner()) {} | |
| 806 | |
| 807 PrivetHTTPClientImpl::PrivetHTTPClientImpl( | |
| 808 const std::string& name, | |
| 809 const net::HostPortPair& host_port, | |
| 810 const scoped_refptr<base::SingleThreadTaskRunner>& net_task_runner) | |
| 811 : name_(name), | |
| 812 context_getter_(new PrivetContextGetter(net_task_runner)), | |
| 813 host_port_(host_port) {} | |
| 814 | 782 |
| 815 PrivetHTTPClientImpl::~PrivetHTTPClientImpl() { | 783 PrivetHTTPClientImpl::~PrivetHTTPClientImpl() { |
| 816 } | 784 } |
| 817 | 785 |
| 818 const std::string& PrivetHTTPClientImpl::GetName() { | 786 const std::string& PrivetHTTPClientImpl::GetName() { |
| 819 return name_; | 787 return name_; |
| 820 } | 788 } |
| 821 | 789 |
| 822 scoped_ptr<PrivetJSONOperation> PrivetHTTPClientImpl::CreateInfoOperation( | 790 scoped_ptr<PrivetJSONOperation> PrivetHTTPClientImpl::CreateInfoOperation( |
| 823 const PrivetJSONOperation::ResultCallback& callback) { | 791 const PrivetJSONOperation::ResultCallback& callback) { |
| 824 return scoped_ptr<PrivetJSONOperation>( | 792 return scoped_ptr<PrivetJSONOperation>( |
| 825 new PrivetInfoOperationImpl(this, callback)); | 793 new PrivetInfoOperationImpl(this, callback)); |
| 826 } | 794 } |
| 827 | 795 |
| 828 scoped_ptr<PrivetURLFetcher> PrivetHTTPClientImpl::CreateURLFetcher( | 796 scoped_ptr<PrivetURLFetcher> PrivetHTTPClientImpl::CreateURLFetcher( |
| 829 const GURL& url, | 797 const GURL& url, |
| 830 net::URLFetcher::RequestType request_type, | 798 net::URLFetcher::RequestType request_type, |
| 831 PrivetURLFetcher::Delegate* delegate) { | 799 PrivetURLFetcher::Delegate* delegate) { |
| 832 GURL::Replacements replacements; | 800 GURL::Replacements replacements; |
| 833 replacements.SetHostStr(host_port_.host()); | 801 replacements.SetHostStr(host_port_.host()); |
|
Ryan Sleevi
2015/10/30 23:17:27
BUG? Should this be HostForURL()? Do you not have
Vitaly Buka (NO REVIEWS)
2015/10/31 03:55:35
All tests with IPv4. We had IPv6 working, so i nee
| |
| 834 std::string port = base::UintToString(host_port_.port()); | 802 std::string port = base::UintToString(host_port_.port()); |
| 835 replacements.SetPortStr(port); | 803 replacements.SetPortStr(port); |
| 836 std::string scheme = IsInHttpsMode() ? "https" : "http"; | 804 std::string scheme = IsInHttpsMode() ? "https" : "http"; |
| 837 replacements.SetSchemeStr(scheme); | 805 replacements.SetSchemeStr(scheme); |
| 838 return scoped_ptr<PrivetURLFetcher>( | 806 return scoped_ptr<PrivetURLFetcher>( |
| 839 new PrivetURLFetcher(url.ReplaceComponents(replacements), request_type, | 807 new PrivetURLFetcher(url.ReplaceComponents(replacements), request_type, |
| 840 context_getter_, delegate)); | 808 context_getter_, delegate)); |
| 841 } | 809 } |
| 842 | 810 |
| 843 void PrivetHTTPClientImpl::RefreshPrivetToken( | 811 void PrivetHTTPClientImpl::RefreshPrivetToken( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 PrivetLocalPrintOperation::Delegate* delegate) { | 890 PrivetLocalPrintOperation::Delegate* delegate) { |
| 923 #if defined(ENABLE_PRINT_PREVIEW) | 891 #if defined(ENABLE_PRINT_PREVIEW) |
| 924 return scoped_ptr<PrivetLocalPrintOperation>( | 892 return scoped_ptr<PrivetLocalPrintOperation>( |
| 925 new PrivetLocalPrintOperationImpl(info_client(), delegate)); | 893 new PrivetLocalPrintOperationImpl(info_client(), delegate)); |
| 926 #else | 894 #else |
| 927 return scoped_ptr<PrivetLocalPrintOperation>(); | 895 return scoped_ptr<PrivetLocalPrintOperation>(); |
| 928 #endif // ENABLE_PRINT_PREVIEW | 896 #endif // ENABLE_PRINT_PREVIEW |
| 929 } | 897 } |
| 930 | 898 |
| 931 } // namespace local_discovery | 899 } // namespace local_discovery |
| OLD | NEW |