This site has been retired. For up to date information, see handbook.gnome.org or gitlab.gnome.org.


[Home] [TitleIndex] [WordIndex

Based on a number of discussions on and and off-list, it seems that we want to get rid of user settings services. In its place, we will extend the security mechanisms in the system settings service so that we can comfortably store all settings there. This will hopefully make our API nicer and cleaner, and it will give us fast-user-switching support basically for free. Best of all, this will simplify the codebase considerably, esp. in the clients. It should make implementing new N-M clients much easier.

We will want to put some serious thought into what kind of security mechanisms to implement. It likely will be some combination of ACLs and polkit.

This is the 2010 Google Summer of Code project of DanielGnoutcheff. Work-in-progress is posted at the rm-userset branch at http://daniel.gnoutcheff.name/nm/daemon.git. Note that this branch is frequently rebased on master, so you won't want to base any work on it without prior arrangement. :)

References

Use cases

How fine-grained should the permissions be?

First, let's define some permissions a user may have on a connection's settings:

So how fine-grained to we want to be? Some proposals considered are listed below. We currently plan to use "by visibility with read-only flag".

By visibility

Have per-connection permission settings determine if that connection is "visible" by a given user. Further restrict users with a set of polkit actions that determine if a user is allowed to perform some operation on any connection. Thus, a user is allowed to perform an operation only if they can perform the corresponding polkit action and if the given connection is visible to them. A good set of polkit actions might be "read", "activate", and "administrate".

Notes/pros/cons:

By visibility with read-only flag

(This is the currently accepted proposal.)

Follows the "by visibility" proposal above, but also makes use of a "read-only" boolean on each connection. Connections that are marked "read-only" cannot be edited by anyone over DBus, regardless of polkit or visibility ACLs. Read-only connections can be modified only by administrators who can manually edit the config files.

Notes/pros/cons:

By activation and administration

Have connections be visible to all users. Have per-connection permissions specify which users can activate that connections, and also specify what subset of those users can administrate that connection.

Notes/pros/cons:

By visibility and administration

Have per-connection permission settings determine what users a connection is visible to, and also allow them to specify a subset of those users who also have the power to administrate those connections. Further restrict users with "activate" and "administrate" polkit actions. So, when a user wishes to perform some operation on a connection, their permissions are decided as follows:

Notes/pros/cons:

Notes/comments/issues for all approaches

How to handle auto(de)activation?

We already have an "autoconnect" flag, but there are many causes were we don't want a connection to be autoactivated even when this flag is set. Some options:

Access API

Since we plan to have controls on who can read a connection, each client will potentially have a different list of connections that it can read. We'll need to modify the DBus settings API somewhat to accommodate this, particularly since DBus signals don't have the kind of permission controls we would need. Some possible approaches:

PermissionsChanged signals

For org.freedesktop.NetworkManagerSettings.Connection, we modify the "Updated" signal to remove settings data, and we add a "PermissionsChanged" signal that is emited only when the connection's permission settings are changed. Each client holds an internal list of "accessible connections", and it maintains this list as follows:

Notes/pros/cons:

Notification sinks

Instead of DBus signals, an N-M client that is interested in connections can export a "notification sink" DBus object and register it with N-M. N-M keeps track of what connections are accessible by each client, and when the list changes for some client (or if one of the connections on the list is updated), N-M calls methods on the "notification sink" of that client to notify it of the changes.

In essence, N-M maintains an "accessible connections" list for each client, and "notification" method calls replace signals 1-for-1.

Notes/pros/cons:

Per-connection permissions settings format

I.e. for permissions that vary from connection to connection, how do we specify what users have what permissions?

We currently plan to use ACLs. This will be implemented as a 'allowed' property on NMSettingsConnection, a string list of users and groups that are allowed to view the connection. Entires are of the form 'user:<name>' or 'group:<name>'. Duplicates entires are removed, order doesn't matter.

Some options that were considered:

"Private connections only"

There are some cases where we want to allow people to add and modify connections, but we want those connections to stay private to the user who created them. How to accomplish this?

Secrets storage

Even without user settings services, we still want to store secrets in gnome-keyring and the like. We want to figure out the best way to do this.

Proposal 1: secrets agents, services services

Secrets are transfered from keyrings to N-M via "N-M secrets-agents", DBus objects exported on the system bus from which N-M can request secrets for a specific connection. These objects would likely implement org.freedesktop.!NetworkManagerSettings.Connection.Secrets or something very similar.

To deal with auto-activated connections, each logged-in user with a keyring has a "N-M secrets-service" (most likely embedded in nm-applet and the like) that keeps track of what secrets that user has. For each connection that the user has a secret for, the secrets service creates and registers secrets-agent.

When a connection is auto-activated, we would request the secret from some secrets-agent registered for that connection. We'd probably have N-M first try the secrets-agent from the user who most recently provided a "correct" secret for the connection (i.e. a secret that led to a successful connection activation).

When someone explicitly activates a connection, they also have the option of supplying a N-M secrets agent along with the activation request. This is intended to override or stand in the place of a secrets service. When N-M receives such a request and if a secret is indeed needed, it does the following:

  1. If the connection has a "secret-always-ask" flag, get the secret from the given secrets agent, requesting that the user be prompted if necessary. If no agent was supplied or if this request fails, the connection fails.
  2. Otherwise, N-M tries the following, in order.
    1. If the user supplied a secrets agent, try to get the secret from that (but with a flag asking that the user not be prompted).
    2. Then, then if the requesting user has a secrets service that registered an agent for the connection, try to get the secret from that (again, asking to avoid prompting the user).
    3. Then, try to get the secret from system-wide settings storage.
    4. Then, try the supplied secrets agent again, this time requesting that the user get prompted.
    5. Then try the pre-registered secrets agent again, again requesting that the user get prompted.
    6. If all that failed, then activation fails.

Note that in the case of explicit activation requests, we only pay attention to secrets agents from the requesting user. (Users probably don't want their keyrings being used to satisfy activation requests made by other users.)

General notes/comments/issues


2024-10-23 11:37