Based on a number of discussions on and and off-list we decided to dramatically simplify the NM API and architecture, largely by merging user settings into the core daemon and securely storing all network configuration there. This will make the NM API simpler and cleaner, and enable featuers like fast-user-switching "for free". Best of all, this will simplify the codebase both in NetworkManager and in clients, allowing easier creation of new and updated user experiences that target different use-cases.
The original work towards this goal was the 2010 Google Summer of Code project of DanielGnoutcheff. Work-in-progress was posted at the rm-userset branch at http://daniel.gnoutcheff.name/nm/daemon.git. After completion of the project, his work was moved to NM git on git.freedesktop.org in the 'rm-userset' branch. The information below is a summarization of the ideas produced over the summer and a blueprint of the ongoing work to create NetworkManager 0.9. Look here for the discussions and background on how these decisions were reached.
NetworkManager 0.9 should enable the following use-cases:
Erin, the single user: Erin is the primary user of her laptop. She has full control over networking on her laptop, without password prompts or any other annoyances.
Erin and always-ask: Erin occasionally uses the VPN to log into a very important part of her company's network. Erin does not want the risks associated with having the password stored anywhere; she'd prefer to enter it each time she connects to work. However, she does want other (non-secret) settings to be saved.
Avery and the family computer: Alex and his son Avery share a family computer. They live in a rural area, and so they must make do with a POTS dial-up modem. Avery is not allowed to change the computer's network configuration, but in order to let him have Internet access when he needs to do homework, he is allowed to use the modem connection.
Max and the family computer: Max also has an account on the family computer. Max spent way too much time surfing the 'net a while back, so he is not allowed to activate the modem connection at all. But he is allowed to use the WiFi connection for LAN parties with his friends.
Family-computer system-wide secrets: The WiFi network that Max can use is a secure WiFi network. The security is mainly intended to keep folks outside the family off the network; anyone who has an account on the family computer can use this WiFi network without having to enter the WPA password.
Alex and encrypted secrets: Alex often needs to make a VPN connection for work. He is the only one allowed to use the connection; he does not want the kids to mess with his co-workers. The VPN password is stored in gnome-keyring, so he knows that it is reasonably safe even if the computer is stolen.
Larry the lab sysadmin: Larry is the sysadmin of a computer lab. He does not want to deal with users fiddling with network configs, and so he does not allow anyone except himself to do anything with network connections.
Shelly and the WiFi laptops: Shelly manages a set of laptops that are lent out to schoolchildren for various activities. These laptops connect to the 'net via a secure WiFi network at the school. She does not want anything else to connect to these networks, so she does not want students to be able to copy the WiFi secrets from the laptops. Thus, she has NM setup such that the students cannot read the WiFi secrets but can still connect easily.
Shared encrypted secrets: Alan and Andrew share a workstation in a branch office, and they both occasionally VPN into the main office. They use the same VPN connection, and they use the same password. They also do not want the password to be compromised if the machine is stolen, so they both keep a copy of the password in their keyrings. When either one of them activates the connection, NM knows that it can look in one of their keyrings for the password.
Private connections on managed laptops: Ellen manages a set of laptops lent to employees in a reasonably large office. This office is a consulting firm, so people often need to set up connections to their various client's networks (VPN connections, wifi connections, etc.). To reduce support issues, she'd also rather not let people modify the connection to the office wifi and wired networks, but she does still want to let anyone activate these connections.
First, let's list the main things that a user may need to do with a connection:
View: the ability to read the non-secret parts of a connection
Activate: the ability to manually activate the connection, possibly deactivating other connections in the process
Modify: the ability to edit the connection and view its secrets
Permissions and Security
In place of user settings, the core daemon's settings service will be able to enforce "visibility" and access control of connections on a per-user basis. Through a combination of PolicyKit, in-connection ACLs, and a "read-only" flag, we'll be able to cover the use-cases above with a clear architecture.
ACLs: each connection will store a list of users who are allowed to "view" the connection. A user not allowed to view the connection will be denied access to its details and secrets and is not allowed to activate the connection. This ACL will be a simple string list with an extendable format. An empty ACL allows everyone to view and activate the connection. This feature replaces user connections from NM 0.8 and earlier.
read-only: to enable use-cases where specific connections are locked-down by a system administrator, but the user is still able to create on-the-fly connections (see "Private connections on managed laptops" above), the existing 'read-only' flag in the 'connection' setting will prevent any user from modifying a specific connection or viewing its secrets. However, since all connections are backed by some type of storage (like config files), a system administrator with root access can still modify the config files to update, change, or remove administered connections. These connections will be given priority when determining what to automatically connect to.
Auto-activation and Visibility
A given connection is only available for automatic activation when either:
- it has an empty ACL, or
- a user listed in its ACL is logged in (and thus the connection is "visible" to at least one user)
functionality for (b) depends on ConsoleKit for session/login tracking, and we intend to make ConsoleKit an optional dependency. If ConsoleKit support is not enabled when building NetworkManager, all connections are available for auto-activation. In this case, if the connection requires secrets, and no user in the ACL list is logged in running an agent to provide those secrets, the activation attempt will fail until the next time it is manually activated. Secrets can be stored in the connection to prevent this failure.
D-Bus API Changes
Since there are now controls on what users can read which connections, each client will potentially have a different list of connections that it can read. This requires modification of the existing D-Bus API, since signals cannot be restricted to specific clients, and we do not wish to require use of peer-to-peer D-Bus connections.
org.freedesktop.NetworkManagerSettings.Connection.Updated: to avoid leaking information to clients that are not allowed by the ACL to view the connection's settings, we'll need to remove the updated settings data from this signal. Thus, when the connection's settings are changed and the Updated signal is sent out, clients will need to requery the core daemon for the new settings with the org.freedesktop.NetworkManagerSettings.Connection.GetSettings() method. The core daemon will then validate the client's access permissions via the ACL and PolicyKit, and either return the settings or an access denied error. Clients should maintain an internal list of all connections advertised by NM even if they cannot read them because at any point the client's user could be added to a connection's ACL and the connection will become readable by the client. This should be simpler than attempting to track only connections that the client has access to at a given point in time, and listening to specific signals for readability.
org.freedesktop.NetworkManagerSettings.Connection.Secrets interface: requests for secrets will change slightly, because this method will now only be called when some client wishes to retrieve secrets for editing the connection. Thus we can lock this call down with the PolicyKit "modify" permission. Previously it was used by both NM itself when connecting to networks, and by configuration editors, and thus we could not reliably determine the intent of the caller. When secrets are stored in the user session and required for immediate connection to a network, NM will use the Agent interface to request them. When a configuration editor requests access to a connection's secrets, NM can validate this request before returning existing secrets or requesting them from the Agent.
Note that with this model all clients will be aware of the existence, creation, modification, and removal of any connection, even if they cannot read any details of it. We don't consider this to be problematic because virtually nothing can be determined from these events when the client is not able to actually read the connection's settings or secrets.
To allow secrets to be stored securely in a users' session (as opposed to plaintext-but-root-only storage by the core daemon) specific processes (called "Agents") will be able to register with the core daemon to store and provide these secrets. VPN connections are a prime example; they are primarily single-user connections and their secrets must be well protected. A new D-Bus interface will be created to allow agents to announce their presence to NetworkManager. This interface allows multiple agents at the same time, solving the architectural issue that prevented NM 0.8 and earlier from supporting fast-user-switching. This will consist of two parts:
- a new interface in the core daemon to handle registration and unregistration of the agents, to request secrets from them, and to send updated secrets to them when the connection is modified
org.freedesktop.NetworkManager.AgentManager.Register: agents that wish to register themselves with the core daemon call this method with an identifier that enables NM to direct specific secrets requests to this agent. Only one agent may register with a given identifier in each session.
- a small interface in the agent itself to receive secrets requests and accept secrets updates from the core daemon
GetSecrets: analogous to the current org.freedesktop.NetworkManagerSettings.Connection.Secrets.GetSecrets request, the core daemon calls this when secrets are required to connect to a specific network. The entire connection details will be sent to the agent so that the agent itself does not have to track all connections. The agent will never be called to request secrets for a connection which the agent's user cannot "view".
SetSecrets: called by the core daemon to save secrets for a given connection. The entire connection is sent to the Agent.
Given that multiple agent may be registered at the same time, if a connection is visible to more than one logged-in user, and the connection itself does not provide secrets or the connection specifies that secrets should always be retrieved from an Agent, NetworkManager will query each agent (giving preference to agents in "active" sessions as determined by ConsoleKit) until it receives a secret. This should allow a system VPN connection to be shared between more than one user where secrets should be requested each time the connection is made, such as for One-Time-Pad tokens.
Settings Changes for ACLs
To facilitate the addition of the ACL to each connection the 'connection' setting will be modified to add a new 'permissions' key. This key will contain a list of strings defining exactly who has permission to view the connection. Empty elements in the list are invalid. Any given user is allowed to view or activate the connection if and only if the list is empty, or if an element in the list specifically allows that user. Each element takes the form:
where the only keyword currently allowed is 'user'. Unknown keywords must be ignored and preserved. For the 'user' keyword, each <data> item names a specific user allowed to view or activate this connection. Any <extra> information is reserved for future usage by NetworkManager and must be both ignored and preserved.