NetworkManager/src/settings/plugins
Thomas Haller 96cabbcbb8 all: make MAC address randomization algorithm configurable
For the per-connection settings "ethernet.cloned-mac-address"
and "wifi.cloned-mac-address", and for the per-device setting
"wifi.scan-rand-mac-address", we may generate MAC addresses using
either the "random" or "stable" algorithm.

Add new properties "generate-mac-address-mask" that allow to configure
which bits of the MAC address will be scrambled.

By default, the "random" and "stable" algorithms scamble all bits
of the MAC address, including the OUI part and generate a locally-
administered, unicast address.

By specifying a MAC address mask, we can now configure to perserve
parts of the current MAC address of the device. For example, setting
"FF:FF:FF:00:00:00" will preserve the first 3 octects of the current
MAC address.

One can also explicitly specify a MAC address to use instead of the
current MAC address. For example, "FF:FF:FF:00:00:00 68:F7:28:00:00:00"
sets the OUI part of the MAC address to "68:F7:28" while scrambling
the last 3 octects.
Similarly, "02:00:00:00:00:00 00:00:00:00:00:00" will scamble
all bits of the MAC address, except clearing the second-least
significant bit. Thus, creating a burned-in address, globally
administered.

One can also supply a list of MAC addresses like
"FF:FF:FF:00:00:00 68:F7:28:00:00:00 00:0C:29:00:00:00 ..." in which
case a MAC address is choosen randomly.

To fully scamble the MAC address one can configure
"02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00".
which also randomly creates either a locally or globally administered
address.

With this, the following macchanger options can be implemented:

  `macchanger --random`
   This is the default if no mask is configured.
   -> ""
   while is the same as:
   -> "00:00:00:00:00:00"
   -> "02:00:00:00:00:00 02:00:00:00:00:00"

  `macchanger --random --bia`
   -> "02:00:00:00:00:00 00:00:00:00:00:00"

  `macchanger --ending`
   This option cannot be fully implemented, because macchanger
   uses the current MAC address but also implies --bia.
   -> "FF:FF:FF:00:00:00"
      This would yields the same result only if the current MAC address
      is already a burned-in address too. Otherwise, it has not the same
      effect as --ending.
   -> "FF:FF:FF:00:00:00 <MAC_ADDR>"
      Alternatively, instead of using the current MAC address,
      spell the OUI part out. But again, that is not really the
      same as macchanger does because you explictly have to name
      the OUI part to use.

  `machanger --another`
  `machanger --another_any`
  -> "FF:FF:FF:00:00:00 <MAC_ADDR> <MAC_ADDR> ..."
     "$(printf "FF:FF:FF:00:00:00 %s\n" "$(sed -n 's/^\([0-9a-fA-F][0-9a-fA-F]\) \([0-9a-fA-F][0-9a-fA-F]\) \([0-9a-fA-F][0-9a-fA-F]\) .*/\1:\2:\3:00:00:00/p' /usr/share/macchanger/wireless.list | xargs)")"
2016-06-30 08:32:50 +02:00
..
ibft all/tests: split core part out of "nm-test-utils.h" 2016-05-17 16:48:52 +02:00
ifcfg-rh all: make MAC address randomization algorithm configurable 2016-06-30 08:32:50 +02:00
ifnet ifnet: fix memory leaks 2016-06-03 22:19:38 +02:00
ifupdown ifupdown/tests: fix memory leaks 2016-06-03 22:19:38 +02:00
keyfile tests: add macro NMTST_G_RETURN_MSG for expecting g_return*() failures 2016-06-09 12:03:39 +02:00
Makefile.am settings/example: remove 'example' settings plugin 2015-06-12 15:59:40 +02:00
README core: fix interface type names 2015-09-10 13:43:47 -04:00

Plugins generally have three components:

1) plugin object: manages the individual "connections", which are
  just objects wrapped around on-disk config data.  The plugin handles requests
  to add new connections via the NM D-Bus API, and also watches config
  directories for changes to configuration data.  Plugins implement the
  NMSettingsPlugin interface.  See plugin.c.

2) "connections": subclasses of NMSettingsConnection.  They handle updates to
  configuration data, deletion, etc.  See NMKeyfileConnection.

3) reader/writer code: typically a separate static library that gets linked
  into the main plugin shared object, so they can be unit tested separately
  from the plugin.  This code should read config data from disk and create
  an NMConnection from it, and be capable of taking an NMConnection and writing
  out appropriate configuration data to disk.

NM will first call the "factory" function that every module must provide, which
is nm_settings_plugin_factory().  That function creates and returns a singleton
instance of the plugin's main object, which implements NMSettingsPlugin.
That interface is implemented via the object definition in G_DEFINE_TYPE_EXTENDED
in plugin.c, which registers the interface setup function
settings_plugin_interface_init(), which when called actually sets up the vtables
for the functions defined by NMSettingsPluginInterface.  Thus there are two
entry points into the plugin:  nm_settings_plugin_factory() and
the NMSettingsPluginInterface methods.

The plugin also emits various signals (defined by NMSettingsPluginInterface)
which NetworkManager listens for.  These include notifications of new
connections if they were created via changes to the on-disk files.  The
"connection" objects can also emit signals (defined by the NMSettingsConnection
and NMConnection superclasses) when the connections' backing storage gets
changed or deleted.