Home | History | Annotate | Download | only in dbus
      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 
     17 #include "apmanager/dbus/permission_broker_dbus_proxy.h"
     18 
     19 #include <base/bind.h>
     20 #include <brillo/errors/error.h>
     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;
     74   brillo::ErrorPtr error;
     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 
     97   brillo::ErrorPtr error;
     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
    137