Permalink
Browse files

interfaces: implement dbus-access interface

The dbus-access interface allows apps within the same snap to
communicate over dbus. It can be used in conjunction of the
dbus-name interface to setup up dbus service which don't need
to be accesible from another snap in the system.

Connecting the interface on between plugs and slots which are
not part of the same snap is prohibited and will cause the
interface connection to fail.

Signed-off-by: Simon Fels <simon.fels@canonical.com>
  • Loading branch information...
1 parent 7d4a725 commit 38d60ce083d1684b20d7394ad5f6824a298efd9d Simon Fels committed May 13, 2016
Showing with 112 additions and 0 deletions.
  1. +1 −0 interfaces/builtin/all.go
  2. +109 −0 interfaces/builtin/dbus_access.go
  3. +2 −0 interfaces/core.go
@@ -26,6 +26,7 @@ import (
var allInterfaces = []interfaces.Interface{
&BoolFileInterface{},
&BluezInterface{},
+ &DBusAccessInterface{},
&DBusNameInterface{},
&NetworkManagerInterface{},
NewFirewallControlInterface(),
@@ -0,0 +1,109 @@
+// -*- Mode: Go; indent-tabs-mode: t -*-
+
+/*
+ * Copyright (C) 2016 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package builtin
+
+import (
+ "fmt"
+ "bytes"
+
+ "github.com/ubuntu-core/snappy/interfaces"
+)
+
+var dbusAccessPermanentSlotAppArmor = []byte(`
+#include <abstractions/dbus-strict>
+
+# Allow binding the service to the requested connection name
+dbus (receive, send)
+ bus=system
+ path=###SLOT_PATH_NAME###
+ peer=(label=###SLOT_SECURITY_TAGS##),
+`)
+
+type DBusAccessInterface struct{}
+
+func (iface *DBusAccessInterface) Name() string {
+ return "dbus-access"
+}
+
+func (iface *DBusAccessInterface) PermanentPlugSnippet(plug *interfaces.Plug, securitySystem interfaces.SecuritySystem) ([]byte, error) {
+ switch securitySystem {
+ case interfaces.SecurityAppArmor:
+ return nil, nil
+ case interfaces.SecurityDBus, interfaces.SecuritySecComp, interfaces.SecurityUDev:
+ return nil, nil
+ default:
+ return nil, interfaces.ErrUnknownSecurity
+ }
+}
+
+
+func (iface *DBusAccessInterface) ConnectedPlugSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
+ switch securitySystem {
+ case interfaces.SecurityDBus:
+ return nil, nil
+ case interfaces.SecurityAppArmor:
+ return nil, nil
+ case interfaces.SecuritySecComp:
+ return dbusNameConnectedPlugSecComp, nil
+ case interfaces.SecurityUDev:
+ return nil, nil
+ default:
+ return nil, interfaces.ErrUnknownSecurity
+ }
+}
+
+func (iface *DBusAccessInterface) PermanentSlotSnippet(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
+ path, _ := slot.Attrs["path"].(string)
+
+ switch securitySystem {
+ case interfaces.SecurityAppArmor:
+ snippet := bytes.Replace(dbusAccessPermanentSlotAppArmor, []byte("###SLOT_PATH_NAME###"), []byte(path), -1)
+ snippet = bytes.Replace(snippet, []byte("###SLOT_SECURITY_TAGS###"), slotAppLabelExpr(slot), -1)
+ return nil, nil
+ case interfaces.SecurityDBus, interfaces.SecuritySecComp, interfaces.SecurityUDev:
+ return nil, nil
+ default:
+ return nil, interfaces.ErrUnknownSecurity
+ }
+}
+
+func (iface *DBusAccessInterface) ConnectedSlotSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
+ switch securitySystem {
+ case interfaces.SecurityDBus, interfaces.SecurityAppArmor, interfaces.SecuritySecComp, interfaces.SecurityUDev:
+ return nil, nil
+ default:
+ return nil, interfaces.ErrUnknownSecurity
+ }
+}
+
+func (iface *DBusAccessInterface) SanitizePlug(plug *interfaces.Plug) error {
+ if iface.Name() != plug.Interface {
+ panic(fmt.Sprintf("plug is not of interface %q", iface))
+ }
+ return nil
+}
+
+func (iface *DBusAccessInterface) SanitizeSlot(slot *interfaces.Slot) error {
+ return nil
+}
+
+func (iface *DBusAccessInterface) AutoConnect() bool {
+ return false
+}
View
@@ -157,6 +157,8 @@ const (
var (
// ErrUnknownSecurity is reported when a interface is unable to deal with a given security system.
ErrUnknownSecurity = errors.New("unknown security system")
+ // ErrNotAllowed is reported when a slot/plug connection on the interface is not allowed
+ ErrNotAllowed = errors.New("interface connection is not allowed")
@zyga

zyga May 13, 2016

How do you plan to use this?

)
// Regular expression describing correct identifiers.

0 comments on commit 38d60ce

Please sign in to comment.