Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interfaces/builtin: add location interface #1118

Merged
merged 17 commits into from May 19, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions interfaces/builtin/all.go
Expand Up @@ -26,6 +26,7 @@ import (
var allInterfaces = []interfaces.Interface{
&BoolFileInterface{},
&BluezInterface{},
&LocationObserveInterface{},
&NetworkManagerInterface{},
NewFirewallControlInterface(),
NewHomeInterface(),
Expand Down
1 change: 1 addition & 0 deletions interfaces/builtin/all_test.go
Expand Up @@ -34,6 +34,7 @@ func (s *AllSuite) TestInterfaces(c *C) {
all := builtin.Interfaces()
c.Check(all, Contains, &builtin.BoolFileInterface{})
c.Check(all, Contains, &builtin.BluezInterface{})
c.Check(all, Contains, &builtin.LocationObserveInterface{})
c.Check(all, DeepContains, builtin.NewFirewallControlInterface())
c.Check(all, DeepContains, builtin.NewHomeInterface())
c.Check(all, DeepContains, builtin.NewLocaleControlInterface())
Expand Down
297 changes: 297 additions & 0 deletions interfaces/builtin/location_observe.go
@@ -0,0 +1,297 @@
// -*- 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 (
"bytes"

"github.com/ubuntu-core/snappy/interfaces"
)

var locationObservePermanentSlotAppArmor = []byte(`
# Description: Allow operating as the location service. Reserved because this
# gives privileged access to the system.
# Usage: reserved

# DBus accesses
#include <abstractions/dbus-strict>
dbus (send)
bus=system
path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member="{Request,Release}Name"
peer=(name=org.freedesktop.DBus, label=unconfined),

dbus (send)
bus=system
path=/org/freedesktop/DBus
interface=org.freedesktop.DBus
member="GetConnectionUnix{ProcessID,User}"
peer=(label=unconfined),

# Allow binding the service to the requested connection name
dbus (bind)
bus=system
name="com.ubuntu.location.Service",

dbus (receive, send)
bus=system
path=/com/ubuntu/location/Service{,/**}
interface=org.freedesktop.DBus**
peer=(label=unconfined),
`)

var locationObserveConnectedSlotAppArmor = []byte(`
# Allow connected clients to interact with the service

# Allow the service to host sessions
dbus (bind)
bus=system
name="com.ubuntu.location.Service.Session",

# Allow clients to create a session
dbus (receive)
bus=system
path=/com/ubuntu/location/Service
interface=com.ubuntu.location.Service
member=CreateSessionForCriteria
peer=(label=###PLUG_SECURITY_TAGS###),

# Allow clients to query service properties
dbus (receive)
bus=system
path=/com/ubuntu/location/Service
interface=org.freedesktop.DBus.Properties
member=Get
peer=(label=###PLUG_SECURITY_TAGS###),

# Allow clients to request starting/stopping updates
dbus (receive)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}PositionUpdates"
peer=(label=###PLUG_SECURITY_TAGS###),

dbus (receive)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}HeadingUpdates"
peer=(label=###PLUG_SECURITY_TAGS###),

dbus (receive)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}VelocityUpdates"
peer=(label=###PLUG_SECURITY_TAGS###),

# Allow the service to send updates to clients
dbus (send)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="Update{Position,Heading,Velocity}"
peer=(label=###PLUG_SECURITY_TAGS###),

dbus (send)
bus=system
path=/com/ubuntu/location/Service
interface=org.freedesktop.DBus.Properties
member=PropertiesChanged
peer=(label=###PLUG_SECURITY_TAGS###),
`)

var locationObserveConnectedPlugAppArmor = []byte(`
# Description: Allow using location service. Reserved because this gives
# privileged access to the service.
# Usage: reserved

#include <abstractions/dbus-strict>

# Allow clients to query service properties
dbus (send)
bus=system
path=/com/ubuntu/location/Service
interface=org.freedesktop.DBus.Properties
member=Get
peer=(label=###SLOT_SECURITY_TAGS###),

# Allow clients to create a session
dbus (send)
bus=system
path=/com/ubuntu/location/Service
interface=com.ubuntu.location.Service
member=CreateSessionForCriteria
peer=(label=###SLOT_SECURITY_TAGS###),

# Allow clients to request starting/stopping updates
dbus (send)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}PositionUpdates"
peer=(label=###SLOT_SECURITY_TAGS###),

dbus (send)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}HeadingUpdates"
peer=(label=###SLOT_SECURITY_TAGS###),

dbus (send)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="{Start,Stop}VelocityUpdates"
peer=(label=###SLOT_SECURITY_TAGS###),

# Allow clients to receive updates from the service
dbus (receive)
bus=system
path=/sessions/*
interface=com.ubuntu.location.Service.Session
member="Update{Position,Heading,Velocity}"
peer=(label=###SLOT_SECURITY_TAGS###),

dbus (receive)
bus=system
path=/com/ubuntu/location/Service
interface=org.freedesktop.DBus.Properties
member=PropertiesChanged
peer=(label=###SLOT_SECURITY_TAGS###),

dbus (receive)
bus=system
path=/
interface=org.freedesktop.DBus.ObjectManager
peer=(label=unconfined),
`)

var locationObservePermanentSlotSecComp = []byte(`
getsockname
recvmsg
sendmsg
sendto
`)

var locationObserveConnectedPlugSecComp = []byte(`
getsockname
recvmsg
sendmsg
sendto
`)

var locationObservePermanentSlotDBus = []byte(`
<policy user="root">
<allow own="com.ubuntu.location.Service"/>
<allow own="com.ubuntu.location.Service.Session"/>
<allow send_destination="com.ubuntu.location.Service"/>
<allow send_destination="com.ubuntu.location.Service.Session"/>
<allow send_interface="com.ubuntu.location.Service"/>
<allow send_interface="com.ubuntu.location.Service.Session"/>
</policy>
`)

var locationObserveConnectedPlugDBus = []byte(`
<policy context="default">
<deny own="com.ubuntu.location.Service"/>
<allow send_destination="com.ubuntu.location.Service"/>
<allow send_destination="com.ubuntu.location.Service.Session"/>
<allow send_interface="com.ubuntu.location.Service"/>
<allow send_interface="com.ubuntu.location.Service.Session"/>
</policy>
`)

type LocationObserveInterface struct{}

func (iface *LocationObserveInterface) Name() string {
return "location-observe"
}

func (iface *LocationObserveInterface) PermanentPlugSnippet(plug *interfaces.Plug, 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 *LocationObserveInterface) ConnectedPlugSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
switch securitySystem {
case interfaces.SecurityAppArmor:
old := []byte("###SLOT_SECURITY_TAGS###")
new := slotAppLabelExpr(slot)
snippet := bytes.Replace(locationObserveConnectedPlugAppArmor, old, new, -1)
return snippet, nil
case interfaces.SecurityDBus:
return locationObserveConnectedPlugDBus, nil
case interfaces.SecuritySecComp:
return locationObserveConnectedPlugSecComp, nil
case interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *LocationObserveInterface) PermanentSlotSnippet(slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
switch securitySystem {
case interfaces.SecurityAppArmor:
return locationObservePermanentSlotAppArmor, nil
case interfaces.SecurityDBus:
return locationObservePermanentSlotDBus, nil
case interfaces.SecuritySecComp:
return locationObservePermanentSlotSecComp, nil
case interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *LocationObserveInterface) ConnectedSlotSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) {
switch securitySystem {
case interfaces.SecurityAppArmor:
old := []byte("###PLUG_SECURITY_TAGS###")
new := plugAppLabelExpr(plug)
snippet := bytes.Replace(locationObserveConnectedSlotAppArmor, old, new, -1)
return snippet, nil
case interfaces.SecurityDBus, interfaces.SecuritySecComp, interfaces.SecurityUDev:
return nil, nil
default:
return nil, interfaces.ErrUnknownSecurity
}
}

func (iface *LocationObserveInterface) SanitizePlug(slot *interfaces.Plug) error {
return nil
}

func (iface *LocationObserveInterface) SanitizeSlot(slot *interfaces.Slot) error {
return nil
}

func (iface *LocationObserveInterface) AutoConnect() bool {
return false
}