Commit Graph

24 Commits

Author SHA1 Message Date
Thomas Haller
b8ea61d26e libnm/keyfile: clear memory when reading certificates from keyfile
Of course, there are countless places where we get it wrong to clear
the memory. In particular, glib's GKeyFile implementation does
not care about that.

Anyway, the keyfile do contain private sensitive data. Adjust
a few places to zero out such data from memory.
2018-09-04 07:38:30 +02:00
Thomas Haller
0fdd42e24c libnm/keyfile: avoid GByteArray to construct path uri in nm_keyfile_detect_unqualified_path_scheme() 2018-09-04 07:38:30 +02:00
Thomas Haller
fcf254c03a libnm/keyfile: fix double free in keyfile's get_bytes()
Fixes: 5e7b14af03
2018-09-04 07:38:30 +02:00
Thomas Haller
4e0f1b16b9 libnm: add generic-data for implementing NMSetting
Add a new way how NMSetting subclasses can be implemented.

Currently, most NMSetting implementations realize all their properties
via GObject properties. That has some downsides:

 - the biggest one, is the large effort to add new properties.
   Most of them are implemented on a one-by-one basis and they come
   with additional API (like native getter functions).
   It makes it cumbersome to add more properties.

 - for certain properties, it's hard to encode them entirely in
   a GObject property. That results in unusable API like
   NM_SETTING_IP_CONFIG_ADDRESSES, NM_SETTING_BOND_OPTIONS,
   NM_SETTING_USER_DATA. These complex valued properties only
   exist, because we currently always need GObject properties
   to even implement simple functionality. For example,
   nm_setting_duplicate() is entirely implemented via
   nm_setting_enumerate_values(), which can only iterate
   GObject properies. There is no reason why this is necessary.
   Note also how nmcli badly handles bond options and VPN
   data. That is only a shortcoming of nmcli and wouldn't
   need to be that way. But it happend, because we didn't
   keep an open mind that settings might be more than just
   accessing GObject properties.

 - a major point of NMSetting is to convert to/from a GVariant
   from the D-Bus API. As NMSetting needs to squeeze all values
   into the static GObject structure, there is no place to
   encode invalid or unknown properties. Optimally,
   _nm_setting_new_from_dbus() does not loose any information
   and a subsequent _nm_setting_to_dbus() can restore the original
   variant. That is interesting, because we want that an older
   libnm client can talk to a newer NetworkManager version. The
   client needs to handle unknown properties gracefully to stay
   forward compatible. However, it also should not just drop the
   properties on the floor.
   Note however, optimally we want that nm_setting_verify() still
   can reject settings that have such unknown/invalid values. So,
   it should be possible to create an NMSetting instance without
   error or loosing information. But verify() should be usable to
   identify such settings as invalid.

They also have a few upsides.

 - libnm is heavily oriented around GObject. So, we generate
   our nm-settings manual based on the gtk-doc. Note however,
   how we fail to generate a useful manual for bond.options.
   Also note, that there is no reason we couldn't generate
   great documentation, even if the properties are not GObject
   properties.

 - GObject properties do give some functionality like meta-data,
   data binding and notification. However, the meta-data is not
   sufficient on its own. Note how keyfile and nmcli need extensive
   descriptor tables on top of GObject properties, to make this
   useful. Note how GObject notifications for NMSetting instances
   are usually not useful, aside for data binding like nmtui does.

Also note how NMSettingBond already follows a different paradigm
than using GObject properties. Nowdays, NMSettingBond is considered
a mistake (related bug rh#1032808). Many ideas of NMSettingBond
are flawed, like exposing an inferiour API that reduces everything
to a string hash. Also, it only implemented the options hash inside
NMSettingBond. That means, if we would consider this a good style,
we would have to duplicate this approach in each new setting
implementation.

Add a new style to track data for NMSetting subclasses. It keeps
an internal hash table with all GVariant properies. Also, the
functionality is hooked into NMSetting base class, so all future
subclasses that follow this way, can benefit from this. This approach
has a few similiarties with NMSettingBond, but avoids its flaws.

With this, we also no longer need GObject properties (if we would
also implement generating useful documentation based on non-gkt-doc).
They may be added as accessors if they are useful, but there is no
need for them.

Also, handling the properties as a hash of variants invites for a
more generic approach when handling them. While we still could add
accessors that operate on a one-by-one bases, this leads to a more
generic usage where we apply common functionality to a set of properties.

Also, this is for the moment entirely internal and an implementation
detail. It's entirely up to the NMSetting subclass to make use of this
new style. Also, there are little hooks for the subclass available.
If they turn out to be necessary, they might be added. However, for
the moment, the functionality is restricted to what is useful and
necessary.
2018-08-10 10:38:19 +02:00
Thomas Haller
2b43ce3a94 libnm/keyfile: use NMMetaSettingInfo for indexing keyfile vtable
We have NMMetaSettingType enum, which is an enum of all setting types.
We also have an efficient way to get the enum (and its NMMetaSettingInfo)
from an NMSetting, setting-name and GType.

No longer maintain the vtable for keyfile by "setting-name". Instead,
index it by NMMetaSettingType enum.

That way, we get efficient lookup, and don't need to duplicate the
functionality of finding the vtable entry for a setting.
2018-08-10 10:38:19 +02:00
Thomas Haller
a587d32467 shared: move nm_utils_ptrarray_find_binary_search() to shared utils 2018-08-10 10:38:19 +02:00
Thomas Haller
d32da2daaa shared: move nm_utils_array_find_binary_search() to shared utils 2018-08-10 10:38:19 +02:00
Thomas Haller
09031978bb keyfile: fix asserting for absolute base-dir in nm_keyfile_read() 2018-08-10 10:38:19 +02:00
Beniamino Galvani
a9b4532fa7 libnm-core: add SR-IOV setting
Add a setting containing SR-IOV parameters.
2018-07-11 16:16:22 +02:00
Thomas Haller
e1c7a2b5d0 all: don't use gchar/gshort/gint/glong but C types
We commonly don't use the glib typedefs for char/short/int/long,
but their C types directly.

    $ git grep '\<g\(char\|short\|int\|long\|float\|double\)\>' | wc -l
    587
    $ git grep '\<\(char\|short\|int\|long\|float\|double\)\>' | wc -l
    21114

One could argue that using the glib typedefs is preferable in
public API (of our glib based libnm library) or where it clearly
is related to glib, like during

  g_object_set (obj, PROPERTY, (gint) value, NULL);

However, that argument does not seem strong, because in practice we don't
follow that argument today, and seldomly use the glib typedefs.
Also, the style guide for this would be hard to formalize, because
"using them where clearly related to a glib" is a very loose suggestion.

Also note that glib typedefs will always just be typedefs of the
underlying C types. There is no danger of glib changing the meaning
of these typedefs (because that would be a major API break of glib).

A simple style guide is instead: don't use these typedefs.

No manual actions, I only ran the bash script:

  FILES=($(git ls-files '*.[hc]'))
  sed -i \
      -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>\( [^ ]\)/\1\2/g' \
      -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>  /\1   /g' \
      -e 's/\<g\(char\|short\|int\|long\|float\|double\)\>/\1/g' \
      "${FILES[@]}"
2018-07-11 12:02:06 +02:00
Thomas Haller
a5a2a92618 libnm/keyfile: add static assertion for ParseInfoProperty 2018-06-28 09:48:34 +02:00
Lubomir Rintel
e69d386975 all: use the elvis operator wherever possible
Coccinelle:

  @@
  expression a, b;
  @@
  -a ? a : b
  +a ?: b

Applied with:

  spatch --sp-file ternary.cocci --in-place --smpl-spacing --dir .

With some manual adjustments on spots that Cocci didn't catch for
reasons unknown.

Thanks to the marvelous effort of the GNU compiler developer we can now
spare a couple of bits that could be used for more important things,
like this commit message. Standards commitees yet have to catch up.
2018-05-10 14:36:58 +02:00
Beniamino Galvani
1b5925ce88 all: remove consecutive empty lines
Normalize coding style by removing consecutive empty lines from C
sources and headers.

https://github.com/NetworkManager/NetworkManager/pull/108
2018-04-30 16:24:52 +02:00
Thomas Haller
3b03b2caee keyfile: don't hack certain properties to be skipped in reader
For writer there is no such hack either. The property-info table
should describe whether to skip a property or not.
2018-04-19 09:45:19 +02:00
Thomas Haller
8c4ce431a6 keyfile: no special handling to set parser_no_check_key for certain settings
Do not have multiple ways of expressing a certain thing. There is
a way how to express that the parser shouldn't check for keys, and
that is via the parse-information. No extra hacks.
2018-04-19 09:36:41 +02:00
Thomas Haller
9c91d44667 keyfile: drop unused set_default_for_missing_key() 2018-04-19 09:36:41 +02:00
Thomas Haller
7e3b7295a4 keyfile: rework handling of checking for whether a key exists in reader
Rework this to have a value "parser_no_check_key" so that:

- the default value for this is FALSE, so that we don't need to
  explicitly set it in @parse_infos to only get the default.
  Contrary to check_for_key.
- check_for_key only had meaning when also "parser" was set.
  That means, the value was really "pip->parser && pip->check_for_key".
  That came from the fact, that orginally this was tracked as
  key_parsers array, which had "parser" always set.
  That is confusing, don't do that. The field "parser_no_check_key"
  has it's meaning, regardless of whether "parser" is set.
2018-04-19 09:36:41 +02:00
Thomas Haller
87cc309249 keyfile: various cleanup of error paths in keyfile handling 2018-04-19 09:36:41 +02:00
Thomas Haller
4dc933174e keyfile: don't special case skipping connection.read-only property in writer 2018-04-19 09:36:41 +02:00
Thomas Haller
94a96b70d0 keyfile: rework handling not skipping default-values in writer 2018-04-19 09:36:41 +02:00
Thomas Haller
a5c026f90e libnm/keyfile: replace dummy writer implementation with flag to skip writing 2018-04-19 09:36:41 +02:00
Thomas Haller
3695d5273a libnm/keyfile: merge parser/writer vtables for keyfile properties 2018-04-19 09:36:41 +02:00
Thomas Haller
21f6058cfe libnm/keyfile: merge keyfile sources (pt2, merge nm-keyfile-writer.c)
Splitting keyfile handling in two "reader.c" and "writer.c" files
is not helpful. What is most interesting, is to see how property XYZ
is serialized to keyfile, and to verify that the parser does the
inverse. For that, it's easier if both the write_xzy() and parse_xyz()
function are beside each other, and not split accross files.

The more important reason is, that both reader and writer have their
separate handler arrays, for special handling of certain properties:
@key_parsers and @key_writers. These two should not be separate but will
be merged. Since they reference static functions, these functions must
all be in the same source file (unless, we put them into headers, which
would be unnecessary complex).

No code was changed, only moved.
2018-04-19 09:36:41 +02:00
Thomas Haller
f99dc6b936 libnm/keyfile: merge keyfile sources (pt1, rename nm-keyfile-reader.c)
I am going to merge the files for keyfile handling in libnm-core.
There is a reason for that, I'll tell you next.
2018-04-19 09:36:41 +02:00