diff options
author | Peter Qiu <zqiu@google.com> | 2015-09-17 14:43:48 -0700 |
---|---|---|
committer | Peter Qiu <zqiu@google.com> | 2015-09-17 14:47:30 -0700 |
commit | 871ad3630238df1a714d7afbed07388c5859a252 (patch) | |
tree | cb8f415933686e1a4de63c270a815ea45522a75d | |
parent | 9b2ecc45cd5cf99e0ced28d4b522e6dee5b52968 (diff) | |
download | apmanager-871ad3630238df1a714d7afbed07388c5859a252.tar.gz |
Add firewalld implementation for FirewallProxyInterface
This implementation wiil be used on Android, where permission_broker
doesn't exist.
Bug: 23757625
TEST=Manually update apmanager.gyp to compile firewalld_dbus_proxy.cc
Change-Id: I7bf0ee2377bcb89730587ee4ab4c5d8b21badf53
-rw-r--r-- | firewalld_dbus_proxy.cc | 121 | ||||
-rw-r--r-- | firewalld_dbus_proxy.h | 65 |
2 files changed, 186 insertions, 0 deletions
diff --git a/firewalld_dbus_proxy.cc b/firewalld_dbus_proxy.cc new file mode 100644 index 0000000..3207b1d --- /dev/null +++ b/firewalld_dbus_proxy.cc @@ -0,0 +1,121 @@ +// +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "apmanager/firewalld_dbus_proxy.h" + +#include <base/bind.h> +#include <chromeos/errors/error.h> + +#include "apmanager/event_dispatcher.h" + +using std::string; + +namespace apmanager { + +FirewalldDBusProxy::FirewalldDBusProxy( + const scoped_refptr<dbus::Bus>& bus, + const base::Closure& service_appeared_callback, + const base::Closure& service_vanished_callback) + : proxy_(new org::chromium::FirewalldProxy(bus)), + dispatcher_(EventDispatcher::GetInstance()), + service_appeared_callback_(service_appeared_callback), + service_vanished_callback_(service_vanished_callback), + service_available_(false) { + // Monitor service owner changes. This callback lives for the lifetime of + // the ObjectProxy. + proxy_->GetObjectProxy()->SetNameOwnerChangedCallback( + base::Bind(&FirewalldDBusProxy::OnServiceOwnerChanged, + weak_factory_.GetWeakPtr())); + + // One time callback when service becomes available. + proxy_->GetObjectProxy()->WaitForServiceToBeAvailable( + base::Bind(&FirewalldDBusProxy::OnServiceAvailable, + weak_factory_.GetWeakPtr())); +} + +FirewalldDBusProxy::~FirewalldDBusProxy() {} + +bool FirewalldDBusProxy::RequestUdpPortAccess(const string& interface, + uint16_t port) { + if (!service_available_) { + LOG(ERROR) << "firewalld service not available"; + return false; + } + + bool success = false; + chromeos::ErrorPtr error; + if (!proxy_->PunchUdpHole(port, interface, &success, &error)) { + LOG(ERROR) << "Failed to request UDP port access: " + << error->GetCode() << " " << error->GetMessage(); + return false; + } + if (!success) { + LOG(ERROR) << "Access request for UDP port " << port + << " on interface " << interface << " is denied"; + return false; + } + LOG(INFO) << "Access granted for UDP port " << port + << " on interface " << interface; + return true; +} + +bool FirewalldDBusProxy::ReleaseUdpPortAccess(const string& interface, + uint16_t port) { + if (!service_available_) { + LOG(ERROR) << "firewalld service not available"; + return false; + } + + chromeos::ErrorPtr error; + bool success; + if (!proxy_->PlugUdpHole(port, interface, &success, &error)) { + LOG(ERROR) << "Failed to release UDP port access: " + << error->GetCode() << " " << error->GetMessage(); + return false; + } + if (!success) { + LOG(ERROR) << "Release request for UDP port " << port + << " on interface " << interface << " is denied"; + return false; + } + LOG(INFO) << "Access released for UDP port " << port + << " on interface " << interface; + return true; +} + +void FirewalldDBusProxy::OnServiceAvailable(bool available) { + LOG(INFO) << __func__ << ": " << available; + // The callback might invoke calls to the ObjectProxy, so defer the callback + // to event loop. + if (available && !service_appeared_callback_.is_null()) { + dispatcher_->PostTask(service_appeared_callback_); + } else if (!available && !service_vanished_callback_.is_null()) { + dispatcher_->PostTask(service_vanished_callback_); + } + service_available_ = available; +} + +void FirewalldDBusProxy::OnServiceOwnerChanged(const string& old_owner, + const string& new_owner) { + LOG(INFO) << __func__ << " old: " << old_owner << " new: " << new_owner; + if (new_owner.empty()) { + OnServiceAvailable(false); + } else { + OnServiceAvailable(true); + } +} + +} // namespace apmanager diff --git a/firewalld_dbus_proxy.h b/firewalld_dbus_proxy.h new file mode 100644 index 0000000..9cb305b --- /dev/null +++ b/firewalld_dbus_proxy.h @@ -0,0 +1,65 @@ +// +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef APMANAGER_FIREWALLD_DBUS_PROXY_H_ +#define APMANAGER_FIREWALLD_DBUS_PROXY_H_ + +#include <string> + +#include <base/macros.h> +#include <base/memory/scoped_ptr.h> +#include <firewalld/dbus-proxies.h> + +#include "apmanager/firewall_proxy_interface.h" + +namespace apmanager { + +class EventDispatcher; + +class FirewalldDBusProxy : public FirewallProxyInterface { + public: + FirewalldDBusProxy(const scoped_refptr<dbus::Bus>& bus, + const base::Closure& service_appeared_callback, + const base::Closure& service_vanished_callback); + ~FirewalldDBusProxy() override; + + // Request/release access for an UDP port |port} on an interface |interface|. + bool RequestUdpPortAccess(const std::string& interface, + uint16_t port) override; + bool ReleaseUdpPortAccess(const std::string& interface, + uint16_t port) override; + + private: + // Called when service appeared or vanished. + void OnServiceAvailable(bool service_available); + + // Service name owner changed handler. + void OnServiceOwnerChanged(const std::string& old_owner, + const std::string& new_owner); + + std::unique_ptr<org::chromium::FirewalldProxy> proxy_; + EventDispatcher* dispatcher_; + base::Closure service_appeared_callback_; + base::Closure service_vanished_callback_; + bool service_available_; + + base::WeakPtrFactory<FirewalldDBusProxy> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(FirewalldDBusProxy); +}; + +} // namespace apmanager + +#endif // APMANAGER_FIREWALLD_DBUS_PROXY_H_ |