Peter Qiu | 9b2ecc4 | 2015-09-17 14:37:22 -0700 | [diff] [blame] | 1 | // |
| 2 | // Copyright (C) 2015 The Android Open Source Project |
| 3 | // |
| 4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | // you may not use this file except in compliance with the License. |
| 6 | // You may obtain a copy of the License at |
| 7 | // |
| 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | // |
| 10 | // Unless required by applicable law or agreed to in writing, software |
| 11 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | // See the License for the specific language governing permissions and |
| 14 | // limitations under the License. |
| 15 | // |
| 16 | |
Peter Qiu | 5808396 | 2015-11-05 14:29:50 -0800 | [diff] [blame] | 17 | #include "apmanager/dbus/permission_broker_dbus_proxy.h" |
Peter Qiu | 9b2ecc4 | 2015-09-17 14:37:22 -0700 | [diff] [blame] | 18 | |
| 19 | #include <base/bind.h> |
Alex Vakulenko | 8d0c31b | 2015-10-13 09:14:24 -0700 | [diff] [blame] | 20 | #include <brillo/errors/error.h> |
Peter Qiu | 9b2ecc4 | 2015-09-17 14:37:22 -0700 | [diff] [blame] | 21 | |
| 22 | #include "apmanager/event_dispatcher.h" |
| 23 | |
| 24 | using std::string; |
| 25 | |
| 26 | namespace apmanager { |
| 27 | |
| 28 | PermissionBrokerDBusProxy::PermissionBrokerDBusProxy( |
| 29 | const scoped_refptr<dbus::Bus>& bus, |
| 30 | const base::Closure& service_appeared_callback, |
| 31 | const base::Closure& service_vanished_callback) |
| 32 | : proxy_(new org::chromium::PermissionBrokerProxy(bus)), |
| 33 | dispatcher_(EventDispatcher::GetInstance()), |
| 34 | service_appeared_callback_(service_appeared_callback), |
| 35 | service_vanished_callback_(service_vanished_callback), |
| 36 | service_available_(false) { |
| 37 | // Monitor service owner changes. This callback lives for the lifetime of |
| 38 | // the ObjectProxy. |
| 39 | proxy_->GetObjectProxy()->SetNameOwnerChangedCallback( |
| 40 | base::Bind(&PermissionBrokerDBusProxy::OnServiceOwnerChanged, |
| 41 | weak_factory_.GetWeakPtr())); |
| 42 | |
| 43 | // One time callback when service becomes available. |
| 44 | proxy_->GetObjectProxy()->WaitForServiceToBeAvailable( |
| 45 | base::Bind(&PermissionBrokerDBusProxy::OnServiceAvailable, |
| 46 | weak_factory_.GetWeakPtr())); |
| 47 | |
| 48 | // Setup lifeline pipe to allow permission_broker to monitor this process, |
| 49 | // so it can automatically remove the firewall rules when this process |
| 50 | // crashed. |
| 51 | int fds[2]; |
| 52 | CHECK(pipe(fds) == 0) << "Failed to create lifeline pipe"; |
| 53 | lifeline_read_fd_ = fds[0]; |
| 54 | lifeline_write_fd_ = fds[1]; |
| 55 | } |
| 56 | |
| 57 | PermissionBrokerDBusProxy::~PermissionBrokerDBusProxy() { |
| 58 | close(lifeline_read_fd_); |
| 59 | close(lifeline_write_fd_); |
| 60 | } |
| 61 | |
| 62 | bool PermissionBrokerDBusProxy::RequestUdpPortAccess(const string& interface, |
| 63 | uint16_t port) { |
| 64 | if (!service_available_) { |
| 65 | LOG(ERROR) << "permission_broker service not available"; |
| 66 | return false; |
| 67 | } |
| 68 | |
| 69 | // Pass the read end of the pipe to permission_broker, to allow it to |
| 70 | // monitor on this process. |
| 71 | dbus::FileDescriptor fd(lifeline_read_fd_); |
| 72 | fd.CheckValidity(); |
| 73 | bool allowed = false; |
Alex Vakulenko | 8d0c31b | 2015-10-13 09:14:24 -0700 | [diff] [blame] | 74 | brillo::ErrorPtr error; |
Peter Qiu | 9b2ecc4 | 2015-09-17 14:37:22 -0700 | [diff] [blame] | 75 | if (!proxy_->RequestUdpPortAccess(port, interface, fd, &allowed, &error)) { |
| 76 | LOG(ERROR) << "Failed to request UDP port access: " |
| 77 | << error->GetCode() << " " << error->GetMessage(); |
| 78 | return false; |
| 79 | } |
| 80 | if (!allowed) { |
| 81 | LOG(ERROR) << "Access request for UDP port " << port |
| 82 | << " on interface " << interface << " is denied"; |
| 83 | return false; |
| 84 | } |
| 85 | LOG(INFO) << "Access granted for UDP port " << port |
| 86 | << " on interface " << interface; |
| 87 | return true; |
| 88 | } |
| 89 | |
| 90 | bool PermissionBrokerDBusProxy::ReleaseUdpPortAccess(const string& interface, |
| 91 | uint16_t port) { |
| 92 | if (!service_available_) { |
| 93 | LOG(ERROR) << "permission_broker service not available"; |
| 94 | return false; |
| 95 | } |
| 96 | |
Alex Vakulenko | 8d0c31b | 2015-10-13 09:14:24 -0700 | [diff] [blame] | 97 | brillo::ErrorPtr error; |
Peter Qiu | 9b2ecc4 | 2015-09-17 14:37:22 -0700 | [diff] [blame] | 98 | bool success; |
| 99 | if (!proxy_->ReleaseUdpPort(port, interface, &success, &error)) { |
| 100 | LOG(ERROR) << "Failed to release UDP port access: " |
| 101 | << error->GetCode() << " " << error->GetMessage(); |
| 102 | return false; |
| 103 | } |
| 104 | if (!success) { |
| 105 | LOG(ERROR) << "Release request for UDP port " << port |
| 106 | << " on interface " << interface << " is denied"; |
| 107 | return false; |
| 108 | } |
| 109 | LOG(INFO) << "Access released for UDP port " << port |
| 110 | << " on interface " << interface; |
| 111 | return true; |
| 112 | } |
| 113 | |
| 114 | void PermissionBrokerDBusProxy::OnServiceAvailable(bool available) { |
| 115 | LOG(INFO) << __func__ << ": " << available; |
| 116 | // The callback might invoke calls to the ObjectProxy, so defer the callback |
| 117 | // to event loop. |
| 118 | if (available && !service_appeared_callback_.is_null()) { |
| 119 | dispatcher_->PostTask(service_appeared_callback_); |
| 120 | } else if (!available && !service_vanished_callback_.is_null()) { |
| 121 | dispatcher_->PostTask(service_vanished_callback_); |
| 122 | } |
| 123 | service_available_ = available; |
| 124 | } |
| 125 | |
| 126 | void PermissionBrokerDBusProxy::OnServiceOwnerChanged(const string& old_owner, |
| 127 | const string& new_owner) { |
| 128 | LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner; |
| 129 | if (new_owner.empty()) { |
| 130 | OnServiceAvailable(false); |
| 131 | } else { |
| 132 | OnServiceAvailable(true); |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | } // namespace apmanager |