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
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
6
7#include "base/bind.h"
8#include "base/callback_helpers.h"
9#include "content/browser/child_process_security_policy_impl.h"
10#include "content/browser/media/webrtc_identity_store.h"
11#include "content/common/media/webrtc_identity_messages.h"
12#include "net/base/net_errors.h"
13
14namespace content {
15
16WebRTCIdentityServiceHost::WebRTCIdentityServiceHost(
17    int renderer_process_id,
18    scoped_refptr<WebRTCIdentityStore> identity_store)
19    : BrowserMessageFilter(WebRTCIdentityMsgStart),
20      renderer_process_id_(renderer_process_id),
21      identity_store_(identity_store),
22      weak_factory_(this) {}
23
24WebRTCIdentityServiceHost::~WebRTCIdentityServiceHost() {
25  if (!cancel_callback_.is_null())
26    cancel_callback_.Run();
27}
28
29bool WebRTCIdentityServiceHost::OnMessageReceived(const IPC::Message& message) {
30  bool handled = true;
31  IPC_BEGIN_MESSAGE_MAP(WebRTCIdentityServiceHost, message)
32    IPC_MESSAGE_HANDLER(WebRTCIdentityMsg_RequestIdentity, OnRequestIdentity)
33    IPC_MESSAGE_HANDLER(WebRTCIdentityMsg_CancelRequest, OnCancelRequest)
34    IPC_MESSAGE_UNHANDLED(handled = false)
35  IPC_END_MESSAGE_MAP()
36  return handled;
37}
38
39void WebRTCIdentityServiceHost::OnRequestIdentity(
40    int sequence_number,
41    const GURL& origin,
42    const std::string& identity_name,
43    const std::string& common_name) {
44  if (!cancel_callback_.is_null()) {
45    DLOG(WARNING)
46        << "Request rejected because the previous request has not finished.";
47    SendErrorMessage(sequence_number, net::ERR_INSUFFICIENT_RESOURCES);
48    return;
49  }
50
51  ChildProcessSecurityPolicyImpl* policy =
52      ChildProcessSecurityPolicyImpl::GetInstance();
53  if (!policy->CanAccessCookiesForOrigin(renderer_process_id_, origin)) {
54    DLOG(WARNING) << "Request rejected because origin access is denied.";
55    SendErrorMessage(sequence_number, net::ERR_ACCESS_DENIED);
56    return;
57  }
58
59  cancel_callback_ = identity_store_->RequestIdentity(
60      origin,
61      identity_name,
62      common_name,
63      base::Bind(&WebRTCIdentityServiceHost::OnComplete,
64                 weak_factory_.GetWeakPtr(),
65                 sequence_number));
66  if (cancel_callback_.is_null()) {
67    SendErrorMessage(sequence_number, net::ERR_UNEXPECTED);
68  }
69}
70
71void WebRTCIdentityServiceHost::OnCancelRequest() {
72  // cancel_callback_ may be null if we have sent the reponse to the renderer
73  // but the renderer has not received it.
74  if (!cancel_callback_.is_null())
75    base::ResetAndReturn(&cancel_callback_).Run();
76}
77
78void WebRTCIdentityServiceHost::OnComplete(int sequence_number,
79                                           int status,
80                                           const std::string& certificate,
81                                           const std::string& private_key) {
82  cancel_callback_.Reset();
83  if (status == net::OK) {
84    Send(new WebRTCIdentityHostMsg_IdentityReady(
85        sequence_number, certificate, private_key));
86  } else {
87    SendErrorMessage(sequence_number, status);
88  }
89}
90
91void WebRTCIdentityServiceHost::SendErrorMessage(int sequence_number,
92                                                 int error) {
93  Send(new WebRTCIdentityHostMsg_RequestFailed(sequence_number, error));
94}
95
96}  // namespace content
97