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/firewalld_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 FirewalldDBusProxy::FirewalldDBusProxy(
     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::FirewalldProxy(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(&FirewalldDBusProxy::OnServiceOwnerChanged,
     41                  weak_factory_.GetWeakPtr()));
     42 
     43   // One time callback when service becomes available.
     44   proxy_->GetObjectProxy()->WaitForServiceToBeAvailable(
     45       base::Bind(&FirewalldDBusProxy::OnServiceAvailable,
     46                  weak_factory_.GetWeakPtr()));
     47 }
     48 
     49 FirewalldDBusProxy::~FirewalldDBusProxy() {}
     50 
     51 bool FirewalldDBusProxy::RequestUdpPortAccess(const string& interface,
     52                                                      uint16_t port) {
     53   if (!service_available_) {
     54     LOG(ERROR) << "firewalld service not available";
     55     return false;
     56   }
     57 
     58   bool success = false;
     59   brillo::ErrorPtr error;
     60   if (!proxy_->PunchUdpHole(port, interface, &success, &error)) {
     61     LOG(ERROR) << "Failed to request UDP port access: "
     62                << error->GetCode() << " " << error->GetMessage();
     63     return false;
     64   }
     65   if (!success) {
     66     LOG(ERROR) << "Access request for UDP port " << port
     67                << " on interface " << interface << " is denied";
     68     return false;
     69   }
     70   LOG(INFO) << "Access granted for UDP port " << port
     71             << " on interface " << interface;
     72   return true;
     73 }
     74 
     75 bool FirewalldDBusProxy::ReleaseUdpPortAccess(const string& interface,
     76                                                      uint16_t port) {
     77   if (!service_available_) {
     78     LOG(ERROR) << "firewalld service not available";
     79     return false;
     80   }
     81 
     82   brillo::ErrorPtr error;
     83   bool success;
     84   if (!proxy_->PlugUdpHole(port, interface, &success, &error)) {
     85     LOG(ERROR) << "Failed to release UDP port access: "
     86                << error->GetCode() << " " << error->GetMessage();
     87     return false;
     88   }
     89   if (!success) {
     90     LOG(ERROR) << "Release request for UDP port " << port
     91                << " on interface " << interface << " is denied";
     92     return false;
     93   }
     94   LOG(INFO) << "Access released for UDP port " << port
     95             << " on interface " << interface;
     96   return true;
     97 }
     98 
     99 void FirewalldDBusProxy::OnServiceAvailable(bool available) {
    100   LOG(INFO) << __func__ << ": " << available;
    101   // The callback might invoke calls to the ObjectProxy, so defer the callback
    102   // to event loop.
    103   if (available && !service_appeared_callback_.is_null()) {
    104     dispatcher_->PostTask(service_appeared_callback_);
    105   } else if (!available && !service_vanished_callback_.is_null()) {
    106     dispatcher_->PostTask(service_vanished_callback_);
    107   }
    108   service_available_ = available;
    109 }
    110 
    111 void FirewalldDBusProxy::OnServiceOwnerChanged(const string& old_owner,
    112                                                const string& new_owner) {
    113   LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner;
    114   if (new_owner.empty()) {
    115     OnServiceAvailable(false);
    116   } else {
    117     OnServiceAvailable(true);
    118   }
    119 }
    120 
    121 }  // namespace apmanager
    122