These are (most likely) only warnings and not severe bugs.
Some of these changes are mostly made to get a clean run of
Coverity without any warnings.
Error found by running Coverity scan
https://bugzilla.redhat.com/show_bug.cgi?id=1025894
Co-Authored-By: Jiří Klimeš <jklimes@redhat.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
This fixes a glib assertion:
"dbus_g_proxy_cancel_call: assertion `pending != NULL' failed"
Backtrace:
#0 0x00007f962dad9e0d in g_logv () from /lib64/libglib-2.0.so.0
#1 0x00007f962dad9ff2 in g_log () from /lib64/libglib-2.0.so.0
#2 0x00000000004a84bd in nm_secret_agent_cancel_secrets (self=0x213b300, call=0x1) at settings/nm-secret-agent.c:331
#3 0x00000000004a4068 in request_free (req=0x216a490) at settings/nm-agent-manager.c:479
#4 0x00007f962dac25fa in g_hash_table_remove_internal () from /lib64/libglib-2.0.so.0
Signed-off-by: Thomas Haller <thaller@redhat.com>
Turns out this function is useless, because it's only called when the
agent has dropped off the bus or when the whole request is being
freed. If the agent has dropped off the bus then there's no point
in asking it to cancel the request because there's nothing to ask.
So we can collapse request_cancel() into request_free().
If all agents can handle VPN hints, then we'll try to use
ConnectInteractive() to let the VPN plugin ask for secrets
interactively via the SecretsRequired signal. These hints
are then passed to agents during the connection process if
the plugin needs more secrets or different secrets, and when
the new secrets are returned, they are passed back to the VPN
plugin.
If at least one agent does not have the VPN hints capability,
we can't use ConnectInteractive(), but fall back to the old
Connect call, because that agent won't be able to send the
hints to the VPN plugin's authentication dialog, and thus
we won't get back the secrets the VPN plugin is looking for.
So, for interactive secrets to work correctly, you need:
1) A VPN plugin updated for interactive secrets requests
2) NM updated for interactive secrets requests
3) all agents to set the VPN_HINTS capability when
registering with NetworkManager and to pass hints
along to the VPN authentication dialog
4) a VPN authentication dialog updated to look for hints
and only return secrets corresponding to the hints
requested by the plugin
Previously I didn't think they'd be used for anything other than connection secrets
which only have one hint, but in the future we'll want to pass more information.
Split the agent secrets request tracking structure into a generic
structure for tracking any agent request, and a connection-specific
subclass. We'll use the generic structure in the future for device
secrets and other stuff.
Most callers of nm_auth_chain_new() call nm_dbus_manager_get_caller_info()
right before that, so just fold the get_caller_info() call into
nm_auth_chain_new() to reduce code complexity in callers. Yes, this
means sometimes we call nm_dbus_manager_get_caller_info() twice,
but that's not really a problem.
Normally, users which are not part of a login session can't access
connections. Root won't always be part of a login session, so
allow root to bypass visibility checks. The code already bypassed
the ACL checks for root, but in multiple places. Consolidate those
checks into one function.
Instead of doing something like
<get caller UID>
if (root) {
perform_operation()
other boilerplate stuff
return;
}
nm_auth_chain_new(perform_operation)
...
just have root also go through the auth chain, which is now
short circuited for root. This ensures we always use the same
code paths for root and non-root, and that fixes made in one path
are also executed for the other.
When providing a service on the bus daemon and a private connection,
we'll need to track objects so we can register them with the
private connection too. Thus all registration/unregistration
calls have to go through the NMDBusManager, not straight to
dbus-glib.
The ctype macros (eg, isalnum(), tolower()) are locale-dependent. Use
glib's ASCII-only versions instead.
Also, replace isascii() with g_ascii_isprint(), since isascii()
accepts control characters, which isn't what the code wanted in any of
the places where it was using it.
Rather than generating enum classes by hand (and complaining in each
file that "this should really be standard"), use glib-mkenums.
Unfortunately, we need a very new version of glib-mkenums in order to
deal with NM's naming conventions and to fix a few other bugs, so just
import that into the source tree temporarily.
Also, to simplify the use of glib-mkenums, import Makefile.glib from
https://bugzilla.gnome.org/654395.
To avoid having to run glib-mkenums for every subdirectory of src/,
add a new "generated" directory, and put the generated enums files
there.
Finally, use Makefile.glib for marshallers too, and generate separate
ones for libnm-glib and NetworkManager.
Use case:
A user has an auto-activatable connection with secrets in a keyring. While
booting NM starts and tries to activate the connection, but it fails because of
missing secrets. Then the user logs in, but the connection is marked as invalid
and is not tried again.
This commit solves the issue by removing invalid flag and activating the
connection when a secret agent registers.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
The core problem was the nm_connection_need_secrets() call in
nm-agent-manager.c's get_start() function; for VPN settings this
always returns TRUE. Thus if a VPN connection had only system
secrets, when the agent manager checked if additional secrets
were required, they would be, and agents would be asked for
secrets they didn't have and couldn't provide. Thus the
connection would fail. nm_connection_need_secrets() simply
can't know if VPN secrets are really required because it
doesn't know anything about the internal VPN private data;
only the plugin itself can tell us if secrets are required.
If the system secrets are sufficient we shouldn't be asking any
agents for secrets at all. So implement a three-step secrets
path for VPN connections. First we retrieve existing system
secrets, and ask the plugin if these are sufficient. Second we
request both existing system secrets and existing agent secrets
and again ask the plugin if these are sufficient. If both those
fail, we ask agents for new secrets.
All non-VPN secrets are considered system-owned if they do not
have any explicitly set secret flags, and this makes VPN secrets
treated the same way. As part of the import process plugins and
the applet already update secret flags. This ensures that VPN
secrets are treated consistently throughout the codebase.
Use one global PolkitAuthority object; we only really need to use it
in one place anyway. So consolidate the code that uses polkit into
nm-manager-auth.c.
If the connection had system secrets, previously the settings core
would consider those sufficient even if the device code had requested
new secrets because the old ones didn't work.
Can't just check whether we have existing system secrets, because
that doesn't catch the case for a completely new connection where
there may not be any secrets yet, but any that we do get should
be system-owned.
When a connection is visible only to one user, check 'own' instead
of 'system', allowing 'own' to be less restrictive since the change
won't affect any other users.
Meaning stays the same, but this will allow us to differentiate
in the future between personal connections (ie, just visible to
one user) and system connections (visible to more than one user).
We need to iterate through each item in the VPN's 'secrets' property
and mark it as not required, instead of just marking the 'secrets'
property itself as not required. Yeah, VPN secrets are a bit
annoying.
Do the check for system-owned secrets once, before kicking off the
request, instead of each time we ask an agent. As a bonus, this
change ensures priv->secrets doesn't store anything except
system-owned secrets too, simplifying some checks later on.
If we can authenticate the agent for 'modify' permission, then send
any existing system secrets to it as the user has permission to change
those secrets. This means the agent doesn't have to call GetSecrets()
itself, which means simpler code on the agent side for a slight LoC
hit in NM itself.
This also moves the permissions checking into the NMAgentManager to
check each agent, which is sub-optimal since now the agent manager
has to do PolicyKit stuff, but hey that's life. Agents need secrets,
and we do need to authenticate every agent before we send secrets to
them, and the NMSettingsConnection doesn't know about individual
agents at all.
If the agent returns system-owned secrets, like when activating a new
connection which was created with no secrets, make sure the agent is
authorized to modify network settings before saving or using the
new secrets.