Without this, `nmcli device modify "$DEVICE"` leads to a crash. At least
since commit c5d45848dd ('cli: mark argv argument for command line
parsing as const'), when this happens.
That is, because it passes a NULL strv array with argc being set to
zero. nmc_process_connection_properties() is not supposed to access
the array, if there are no elements there.
Fixes: c5d45848dd ('cli: mark argv argument for command line parsing as const')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/492
Before 1.24, nm_setting_bond_add_option() would clear
miimon/arp_interval settings when the respective other was set.
That was no longer done, with the effect that enabling (for example)
miimon on a bond profile that has arp_interval enabled, sets both
conflicting options.
That is not a severe problem, because the profile still validates.
However, at runtime only one of the settings can be actually configured.
Fix that, by restoring the previous behavior for the client. But note
that this time it's implemented in the client, and not in libnm's
nm_setting_bond_add_option().
$ nmcli -f GENERAL.HWADDR device show ovsport0
GENERAL.HWADDR: (unknown)
but:
$ nmcli -f GENERAL.HWADDR --terse device show ovsport0
GENERAL.HWADDR:
This is an API change of nmcli.
The connection is automatically unreferenced when the function
returns.
Fixes: 9c5ea0917d ('devices: reuse the hotspot connection if we find appropriate one'):
We have the correct meta-data of supported properties for nmcli. It is
in clients/common. Use that for generating the manual page instead of
the properties that are part of libnm (some properties may be in libnm
but not supported by nmcli, or some properties may not be GObject
properties, and not detected as by GObject introspection).
Commit 37e7fa38c2 ("nm-supplicant-interface: enable OWE security
when transition mode is available") adds the OWE security flag in
case a valid OWE transtition mode IE is present on the beacon.
It also removes the OWE security flag in case the Iinformation elements
of a beacon are updated and a OWE transition mode IE can't be found.
When a pure OWE AP updates it's Information Elements (e.g. BSS Load
Element), the OWE security flag is falsely removed.
Introduce a new NM_802_11_AP_SEC_KEY_MGMT_OWE_TM security flag and use
it exclusively for OWE transition mode. Don't use the
M_802_11_AP_SEC_KEY_MGMT_OWE security flag on transition-mode APs.
Signed-off-by: David Bauer <mail@david-bauer.net>
Rework parsing of nmcli's passwd-file.
1) support backslash escaping of secrets.
- only the secret can be backslash escaped, the property and setting
name cannot.
This is a change in behavior for passwd-files with secrets that contain
a backslash.
2) strip the white space around the secret. This is a change in behavior
for secrets that had leading or trailing spaces. Note that you can
backslash escape spaces in secrets.
3) strip white space around the setting.property key. This is also a
change in behavior, but such keys would never have been valid
previously (or the caller would have performed the same kind of
stripping).
4) accept '=' as alternative delimiter beside ':'. The ':' feels really
odd and unexpected. Also accept '='. This is a change in behavior if
keys would contain '=', which they really shouldn't.
5) reject non-UTF-8 secrets and keys. For keys, that is not an issue,
because such keys were never valid. For secrets, it probably didn't
work anyway to specify non-UTF-8 secrets, because most (if not all)
secrets are transmitted via D-Bus as strings where arbitrary binary
is not allowed.
6) ignore empty lines and lines starting with '#'.
7) ensure we don't leak any secrets in memory.
1) to 4) are changes in behavior. 3) and 4) seem less severe, as they
only concern unusual setting.property keys, which really shouldn't be
used (although, VPN secrets can have almost arbitrary names *sigh*).
1) and 2) is more dangerous, as it changes behavior for secrets that
contain backslashes or leading/trailing white space.
Callbacks might reference the main loop when destroying the NMClient
instance. Unref the main loop later.
# G_DEBUG=fatal-warnings valgrind --num-callers=100 nmcli device wifi connect home
^C
Error: nmcli terminated by signal Interrupt (2)
Error: Connection activation failed: (0) No reason given.
==11050== Invalid read of size 4
==11050== at 0x4C90D3D: g_main_loop_quit (in /usr/lib64/libglib-2.0.so.0.6200.6)
==11050== by 0x431435: quit (devices.c:934)
==11050== by 0x43272C: connected_state_cb (devices.c:1919)
==11050== by 0x4BF6741: g_closure_invoke (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4C0A603: ??? (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4C133AD: g_signal_emit_valist (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4C139D2: g_signal_emit (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4BFB1C3: ??? (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4BFAAEC: ??? (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x4BFD86A: g_object_thaw_notify (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x48BA040: _nm_client_notify_event_emit (nm-client.c:937)
==11050== by 0x48CA01F: _dbus_handle_changes_commit (nm-client.c:2850)
==11050== by 0x48CC221: _dbus_handle_changes (nm-client.c:2864)
==11050== by 0x48CC833: _init_release_all (nm-client.c:6969)
==11050== by 0x48D2818: dispose (nm-client.c:7826)
==11050== by 0x4BFBC27: g_object_unref (in /usr/lib64/libgobject-2.0.so.0.6200.6)
==11050== by 0x43FF93: nmc_cleanup (nmcli.c:941)
==11050== by 0x4410AD: main (nmcli.c:1005)
==11050== Address 0x54738fc is 12 bytes inside a block of size 16 free'd
==11050== at 0x4839A0C: free (vg_replace_malloc.c:540)
==11050== by 0x4C9649C: g_free (in /usr/lib64/libglib-2.0.so.0.6200.6)
==11050== by 0x4410A3: main (nmcli.c:1004)
==11050== Block was alloc'd at
==11050== at 0x483AB1A: calloc (vg_replace_malloc.c:762)
==11050== by 0x4C96400: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.6200.6)
==11050== by 0x4C90A45: g_main_loop_new (in /usr/lib64/libglib-2.0.so.0.6200.6)
==11050== by 0x441020: main (nmcli.c:987)
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/501
lgtm.com flags this as "Empty block without comment".
Avoid it.
This code is of course ugly. Much work was already done to
port such occurrences, and more is needed. I won't add a FIXME
comment, because lgtm.com flags those too. :)
Static analysis tools flag the use of localtime() because it is not
thread safe. Of course, that was no problem here, but avoiding the
warning is simple.
Also, if we allocate 128 bytes, let strftime use it.
NetworkManager will reject scan requests, if it is currently scanning.
That is very wrong. Even if NetworkManager wants to ratelimit scan
requests or not scan at critical moments, it should never reject a
request, but remember and start scanning as soon as it can.
That should be fixed.
But regardless, also nmcli can do better.
If you issue
$ nmcli device wifi list --rescan yes
once, it works as expected.
If you issue it again right after, the scan request of nmcli will be
rejected. But nmcli cannot just merely complete and print the result.
Instead, it will wait in the hope that a scan result will be present
soon. But if the request was simply rejected, then the result will
never come, and nmcli hangs for the 15 seconds timeout.
Instead, repeatedly re-trigger scan requests, in the hope that as soon
as possible we will be ready.
Many func implementations are asynchronous, that means, they
cannot return right away. Instead, they record the return value
in nmc->result_value.
The return value from the command functions was thus redundant.
In the best case, the return value agrees with the cached result
in nmc->result_value, in which it was unnecessary. In the worst case,
they disagree, and overwrite each other.
nmc->result_value is state. Tracking state is hard, and there should
be fewer places where the state gets mutated. Also, the rules how that
happened should be clearer. Drop the redundant, conflicting mechanism.
It's bad style to pass the argv argument around and mutate it.
We shouldn't mutate it, and not assume that it stays around after
the function returns to the caller (meaning, we should clone the
array if we intend to use it later).
Add const specifier.
It is useful from inside a function to know the command that it belongs to.
Currently we have do_networking_on() and do_networking_off() as separate
functions. However, these are basically the same with a minor difference.
If the func callback could know the "cmd" that it was called for, these
function can be combined.
Of course, without passing the NMCCommand instance, you still can
achieve the same results, especially as the NMCCommand instances are
static and known at compile time: just have separate func
implementations. But by passing the command to the function, they
*can* be combined, which is a useful thing to do.
- move the main func declarations to nmcli.h and give them a common
prefix "nmc_command_func_" prefix.
- remove some of the header files that are now empty. In fact, these
headers did not really declare some well separated module. While we
probably should structure the code in nmcli better with better layering,
it was not and still is not. Having these dummy headers don't mean that
the code is well structured and they serve little purpose.
- move the static NMCommand lists variables into the function scope
where they are used.
We should not use global variables, and we should minimize the state
that we pass around. Instead of requiring the full NmCli struct in
nm_cli_spawn_pager(), pass only the necessary data.
This reduces our use of global variables.
Of course, we later pass the point on, where we need to cast the constness away
again. This is more a reminder that we aren't suppost to change the variable.
We should try to avoid access to global variables. For libreadline
callbacks we still need a global variable.
Introduce a global variable nm_cli_global_readline, specially for this
use. It makes the places clear where we use it, and discourages
the use at other places, where we better avoid global variables.
g_clear_pointer() would always cast the destroy notify function
pointer to GDestroyNotify. That means, it lost some type safety, like
GPtrArray *ptr_arr = ...
g_clear_pointer (&ptr_arr, g_array_unref);
Since glib 2.58 ([1]), g_clear_pointer() is also more type safe. But
this is not used by NetworkManager, because we don't set
GLIB_VERSION_MIN_REQUIRED to 2.58.
[1] f9a9902aac
We have nm_clear_pointer() to avoid this issue for a long time (pre
1.12.0). Possibly we should redefine in our source tree g_clear_pointer()
as nm_clear_pointer(). However, I don't like to patch glib functions
with our own variant. Arguably, we do patch g_clear_error() in
such a manner. But there the point is to make the function inlinable.
Also, nm_clear_pointer() returns a boolean that indicates whether
anything was cleared. That is sometimes useful. I think we should
just consistently use nm_clear_pointer() instead, which does always
the preferable thing.
Replace:
sed 's/\<g_clear_pointer *(\([^;]*\), *\([a-z_A-Z0-9]\+\) *)/nm_clear_pointer (\1, \2)/g' $(git grep -l g_clear_pointer) -i
Showcase nm_client_dbus_set_property().
Thereby, also print error messages and return an error if
the command fails.
Also, enable PolicyKit authentication (although, I think there are
some bugs with this still).
Previously, we would call the synchronous nm_client_networking_set_enabled()
method. There were 3 problems:
1) nmcli ignored the return value, that means, if the request failed with
access denied it would just silently pretend that it succeeded.
2) nmcli first called nmc_start_polkit_agent_start_try(), but when
invoking the synchronous method, the main context is busy and a
polkit request cannot possibly be handled.
3) nm_client_networking_set_enabled() is deprecated.
Fix all of these, by calling the D-Bus method directly.
Policykit authentication requests are only handled partly. There
seems to be an unrelated race/bug. Now it works sometimes.
This is more a showcase for using nm_client_dbus_call(), than a
real use.
In this case, nmcli was mostly fine to just invoke the synchronous API
and not care about the problems that it had.
Still, replace it, and show the suggested alternative.