We need to wait for it to finish so we can show error messages, if any.
Also, if we don't do it, sometimes the `d set eth0 managed ...`
operation fails with the following message in the daemon's log: "Unable
to determine UID of the request". This is because the client's process
is terminated before the daemon can check the permissions, as it needs
to check the uid and gid from the client's process.
Allow to manage or unmanage a device persisting across reboots.
If --permanent is not specified, only the runtime managed state is
changed, preserving the previous behavior. The --permanent-only
option allows to edit only the persistent value, without touching
the runtime value.
Also add the values up/down. Up means managed=yes and set device's
administrative state UP. Down means managed=no and admin state DOWN.
Add the value 'reset' too. It reverts managed runtime status to default
behaviour. When used with `--permanent` flag, the persisted managed
settings is cleared.
Co-authored-by: Rahul Rajesh <rajeshrah22@gmail.com>
They show the same than the old BRIDGE/TEAM.SLAVES and GENERAL.MASTER-PATH.
We missed this when we did the changes in favour of conscious language.
Instead of replacing them, we add a new field that will show the same
value with the new name. This way we avoid breaking users doing
`nmcli -f BRIDGE.SLAVES` or `nmcli ... | grep SLAVES`.
It's a valuable information for users, especially because the channel
number can be ambiguous.
Before:
$ nmcli device wifi
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
42:00:00:AA:DD:CC test Infra 44 1170 Mbit/s 85 ▂▄▆█ WPA2
92:00:00:AB:DD:CC guest Infra 44 1170 Mbit/s 85 ▂▄▆█ WPA2
After:
$ nmcli device wifi
IN-USE BSSID SSID MODE BAND CHAN RATE SIGNAL BARS SECURITY
42:00:00:AA:DD:CC test Infra 5 GHz 44 1170 Mbit/s 85 ▂▄▆█ WPA2
42:00:00:AB:DD:CC guest Infra 5 GHz 44 1170 Mbit/s 85 ▂▄▆█ WPA2
Until now the Wi-Fi bands were named after the first 802.11 standard
that introduced them: "a" for 5GHz introduced in 802.11a and "bg" for
2.4GHz introduced in 802.11b/g. With new bands added, this naming
scheme doesn't sound very intuitive to remember for users. Furthermore
we have now 6GHz that is introduced by 802.11ax (Wi-Fi 6), but the
compatible devices can use all three the bands (2.4, 5, 6 GHz).
For the 6 GHz band, simply name it "6GHz".
Co-authored-by: Beniamino Galvani <bgalvani@redhat.com>
When connecting to a wifi network and providing the password on the
command line, nmcli first looks if there is a compatible connection to
reuse. If there is not, it creates and activates a new one via a
single call to AddAndActivate().
If there is a compatible connection, nmcli first calls Update() on it
to set the new password and then Activate() to bring it up. Before
that, it registers a secret agent that can prompt for a new password
in case of authentication failure.
However, as soon as nmcli registers a secret agent, NM tries to
activate again the connection if it was blocked due to a previous
authentication failure. This connection attempt is going to fail
because it still uses the old password, as new one hasn't been set via
Update().
Change the order of operations to register the agent after Update()
and before Activate().
Reproducer:
nmcli device wifi connect SSID password BAD_PASSWORD
nmcli device wifi connect SSID password GOOD_PASSWORD
Fixes: c8ff1b30fb ('nmcli/dev: use secret agent for nmcli d [wifi] connect')
Executing this command twice, or when a connection profile already
exists for the SSID:
nmcli device wifi connect $SSID password $PASSWORD
returns error:
Error: 802-11-wireless-security.key-mgmt: property is missing.
When setting the password nmcli was wiping the existing wireless
security setting.
Fixes: c8ff1b30fb ('nmcli/dev: use secret agent for nmcli d [wifi] connect')
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1688
If the connection is a port we need to set the connection.port-type
property. Usually this property is guessed by nmcli depending on the
connection type or the chosen controller, so it doesn't need to be
specified by the user. However, if it is explicitly set by the user
we should not guess, but just use it.
When we process arguments like "controller" or "type" we call custom
functions like set_connection_controller that will guess the port-type
if needed. By processing port-type first, it will be set in the
connection by the time that these other properties are processed, so they
won't try to guess.
After port-type, process connection.type and connection.controller, as we
are usually capable of deducing the port-type from them. Type needs to
be processed first because some types like bond-slave or ovs-port have
only one possible port-type value so we must not try to guess from the
controller.
Fixes: c5324ed285 ('nmcli: streamline connection addition')
The current mess of code seems like a hodgepodge of complex ideas,
partially copied from systemd, but then subtly different, and it's a
mess. Let's simplify this drastically.
First, assume that getrandom() is always available. If the kernel is too
old, we have an unoptimized slowpath for still supporting ancient
kernels, a path that should be removed at some point. If getrandom()
isn't available and the fallback path doesn't work, the system has much
larger problems, so just crash. This should basically never happen.
getrandom() and having randomness available in general is a critical
system API that should be expected to be available on any functioning
system.
Second, assume that the rng is initialized, so that asking for random
numbers should never block. This is virtually always true on modern
kernels. On ancient kernels, it usually becomes true. But, more
importantly, this is not the responsibility of various daemons, even
ones that run at boot. Instead, this is something for the kernel and/or
init to ensure.
Putting these together, we adopt new behavior:
- First, try getrandom(..., ..., 0). The 0 flags field means that this
call will only return good random bytes, not insecure ones.
- If this fails for some reason that isn't ENOSYS, crash.
- If this fails due to ENOSYS, poll on /dev/random until 1 byte is
available, suggesting that subsequent reads from the rng will almost
have good random bytes. If this fails, crash. Then, read from
/dev/urandom. If this fails, crash.
We don't bother caching when getrandom() returns ENOSYS. We don't apply
any other fancy optimizations to the slow fallback path. We keep that as
barebones and minimal as we can. It works. It's for ancient kernels. It
should be removed soon. It's not worth spending cycles over. Instead,
the goal is to eventually reduce all of this down to a simple boring
call to getrandom(..., ..., 0).
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2127
Instead of asking the Wi-Fi password in advance (or not at all, if we're
creating a new connection for "nmcli d conn"), use the secret agent.
This makes things consistent with other places where we handle the secrets
for an activating connection in nmcli ("nmcli c up", "nmcli d con" with
an existing connection).
This also fixes the situation where the secrets would stop being
required, such as on enrollment via WPS button press on a router.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1960
Previously, we first sort by the device's state, then by the active
connection's state. Contrast to `nmcli connection`, which first sorts
by the active connection's state.
It means, the sort order is somewhat different. Fix that.
In most cases, that shouldn't make a difference, because the
device's state and the active-connection's state should
correspond. However, it matters as we now treat external activations
different, and that is tied to the active connection.
Comparing integers of different signedness gives often unexpected
results. Adjust usages of MIN()/MAX() to ensure that the arguments agree
in signedness.
Adds a new WiFi 6GHz capability flag, NM_WIFI_DEVICE_CAP_FREQ_6GHZ,
along side the existing NM_WIFI_DEVICE_CAP_FREQ_2GHZ &
NM_WIFI_DEVICE_CAP_FREQ_5GHZ flags.
Gnome settings utilizes the 2 existing flags to present supported
bands in gnome-settings. I will be using this additional flag in
modifications there.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1739
The password currently generated has ~48 bits of entropy; increase the
length from 8 to 12 to get ~70 bits. While at it, exclude characters
that look similar and might be entered wrongly by users.
Since commit f18bf17dea ('wifi: cleanup
ensure_hotspot_frequency()'), NetworkManager automatically selects a
stable channel for AP connections that don't specify a fixed one. The
advantage of this approach is that NM can select a channel that works
well in the current regulatory domain.
However, nmcli still sets fixed channels 1 for 2.4GHz and 7 for 5GHz
when using the "device wifi hotspot". In particular, channel 7 on 5GHz
seems a bad choice because according to [1] it is not usable anywhere
in the world.
It seems difficult to select channel that works everywhere in the 5GHz
band, so it's better to not set a channel in the profile and let NM
find a usable one. For consistency, do the same also for the 2.4GHz
band even if the default choice (channel 1) should always work; by
letting NM choose a channel, different hotspot created with nmcli have
the chance of using different bands and not interfere with each other.
[1] https://en.wikipedia.org/wiki/List_of_WLAN_channels
The main purpose is to simplify printf debugging and manual testing. We
can now trivially patch the code so that all output from nmcli gets
(additionally) written to a file. That is useful when debugging a unit
test in "test-client.py". Thereby we can duplicate all messages via
nm_utils_print(), which is in sync with the debug messages from libnm
and which honors LIBNM_CLIENT_DEBUG_FILE.
nmc_print() will be used for something else. Rename. Also,
nmc_print_table() is the better name anyway because the function does a
lot of formatting and not simple printf().
g_random_*() is based on GRand, which is not a CSPRNG. Instead, rely on
kernel to give us good random numbers, which is what nm_random_*() does.
Note that nm_random_*() calls getrandom() (or reads /dev/urandom), which
most likely is slower than GRand. It doesn't matter for our uses though.
It is cumbersome to review all uses of g_rand_*() whether their usage of
a non-cryptographically secure generator is appropriate. Instead, just
always use an appropriate function, thereby avoiding this question. Even
glib documentation refers to reading "/dev/urandom" as alternative. Which
is what nm_random_*() does. These days, it seems unnecessary to not use
the best random generator available, unless it's not fast enough or you
need a stable/seedable stream of random numbers.
In particular in nmcli, we used g_random_int_range() to generate
passwords. That is not appropriate. Sure, it's *only* for the hotspot,
but still.
src/nmcli/devices.c:1196: double_free: Calling "_nm_auto_strfreev" frees pointer "arg_arr" which has already been freed.
Fixes: c5d45848dd ('cli: mark argv argument for command line parsing as const')
It seems really ugly, to pass a callback function of wrong
signature. Granted, it probably works due to the C calling
convention, but it seems odd.
Use callbacks of the proper type instead. Then we also don'
need g_signal_connect_swapped().
While at it, rename. "connected_state_cb()" seems a bad name.
Fix the following crash:
$ nmcli device monitor a
Error: Device 'a' not found.
Segmentation fault (core dumped)
Found by coverity:
1. NetworkManager-1.41.3/src/nmcli/devices.c:0: scope_hint: In function 'do_devices_monitor'
2. NetworkManager-1.41.3/src/nmcli/devices.c:2932:28: warning[-Wanalyzer-null-dereference]: dereference of NULL 'devices'
2930| }
2931|
2932|-> for (i = 0; i < devices->len; i++)
2933| device_watch(nmc, g_ptr_array_index(devices, i));
2934|
Fixes: 2074b28976 ('nmcli/devices: return GPtrArray instead of GSList from get_device_list()')
Before:
$ nmcli device connect veth0; echo $?
Error: Connection activation failed: (5) IP configuration could not be reserved (no available address, timeout, etc.).
0
After
$ nmcli device connect veth0; echo $?
Error: Connection activation failed: (5) IP configuration could not be reserved (no available address, timeout, etc.).
4
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/902
These variants provide additional nm_assert() checks, and are thus
preferable.
Note that we cannot just blindly replace &g_array_index() with
&nm_g_array_index(), because the latter would not allow getting a
pointer at index [arr->len]. That might be a valid (though uncommon)
usecase. The correct replacement of &g_array_index() is thus
nm_g_array_index_p().
I checked the code manually and replaced uses of nm_g_array_index_p()
with &nm_g_array_index(), if that was a safe thing to do. The latter
seems preferable, because it is familar to &g_array_index().
This is not good:
$ nmcli device delete nm-bond
Segmentation fault (core dumped)
Fixes: 5f9d2927ed ("nmcli/devices: use GPtrArray from get_device_list() directly")
Distinguish a OWE-TM enabled BSS (which itself is unencrypted) from the
OWE BSS actually employing encryption.
Signed-off-by: David Bauer <mail@david-bauer.net>
This is an interface to the Checkpoint/Restore functionality that's
available for quite some time. It runs a command with a checkpoint taken
and rolls back unless success is confirmed before the checkpoint times
out:
$ nmcli dev checkpoint eth0 -- nmcli dev dis eth0
Device 'eth0' successfully disconnected.
Type "Yes" to commit the changes: No
Checkpoint was removed.
The details about how it's used are documented in nmcli(1) and
nmcli-examples(7).
This makes get_device_list() return an array of NMDevices with a
reference taken and a destroy notifier that unhooks disconnect_state_cb,
so that it could replace the GSList of the same utility used by
disconnect/delete commands.
Suggested-by: Thomas Haller <thaller@redhat.com>
A pointer array is slightly more efficient here, since we don't really
need the ability to insert elements in the middle. In fact, we'd prefer
if we could just add to the end, so that we'd spare some callers from a
need to do a g_slist_reverse().
Even though that alone being a good reason to use a GPtrArray instead of
GSList, I'm doing this for so that I could actually use the returned value
as-is in a call to nm_client_checkpoint_create() in a future patch.
Don't consider "--" a device name. Instead, treat it as a signal to stop
reading the device list.
If a caller expects nothing beyond the device names, it now has to
check.
Prior to this patch, get_device_list() would give the caller no clue
about how many options did it consume. That is okay -- it would always
process all argument until the end, so the no callers would really care.
In a further patch, I'd like to allow termination of the device name
list (with a "--" arguments), so it will be possible to specify further
arguments.
Let's change the protype of this routine to use pointers to argc/argv,
that it will be possible to adjust them.
We want to warn the user if they're connecting to an insecure network:
$ nmcli d wifi
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
BA:00:6A:3C:C2:09 Secured Network Infra 2 54 Mbit/s 100 ▂▄▆█ WPA3
FA:7C:46:CC:9F:BE Ye Olde Wlan Infra 1 54 Mbit/s 100 ▂▄▆█ WEP
$ nmcli d wifi connect 'Ye Olde Wlan'
Warning: WEP encryption is known to be insecure.
...
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1224
(cherry picked from commit bf9a11f7c7)
It's helpful to control when data/state gets mutated. In particular,
when passing on a pointer via several hops. C can help with that
at compile time via "const".
But the "index" field of APInfo is actually mutable, as it counts
the lines. So most of the data is immutable, but the index.
Make APInfo const. But to do that, the mutable part must be moved to a
separate place.
Also, start with the counter initialized to zero instead of one.
It is just nicer.
On the D-Bus API, the current access point is referred exactly, by its
D-Bus path. Likewise, in libnm's NMClient cache, the access point
instance is unique in representing the D-Bus object (meaning, we
can directly use pointer equality).
Let's not compare the active AP based on the BSSID. It can happen
that the scan list contains the same BSSID multiple times (for example
on different bands). In that case, the output should only highlight
one AP as in-use:
$ nmcli device wifi list
IN-USE BSSID SSID MODE CHAN RATE SIGNAL BARS SECURITY
* E4:0f:4b:2a:c3:d1 MYSSID1 Infra 6 270 Mbit/s 100 ▂▄▆█ WPA2
* E4:0f:4b:2a:c3:d1 MYSSID1 Infra 6 270 Mbit/s 87 ▂▄▆█ WPA2
We use clang-format for automatic formatting of our source files.
Since clang-format is actively maintained software, the actual
formatting depends on the used version of clang-format. That is
unfortunate and painful, but really unavoidable unless clang-format
would be strictly bug-compatible.
So the version that we must use is from the current Fedora release, which
is also tested by our gitlab-ci. Previously, we were using Fedora 34 with
clang-tools-extra-12.0.1-1.fc34.x86_64.
As Fedora 35 comes along, we need to update our formatting as Fedora 35
comes with version "13.0.0~rc1-1.fc35".
An alternative would be to freeze on version 12, but that has different
problems (like, it's cumbersome to rebuild clang 12 on Fedora 35 and it
would be cumbersome for our developers which are on Fedora 35 to use a
clang that they cannot easily install).
The (differently painful) solution is to reformat from time to time, as we
switch to a new Fedora (and thus clang) version.
Usually we would expect that such a reformatting brings minor changes.
But this time, the changes are huge. That is mentioned in the release
notes [1] as
Makes PointerAligment: Right working with AlignConsecutiveDeclarations. (Fixes https://llvm.org/PR27353)
[1] https://releases.llvm.org/13.0.0/tools/clang/docs/ReleaseNotes.html#clang-format
Naming is important, because the name of a thing should give you a good
idea what it does. Also, to find a thing, it needs a good name in the
first place. But naming is also hard.
Historically, some strv helper API was named as nm_utils_strv_*(),
and some API had a leading underscore (as it is internal API).
This was all inconsistent. Do some renaming and try to unify things.
We get rid of the leading underscore if this is just a regular
(internal) helper. But not for example from _nm_strv_find_first(),
because that is the implementation of nm_strv_find_first().
- _nm_utils_strv_cleanup() -> nm_strv_cleanup()
- _nm_utils_strv_cleanup_const() -> nm_strv_cleanup_const()
- _nm_utils_strv_cmp_n() -> _nm_strv_cmp_n()
- _nm_utils_strv_dup() -> _nm_strv_dup()
- _nm_utils_strv_dup_packed() -> _nm_strv_dup_packed()
- _nm_utils_strv_find_first() -> _nm_strv_find_first()
- _nm_utils_strv_sort() -> _nm_strv_sort()
- _nm_utils_strv_to_ptrarray() -> nm_strv_to_ptrarray()
- _nm_utils_strv_to_slist() -> nm_strv_to_gslist()
- nm_utils_strv_cmp_n() -> nm_strv_cmp_n()
- nm_utils_strv_dup() -> nm_strv_dup()
- nm_utils_strv_dup_packed() -> nm_strv_dup_packed()
- nm_utils_strv_dup_shallow_maybe_a() -> nm_strv_dup_shallow_maybe_a()
- nm_utils_strv_equal() -> nm_strv_equal()
- nm_utils_strv_find_binary_search() -> nm_strv_find_binary_search()
- nm_utils_strv_find_first() -> nm_strv_find_first()
- nm_utils_strv_make_deep_copied() -> nm_strv_make_deep_copied()
- nm_utils_strv_make_deep_copied_n() -> nm_strv_make_deep_copied_n()
- nm_utils_strv_make_deep_copied_nonnull() -> nm_strv_make_deep_copied_nonnull()
- nm_utils_strv_sort() -> nm_strv_sort()
Note that no names are swapped and none of the new names existed
previously. That means, all the new names are really new, which
simplifies to find errors due to this larger refactoring. E.g. if
you backport a patch from after this change to an old branch, you'll
get a compiler error and notice that something is missing.