Commit Graph

82 Commits

Author SHA1 Message Date
Thomas Haller
78629830c8 all: add "libnm-core/nm-default-libnm-core.h" as replacement for "nm-default.h" 2021-02-09 12:38:18 +01:00
Thomas Haller
977ea352a0 all: update deprecated SPDX license identifiers
These SPDX license identifiers are deprecated ([1]). Update them.

[1] https://spdx.org/licenses/

  sed \
     -e '1 s%^/\* SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+ \*/$%/* SPDX-License-Identifier: \1-or-later */%' \
     -e '1,2 s%^\(--\|#\|//\) SPDX-License-Identifier: \(GPL-2.0\|LGPL-2.1\)+$%\1 SPDX-License-Identifier: \2-or-later%' \
     -i \
     $(git grep -l SPDX-License-Identifier -- \
         ':(exclude)shared/c-*/' \
         ':(exclude)shared/n-*/' \
         ':(exclude)shared/systemd/src' \
         ':(exclude)src/systemd/src')
2021-01-05 09:46:21 +01:00
Thomas Haller
a2b5e22f82 all: drop unnecessary cast for return value of g_object_new()
C casts unconditionally force the type, and as such they don't
necessarily improve type safety, but rather overcome restrictions
from the compiler when necessary.

Casting a void pointer is unnecessary (in C), it does not make the
code more readable nor more safe. In particular for g_object_new(),
which is known to return a void pointer of the right type.

Drop such casts.

  sed 's/([A-Za-z_0-9]\+ *\* *) *g_object_new/g_object_new/g' $(git grep -l g_object_new) -i
  ./contrib/scripts/nm-code-format-container.sh
2020-11-12 16:03:09 +01:00
Thomas Haller
88071abb43 all: unify comment style for SPDX-License-Identifier tag
Our coding style recommends C style comments (/* */) instead of C++
(//). Also, systemd (which we partly fork) uses C style comments for
the SPDX-License-Identifier.

Unify the style.

  $ sed -i '1 s#// SPDX-License-Identifier: \([^ ]\+\)$#/* SPDX-License-Identifier: \1 */#' -- $(git ls-files -- '*.[hc]' '*.[hc]pp')
2020-09-29 16:50:53 +02:00
Thomas Haller
740b092fda format: replace tabs for indentation in code comments
sed -i \
     -e 's/^'$'\t'' \*/     */g' \
     -e 's/^'$'\t\t'' \*/         */g' \
     -e 's/^'$'\t\t\t'' \*/             */g' \
     -e 's/^'$'\t\t\t\t'' \*/                 */g' \
     -e 's/^'$'\t\t\t\t\t'' \*/                     */g' \
     -e 's/^'$'\t\t\t\t\t\t'' \*/                         */g' \
     -e 's/^'$'\t\t\t\t\t\t\t'' \*/                             */g' \
     $(git ls-files -- '*.[hc]')
2020-09-28 16:07:52 +02:00
Antonio Cardace
328fb90f3e all: reformat all with new clang-format style
Run:

    ./contrib/scripts/nm-code-format.sh -i
    ./contrib/scripts/nm-code-format.sh -i

Yes, it needs to run twice because the first run doesn't yet produce the
final result.

Signed-off-by: Antonio Cardace <acardace@redhat.com>
2020-09-28 16:07:51 +02:00
Thomas Haller
7842da1606 libnm: convert vpn-secrets to D-Bus in stable order
We should generate the GVariant in a stable manner. That implies
to sort the keys first.

Also, don't use the NM_SETTING_VPN_SECRETS getter, which first needs
to clone all secrets.
2020-04-04 19:51:34 +02:00
Thomas Haller
3d9d2ad651 libnm: avoid cloning secrets during vpn_secrets_from_dbus()
When we use _nm_utils_strdict_from_dbus(), we clone the secrets, but don't use
nm_free_secret() for freeing them.

And in fact, we clone the setings twice. It't really not too nice. Implement
this without the property setter.
2020-04-04 19:51:34 +02:00
Thomas Haller
3bca926d20 libnm: refactor property setters of data and secrets in NMSettingVpn
Don't use _nm_utils_copy_strdict().

On a minor note, that function will always allocate a GHashTable, even if
it only contains "" as only key. Later we would throw that out again,
so it was unnecessary.

Worse, using _nm_utils_copy_strdict() does not use nm_free_secrets as
destroy function. While it's in general difficult to clear all places
in memory where we copy the secrets around, we can easily avoid that.

Also skip over %NULL keys and values. It probably would be a bug passing
such arguments to the property. Better ignore them and not crash.
2020-04-04 19:51:34 +02:00
Thomas Haller
117cbd1894 libnm: allow setting empty vpn.secrets item
Like for data, now also allow empty secrets to be added to the VPN
setting.

For one, this avoids an assertion failure, where keyfile reader wouldn't
check whether a secret key is set to the empty word.

For data, it's more clear that we want to allow setting empty data
values. VPN settings are only interpreted by the VPN plugin, so libnm
and the daemon shouldn't prevent empty settings. It can be useful to
distinguish between unset (NULL) and empty values.

For secrets, it's less clear that empty secrets shall be allowed. I
think it should. Of course, the empty secret likely isn't a correct
nor valid secret. But libnm cannot validate the secrets anyway. It's
up to the VPN plugin to handle this in any way they see fit.

Also, already before, the user could set NM_SETTING_VPN_SECRETS to
a string dictionary with empty passwords. So, the API didn't fully
prevent that. Only certain API wouldn't play along.
2020-04-04 19:51:34 +02:00
Thomas Haller
64da830b07 libnm: allow setting empty vpn.data item
Until now, nm_setting_vpn_add_data_item() would reject empty data values.
This leads for example to an assertion failure, if you write a keyfile
that assigns an empty value to a key. Keyfile reader would not check that
the value is non-empty before calling nm_setting_vpn_add_data_item().

Anyway, I think we should not require having non-empty data elements. It's
an unnecessary and sometimes harmful restriction. NetworkManager doesn't understand
not care about the content of the vpn data. That is up the VPN plugins. Sometimes
and empty value may be desirable.

Also, the NM_SETTING_VPN_DATA property setter wouldn't filter out empty
values either. So it was always possible to use some libnm API to set data
with empty values. The restriction in nm_setting_vpn_add_data_item() was
inconsistent.
2020-04-04 19:51:34 +02:00
Thomas Haller
8280c85fac libnm: ensure we have no empty secret keys in NMSettingVpn
Also drop the g_warn_if_fail() from update_secret_dict(). We
may get the variant from D-Bus, so avoiding this assertion (g_warn*() is
an assertion!) would require us to prevalidate the variant.
That would be very cumbersome, and we would probably not want to
handle that as an error and silently ignore them anyway. Just shut
up.
2020-04-04 19:51:34 +02:00
Thomas Haller
f51cf10ccc libnm: ensure we have no empty data keys in NMSettingVpn
Ensure that the data hash doesn't contain keys with empty key-name.
It just doesn't make sense, and will lead to potential problems later,
if we would allow this to happen.

For example, keyfile writer may naively try to set all keys, without
checking for empty keys. That may lead to assertion failures or worse,
later on. Don't allow that.

Also, assert against non-empty keys in nm_setting_vpn_get_data_item()
and nm_setting_vpn_remove_data_item(). This stricter handling is a
change in behavior, however it would have always been a bug trying to
refer to empty key names. So, this assertion will only help to find
those bugs.
2020-04-04 19:51:34 +02:00
Thomas Haller
05756ddc3a libnm: allocate "secrets" hash for NMSettingVpn lazily 2020-04-04 19:51:34 +02:00
Thomas Haller
7047fd212e libnm: allocate "data" hash for NMSettingVpn lazily
We always initialized priv->data in nm_setting_vpn_init(), but usually
soon after this hash would be replaced by NM_SETTING_VPN_DATA property
setter.

Avoid that. Allow for priv->data to be %NULL, which of course has the
meaning that no keys are set.
2020-04-04 19:51:34 +02:00
Thomas Haller
68328e0f21 libnm: fail get_secret_flags(),set_secret_flags() for empty secret name in NMSettingVpn 2020-04-04 19:51:34 +02:00
Thomas Haller
40e2603d4c libnm: make NMSettingVpn's foreach_item_helper() robust against changes
When we invoke the user's callback, be more robust about the user
modifying or unreferencing the NMSettingVpn, while iterating.

While it would be odd to modify the NMSettingVpn from inside the foreach
callback, we should behave consistently and sensibly.

That means, to ensure that the NMSettingVpn instance stays alive all
the time, that we don't crash, and that we always iterate over the
previously determined, planned list of keys.

Also, avoid some unnecessary string copies, like the clone of the first key.
2020-04-04 19:51:34 +02:00
Thomas Haller
c9bfdc2f75 libnm: use streq() instead of strcmp() for NMSettingVpn 2020-04-04 19:51:34 +02:00
Thomas Haller
c97b217772 libnm: drop unrechable g_warn_if_fail() assertion from NMSettingVpn's update_secret_dict()
For one, this code was unreachable, because we checked these conditions
already before.

That aside, g_warn_*() is for all intended purposes an assertion.
The caller probably gets the GVariant from an untrusted source (e.g. via
D-Bus). Asserting here is not helpful.
It's up to the caller to validate the argument. Or, in case the caller
doesn't care, update_secret_dict() should just do the sensible thing.
But be silent about it!
2020-04-04 19:51:34 +02:00
Thomas Haller
63ad9b7b1d libnm: avoid strlen() to determine whether a string is empty
Yes, the compiler probably can optimize strlen() in these cases. That
still doesn't make strlen() the right API to check whether a NUL
terminated string is empty.
2020-04-04 19:51:34 +02:00
Thomas Haller
7a1beb5667 libnm: use NM_STR_HAS_SUFFIX() in nm-setting-vpn.c's aggregate() 2020-04-04 19:51:34 +02:00
Thomas Haller
3b69f02164 all: unify format of our Copyright source code comments
```bash

readarray -d '' FILES < <(
  git ls-files -z \
    ':(exclude)po' \
    ':(exclude)shared/c-rbtree' \
    ':(exclude)shared/c-list' \
    ':(exclude)shared/c-siphash' \
    ':(exclude)shared/c-stdaux' \
    ':(exclude)shared/n-acd' \
    ':(exclude)shared/n-dhcp4' \
    ':(exclude)src/systemd/src' \
    ':(exclude)shared/systemd/src' \
    ':(exclude)m4' \
    ':(exclude)COPYING*'
  )

sed \
  -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) *[-–] *\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C1pyright#\5 - \7#\9/' \
  -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) *[,] *\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C2pyright#\5, \7#\9/' \
  -e 's/^\(--\|#\| \*\) *\(([cC]) *\)\?Copyright \+\(\(([cC])\) \+\)\?\(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/\1 C3pyright#\5#\7/' \
  -e 's/^Copyright \(\(20\|19\)[0-9][0-9]\) \+\([^ ].*\)$/C4pyright#\1#\3/' \
  -i \
  "${FILES[@]}"

echo ">>> untouched Copyright lines"
git grep Copyright "${FILES[@]}"

echo ">>> Copyright lines with unusual extra"
git grep '\<C[0-9]pyright#' "${FILES[@]}" | grep -i reserved

sed \
  -e 's/\<C[0-9]pyright#\([^#]*\)#\(.*\)$/Copyright (C) \1 \2/' \
  -i \
  "${FILES[@]}"

```

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/298
2019-10-02 17:03:52 +02:00
Thomas Haller
29a451d33a libnm: don't special case "vpn.secrets" property in property_to_dbus()
"nm-setting.c" (and property_to_dbus()) should stay independent of
actualy settings implementations. Instead, the property-info should
control the behavior.

What I like about this change is also that the generic handling is not a
flags "handle_secrets_for_vpn", but it just says to skip checking the
param-spec flags and directly call the to_dbus_fcn(). It's just a
generally useful thing to do, to let the to_dbus_fcn() function also
handle checking the property flags. The fact that only vpn.secrets
properties uses this for a certain pupose, is abstracted in a way that
makes sense.
2019-09-30 08:23:19 +02:00
Thomas Haller
a1b575b07b libnm/trivial: rename _properties_override_add_*() to _nm_properties_override_*()
These macros/functions are in a header file. Everything in a header file
should have an "nm" prefix. Rename.
2019-09-30 08:23:19 +02:00
Thomas Haller
275d850d1b libnm: replace _properties_override_add_override() with _properties_override_add_gobj() 2019-09-30 08:23:19 +02:00
Thomas Haller
d534b6d07a libnm: deduplicate NMSettInfoPropertType instances
There is no need to keep duplicate instances.

Before we had 89 distinct property types, now there are 49.
2019-09-30 08:23:19 +02:00
Thomas Haller
3f36f69156 libnm: refactor NMSettInfoProperty to save memory for simple properties
In total, we register 447 property informations. Out of these,
326 are plain, GObject property based without special implementations.

The NMSettInfoProperty had all function pointers directly embedded,
currently this amounts to 5 function pointers and the "dbus_type" field.

That means, at runtime we have 326 times trivial implementations with
waste 326*6*8 bytes of NULL pointers. We can compact these by moving
them to a separate structure.

Before:

    447 * 5 function pointers
    447 * "dbus_type" pointer
    = 2682 pointers

After:

    447 * 1 pointers (for NMSettInfoProperty.property_type)
     89 * 6 pointers (for the distinct NMSettInfoPropertType data)
    = 981 pointers

So, in total this saves 13608 byes of runtime memory (on 64 bit arch).

The 89 NMSettInfoPropertType instances are the remaining distinct instances.
Note that every NMSettInfoProperty has a "property_type" pointer, but most of them are
shared. That is because the underlying type and the operations are the same.

Also nice is that the NMSettInfoPropertType are actually constant,
static fields and initialized very early.

This change also makes sense form a design point of view. Previously,
NMSettInfoProperty contained both per-property data (the "name") but
also the behavior. Now, the "behavioral" part is moved to a separate
structure (where it is also shared). That means, the parts that are
concerned with the type of the property (the behavior) are separate
from the actual data of the property.
2019-09-30 08:23:19 +02:00
Beniamino Galvani
43b7e66948 settings: fix updating agent-owned VPN secrets
property_to_dbus() returns NULL when called with
NM_CONNECTION_SERIALIZE_WITH_SECRETS_AGENT_OWNED and the property is
not an agent-owned secrets. The function doesn't handle VPN secrets
correctly, since they are all stored as a hash in the vpn.secrets
property and the flag for each of them is a matching '*-flags' key in
the vpn.data property. VPN secrets must be handled differently; do it
in the VPN setting to_dbus_fcn() function.

Fixes: 71928a3e5c ('settings: avoid cloning the connection to maintain agent-owned secrets')

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/230
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/280
2019-09-24 17:00:22 +02:00
Lubomir Rintel
24028a2246 all: SPDX header conversion
$ find * -type f |xargs perl contrib/scripts/spdx.pl
  $ git rm contrib/scripts/spdx.pl
2019-09-10 11:19:56 +02:00
Thomas Haller
4952e945dc libnm: try to avoid coverity warning in assertion()
Coverity thinks that this could be NULL sometimes. Try to check for that
to shut up the warning.

(cherry picked from commit f61e274df9)
2019-08-02 11:10:50 +02:00
Thomas Haller
c0e075c902 all: drop emacs file variables from source files
We no longer add these. If you use Emacs, configure it yourself.

Also, due to our "smart-tab" usage the editor anyway does a subpar
job handling our tabs. However, on the upside every user can choose
whatever tab-width he/she prefers. If "smart-tabs" are used properly
(like we do), every tab-width will work.

No manual changes, just ran commands:

    F=($(git grep -l -e '-\*-'))
    sed '1 { /\/\* *-\*-  *[mM]ode.*\*\/$/d }'     -i "${F[@]}"
    sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}"

Check remaining lines with:

    git grep -e '-\*-'

The ultimate purpose of this is to cleanup our files and eventually use
SPDX license identifiers. For that, first get rid of the boilerplate lines.
2019-06-11 10:04:00 +02:00
Thomas Haller
b1344b6b94 libnm: pass connection to compare_property() function
We have certain artificial properties that not only depend on one
property alone or that depend on a property in another(!) setting.

For that, we have synth_func.

Other than that, synth_func and get_func are really fundamentally
similar and should be merged. That is because the distinction whether a
property value is "synthetized" or just based on a plain property is
minor. It's better to have the general concept of "convert property to
GVariant" in one form only.

Note that compare_property() is by default implemented based
on get_func. Hence, if get_func and synth_func get merged,
compare_property() will also require access to the NMConnection.

Also it makes some sense: some properties are artificial and actually
stored in "another" setting of the connection. But still, the property
descriptor for the property is in this setting. The example is the
"bond.interface-name" which only exists on D-Bus. It's stored as
"connection.interface-name".
I don't really like to say "exists on D-Bus only". It's still a valid
property, despite in NMSetting it's stored somehow differently (or not
at all). So, this is also just a regular property for which we have a
property-info vtable.
Does it make sense to compare such properties? Maybe. But the point is that
compare_property() function needs sometimes access to the entire
connection. So add the argument.
2019-05-01 13:46:32 +02:00
Thomas Haller
d984b2ce4a shared: move most of "shared/nm-utils" to "shared/nm-glib-aux"
From the files under "shared/nm-utils" we build an internal library
that provides glib-based helper utilities.

Move the files of that basic library to a new subdirectory
"shared/nm-glib-aux" and rename the helper library "libnm-core-base.la"
to "libnm-glib-aux.la".

Reasons:

 - the name "utils" is overused in our code-base. Everything's an
   "utils". Give this thing a more distinct name.

 - there were additional files under "shared/nm-utils", which are not
   part of this internal library "libnm-utils-base.la". All the files
   that are part of this library should be together in the same
   directory, but files that are not, should not be there.

 - the new name should better convey what this library is and what is isn't:
   it's a set of utilities and helper functions that extend glib with
   funcitonality that we commonly need.

There are still some files left under "shared/nm-utils". They have less
a unifying propose to be in their own directory, so I leave them there
for now. But at least they are separate from "shared/nm-glib-aux",
which has a very clear purpose.

(cherry picked from commit 80db06f768)
2019-04-18 19:57:27 +02:00
Thomas Haller
395738900f libnm: don't use strlen() for checking for non-empty string
It's well understood that these are NUL terminated strings.
We don't need strlen() to check that the strings aren't
empty.
2019-03-25 09:12:32 +01:00
Marco Trevisan (Treviño)
b5bbf8edc2 nm: Fix syntax on introspection annotations
Various annotations were added using multiple colons, while only one has
to be added or g-ir-introspect will consider them part of the description

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/94
(cherry picked from commit 73005fcf5b)
2019-03-07 10:09:23 +01:00
Thomas Haller
28c53ea37e libnm/trivial: rename NM_SETTING_SECRET_FLAG_ALL flag (formerly NM_SETTING_SECRET_FLAGS_ALL)
It should mirror the naming pattern of the flags.
2019-02-14 08:00:29 +01:00
Thomas Haller
a3370af3a8 all: drop unnecessary includes of <errno.h> and <string.h>
"nm-macros-interal.h" already includes <errno.h> and <string.h>.
No need to include it everywhere else too.
2019-02-12 08:50:28 +01:00
Thomas Haller
353e619c9f libnm,core: make for-each-secret implementation virtual functions of NMSetting
We already need to special handle regular settings (with secrets as
GObject properties) and VPN secrets.

Next, we will also need to special handle WireGuard peers, which can
have secrets too.

Move the code to a virtual function, so that "nm-connection.c" and
"nm-setting.c" does not have explicit per-setting knowledge.
2019-02-04 20:15:20 +01:00
Thomas Haller
b64e24dcd7 libnm: rework _nm_setting_aggregate() to delegate to setting class
Instead of special-casing the aggregate implementation for NMSettingVpn,
delegate to a virtual function.

This will also work with other settings, that have properties/secrets
that are not GObject based properties.
2019-02-04 20:15:20 +01:00
Thomas Haller
08a0f682e1 libnm: always call clear_secrets() function for all properties
And merge it with the version that uses no flags.

Previously, clear_secrets(_with_flags()) was only implemented
by NMSettingVpn. All other settings would only consider GObject-based
properties.

As we will add secrets that have no GObject property, call the virtual
function always, so that the setting can hook into this (for WireGuard
peers).
2019-01-22 16:30:23 +01:00
Thomas Haller
d2388250d6 libnm: fix secret-name parameter in NMSettingClearSecretsWithFlagsFn for VPN
The secret name should be the one that we can pass to nm_setting_get_secret_flags().
It's wrong to call the function repeatedly with secret-name "secrets".

Probably nobody cared anyway about the name. nm_connection_clear_secrets_with_func()
is used to clear secrets based on the flags, not the secret-name.

Fixes: 2b2404bbef
2019-01-22 16:30:23 +01:00
Thomas Haller
19141ef770 libnm-core: reorder code in settings
Order the code in our common way. No other changes.

- ensure to include the main header first (directly after
  "nm-default.h").

- reorder function definitions: get_property(), set_property(),
  *_init(), *_new(), finalize(), *_class_init().
2019-01-15 09:55:24 +01:00
Thomas Haller
a3d6976efc libnm-core: cleanup NMSetting's class initialization
Unify the coding style for class-init functions in libnm-core.

Also make use of obj_properties, NM_GOBJECT_PROPERTIES_DEFINE(), and
_notify().
2019-01-15 09:55:24 +01:00
Thomas Haller
885c872d5a libnm: rework compare_property() implementation for NMSetting
NMSetting's compare_property() has and had two callers:
nm_setting_compare() and nm_setting_diff().

compare_property() accepts a NMSettingCompareFlags argument, but
at the same time, both callers have another complex (and
inconsistent!) set of pre-checks for shortcuting the call of
compare_property(): should_compare_prop().

Merge should_compare_prop() into compare_property(). This way,
nm_setting_compare() and nm_setting_diff() has less additional
code, and are simpler to follow. Especially nm_setting_compare()
is now trivial. And nm_setting_diff() is still complicated, but
not related to the question how the property compares or whether
it should be compared at all.

If you want to know whether it should be compared, all you need to do
now is follow NMSettingClass.compare_property().

This changes function pointer NMSettingClass.compare_property(),
which is public API. However, no user can actually use this (and shall
not!), because _nm_setting_class_commit_full() etc. is private API. A
user outside of libnm-core cannot create his/her own subclasses of
NMSetting, and never could in the past. So, this API/ABI change doesn't
matter.
2019-01-11 11:48:47 +01:00
Thomas Haller
a5b20ba211 libnm-core: add _nm_setting_secret_flags_valid() helper
Secret-flags are flags, but most combinations don't actually make sense
and maybe should be rejected. Anyway, that is not done, and most places
just check that there are no unknown flags set.

Add _nm_setting_secret_flags_valid() to perform the check at one place
instead of having the implementation at various places.
2019-01-07 11:20:56 +01:00
Thomas Haller
7771473f46 libnm,core: add _nm_connection_aggregate() to replace nm_connection_for_each_setting_value()
We should no longer use nm_connection_for_each_setting_value() and
nm_setting_for_each_value(). It's fundamentally broken as it does
not work with properties that are not backed by a GObject property
and it cannot be fixed because it is public API.

Add an internal function _nm_connection_aggregate() to replace it.

Compare the implementation of the aggregation functionality inside
libnm with the previous two checks for secret-flags that it replaces:

- previous approach broke abstraction and require detailed knowledge of
  secret flags. Meaning, they must special case NMSettingVpn and
  GObject-property based secrets.
  If we implement a new way for implementing secrets (like we will need
  for WireGuard), then this the new way should only affect libnm-core,
  not require changes elsewhere.

- it's very inefficient to itereate over all settings. It involves
  cloning and sorting the list of settings, and retrieve and clone all
  GObject properties. Only to look at secret properties alone.

_nm_connection_aggregate() is supposed to be more flexible then just
the two new aggregate types that perform a "find-any" search. The
@arg argument and boolean return value can suffice to implement
different aggregation types in the future.

Also fixes the check of NMAgentManager for secret flags for VPNs
(NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS). A secret for VPNs
is a property that either has a secret or a secret-flag. The previous
implementation would only look at present secrets and
check their flags. It wouldn't check secret-flags that are
NM_SETTING_SECRET_FLAG_NONE, but have no secret.
2019-01-07 10:54:28 +01:00
Thomas Haller
4a5514dc0f libnm: cleanup secret-flags setter and getter
There are 3 kinds of secret flag implementations:

1) regular properties have a GObject property and a corresponding
  "-flags" property.

2) NMSettingVpn handles this entirely differently

3) NMSettingWirelessSecurity's WEP keys, where the secret keys
   share a flags property that does not follow the same naming
   scheme as 1).

The getter and setter had a boolean "verifiy_secret", only to
handle 3). Drop that parameter. Don't let NMSettingWirelessSecurity
call the parent's implementation for WEP keys. Just let it handle
it directly.
2019-01-07 10:42:33 +01:00
Thomas Haller
9c139b2c47 libnm: cleanup NMSettingVpn's get_secret_flags()
- most of the time, the secret-name is short and fits in a
  stack-allocated buffer.
  Optimize for that by using nm_construct_name_a().

- use _nm_utils_ascii_str_to_int64() instead of strtoul().

       tmp = strtoul ((const char *) val, NULL, 10);
       if ((errno != 0) || (tmp > NM_SETTING_SECRET_FLAGS_ALL)) {

  is not the right way to check for errors of strtoul().

- refactor the code to return-early on errors.

- since commit 9b96bfaa72 "setting-vpn: whatever is in vpn.secrets always
  is a secrets", we accept secrets without secret-flags as valid too.
  However, only do that, when we at least have a corresponding key in
  priv->secrets hash. If the secret name is not used at all, it's
  clearly not a secret.

- if the secret flags are not a valid number, pretend that the flags
  are still set to "none" (zero). That is because we use the presence
  of the "*-flags" data item as indication that this is in fact a
  secret. The user cannot use data items with such a name for another
  purpose, so on failure, we still claim that this is in fact a secret.
2019-01-07 10:41:00 +01:00
Thomas Haller
b232508707 shared: add nm-secret-utils.h helper
We already had nm_free_secret() to clear the secret out
of a NUL terminated string. That works well for secrets
which are strings, it can be used with a cleanup attribute
(nm_auto_free_secret) and as a cleanup function for a
GBytes.

However, it does not work for secrets which are binary.
For those, we must also track the length of the allocated
data and clear it.

Add two new structs NMSecretPtr and NMSecretBuf to help
with that.
2018-09-04 07:38:30 +02:00
Thomas Haller
3793804314 libnm: rework setting metadata for property handling
NMSetting internally already tracked a list of all proper GObject properties
and D-Bus-only properties.

Rework the tracking of the list, so that:

- instead of attaching the data to the GType of the setting via
  g_type_set_qdata(), it is tracked in a static array indexed by
  NMMetaSettingType. This allows to find the setting-data by simple
  pointer arithmetic, instead of taking a look and iterating (like
  g_type_set_qdata() does).

  Note, that this is still thread safe, because the static table entry is
  initialized in the class-init function with _nm_setting_class_commit().
  And it only accessed by following a NMSettingClass instance, thus
  the class constructor already ran (maybe not for all setting classes,
  but for the particular one that we look up).

  I think this makes initialization of the metadata simpler to
  understand.
  Previously, in a first phase each class would attach the metadata
  to the GType as setting_property_overrides_quark(). Then during
  nm_setting_class_ensure_properties() it would merge them and
  set as setting_properties_quark(). Now, during the first phase,
  we only incrementally build a properties_override GArray, which
  we finally hand over during nm_setting_class_commit().

- sort the property infos by name and do binary search.

Also expose this meta data types as internal API in nm-setting-private.h.
While not accessed yet, it can prove beneficial, to have direct (internal)
access to these structures.

Also, rename NMSettingProperty to NMSettInfoProperty to use a distinct
naming scheme. We already have 40+ subclasses of NMSetting that are called
NMSetting*. Likewise, NMMetaSetting* is heavily used already. So, choose a
new, distinct name.
2018-08-10 10:38:19 +02:00