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>
ifcfg-rh plugin now reads/writes the property as MACADDR_BLACKLIST variable.
The variable is space-separated list of MAC addresses in the standard
hex-digits-and-colons notation.
E.g. MACADDR_BLACKLIST="7e:d8:c0:85:58:7f 00:1e:65:30:d5:c7"
IPV6_FAILURE_FATAL is now read and defaults to TRUE for ifcfg files
even if IPv6 is turned off. That means that if we write a connection
for which NM_SETTING_IP6_CONFIG_MAY_FAIL is FALSE but IPv6 is disabled,
ifcfg-rh won't write out IPV6_FAILURE_FATAL (because IPv6 is disabled
so why bother writing out IPv6-related settings) but on re-read it will
treat the absence of IPV6_FAILURE_FATAL as TRUE/yes. This leads to
a mismatch between the connection that was written out (which will
have NM_SETTING_IP6_CONFIG_MAY_FAIL=FALSE and no IPV6_FAILURE_FATAL)
and the re-read connection (which will have
NM_SETTING_IP6_CONFIG_MAY_FAIL=TRUE since a missing IPV6_FAILURE_FATAL
is treated as NM_SETTING_IP6_CONFIG_MAY_FAIL=TRUE).
We need to read IPV6_FAILURE_FATAL and other values, even if IPv6 is disabled.
Else the variables would use default values, which may not be right. Then
switching between methods "Ignore" and "Automatic" in a GUI would change value of
IPV6_FAILURE_FATAL property, even if it's not touched explicitly.
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.
Previously (in NM 0.8.x) most WiFi connection were from user settings service.
And the service updated 'seen-bssids' property when got connected.
But the settings service in 0.9 don't do that. That inhibits auto-connecting to
hidden networks. This commit takes care of updating 'seen-bssids'. However, we
don't want to write out the conection each time it's activated (touching /etc).
So, seen BSSIDs are kept separately from the connection in a look-aside file.
Signed-off-by: Jiří Klimeš <jklimes@redhat.com>
When a connection changes on-disk, the in-memory copy of it may contain
transient secrets (agent-owned or not saved) that dont' get written out
to disk. When comparing the on-disk copy to the in-memory copy make sure
transient secrets are ignored so that we don't re-read the on-disk copy
needlessly.
The keyfile code has to handle a few different formats of cert/key values,
and wasn't doing a good enough job of detecting plain paths as values. By
default the writer will write out a plain path (ie, not prefixed with file://)
and the reader will handle that correctly, *unless* that file does not
exist, at which the reader assumed it was a byte array. This caused the
read-in keyfile not to match the in-memory connection (since the in-memory
connection though the cert/key held a path, but the read-in one thought it
contained a blob) and this seems to eventually have triggered a write-out
with the new values (as a blob), which would then drop a .pem file into
system-connections/ containing the path that should have been in the
keyfile in the first place.
This all happened because we assumed that the given path for the cert or
key would actually be valid, which doesn't seem to be the case for a lot
of people. Clearly these connections won't work (since the certificate or
key does not exist) but the keyfile plugin shouldn't be messing up the
connection's settings at the very least.
Fix that by handling the check of whether the cert/key data is a path or
not in a less restrictive manner and add some testcases to make sure that
everything works as we expect.
If the cert/key path is relative to the keyfile then don't
bother writing the absolute path out. This also prevents the
keyfile plugin from rewriting a relative path to an absolute one,
preventing some annoyance for people that hand-edit keyfiles.
Passing a relative path to wpa_supplicant does no good since the supplicant
may not have the same working directory as NetworkManager. Relative paths
used in keyfiles are assumed to be relative to the keyfile itself anyway,
so actually use the absolute path we compute for the cert/key instead of
leaving it relative.
Since the keyfile plugin only stores the paths of these files,
we don't really care about what's in them. We also don't want
to attempt to read them as keyfiles, which produces warnings
in the logs.
Here's the problem:
- NM requests secrets
- secret agent returns secrets including some that are agent-owned or
not-saved (ie, transient secrets)
- for whatever reason (other secrets are system-owned, whatever) the
connection gets written back out to disk
- at some point later inotify triggers a connection re-read from disk
- the connection is read from disk, but doesn't contain the agent-owned
or not-saved secrets, because they obviously don't get saved
- nm_settings_connection_replace_and_commit() blows away the agent-owned
or not-saved secrets that the agent originally returned
- device activation no longer has the transient secrets
Re-reading connection data from disk shouldn't change transient secrets;
instead we need to merge the just-read system-owned secrets with whatever
transient secrets an agent sent. Transient secrets should only be cleared
by nm_connection_clear_secrets() to ensure that they stick around for as
long as we need them.
Commit e083cd5c63 stopped openconnect from
saving its secrets. It'd been working for a whole three minutes since my
previous commit.
We need to have at least one secret with an *extant* flags setting of
NM_SETTING_SECRET_FLAG_NONE, in order to trigger a write-out of the new
set of secrets. And we might as well list all the secrets we *know* the
auth-dialog is going to use, although we know there will be some secrets
that we cannot predict in advance (the form entry boxes).
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.
Previously a secret marked NOT_SAVED or NOT_REQUIRED would be
treated as a system secret when checking returned secrets. That's
incorrect since unsaved or not required secrets aren't stored
by system settings.
Evil hack; but the problem is that before this commit anyone who
migrated connections wouldn't have the right secrets flag set in
their openconnect connections. Figuring out some way of updating
those connections now is harder and we don't want people to have
to go through the delete-connection-file-change-applet-stamp-rerun
dance. So we'll live with this for now...
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 client knows the UUID, add a convenience function to get
the connection path directly, instead of having to iterate the
whole connection list and get each connection's details and then
check the UUID.
The signal was emitted in case the removed connection was managed instead of
for unmanaged connection. Thus the signal had no effect.
That caused incorrect behaviour in case of changing NM_CONTROLLED=no to yes.
That didn't enable the device; only after the file was changed for the second time.
The default wired connection should own a reference to the device
it's made for, but that got dropped in
78df8c49a1, which used to use a
set_property handler with g_value_dup_object() which obviously
increments the reference count. But that ref got dropped when
the object initialization was simplified.
Now that initscripts also support IPADDRn syntax, update the implementation
to match the intitscripts' one (see rh #633984)
Basically, writer produces IPADDR0 .. IPADDR255. reader is more tolerant and
supports older configs too: IPADDR, IPADDR0, IPADDR1 could be missing, from
IPADDR2 up the indexes have to be contiguous.
Due to an error in the loop logic, if there were no connections yet (like
a fresh install or a livecd or whatever) no default name would be returned
and thus ethernet devices wouldn't come up automatically. Fix that loop
error and add testcases for it.
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.