summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am87
-rw-r--r--src/Makefile.in273
-rw-r--r--src/NetworkManager.conf20
-rw-r--r--src/NetworkManagerUtils.c130
-rw-r--r--src/NetworkManagerUtils.h7
-rw-r--r--src/backends/Makefile.in50
-rw-r--r--src/bluez-manager/Makefile.in50
-rw-r--r--src/bluez-manager/nm-bluez-device.c2
-rw-r--r--src/bluez-manager/nm-bluez-manager.c4
-rw-r--r--src/dhcp-manager/Makefile.in50
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c16
-rw-r--r--src/dhcp-manager/nm-dhcp-client.h25
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient.c83
-rw-r--r--src/dhcp-manager/nm-dhcp-dhcpcd.c6
-rw-r--r--src/dhcp-manager/nm-dhcp-manager.c4
-rw-r--r--src/dhcp-manager/tests/Makefile.in50
-rw-r--r--src/dns-manager/Makefile.in50
-rw-r--r--src/dns-manager/nm-dns-bind.c2
-rw-r--r--src/dns-manager/nm-dns-manager.h1
-rw-r--r--src/dnsmasq-manager/Makefile.in50
-rw-r--r--src/ip6-manager/Makefile.in50
-rw-r--r--src/logging/Makefile.in50
-rw-r--r--src/logging/nm-logging.c13
-rw-r--r--src/logging/nm-logging.h5
-rw-r--r--src/main.c46
-rw-r--r--src/modem-manager/Makefile.am7
-rw-r--r--src/modem-manager/Makefile.in70
-rw-r--r--src/modem-manager/nm-modem-cdma.c40
-rw-r--r--src/modem-manager/nm-modem-gsm.c55
-rw-r--r--src/modem-manager/nm-modem-manager.c2
-rw-r--r--src/modem-manager/nm-modem.c217
-rw-r--r--src/modem-manager/nm-modem.h40
-rw-r--r--src/nm-activation-request.c693
-rw-r--r--src/nm-activation-request.h34
-rw-r--r--src/nm-active-connection.c31
-rw-r--r--src/nm-active-connection.h4
-rw-r--r--src/nm-dbus-manager.c22
-rw-r--r--src/nm-dbus-manager.h4
-rw-r--r--src/nm-device-bt.c238
-rw-r--r--src/nm-device-cdma.c75
-rw-r--r--src/nm-device-cdma.h55
-rw-r--r--src/nm-device-ethernet.c486
-rw-r--r--src/nm-device-gsm.c75
-rw-r--r--src/nm-device-gsm.h55
-rw-r--r--src/nm-device-interface.c5
-rw-r--r--src/nm-device-modem.c192
-rw-r--r--src/nm-device-modem.h8
-rw-r--r--src/nm-device-olpc-mesh.c57
-rw-r--r--src/nm-device-private.h2
-rw-r--r--src/nm-device-wifi.c1051
-rw-r--r--src/nm-device.c332
-rw-r--r--src/nm-device.h23
-rw-r--r--src/nm-ip4-config.c2
-rw-r--r--src/nm-ip6-config.c2
-rw-r--r--src/nm-manager-auth.c156
-rw-r--r--src/nm-manager-auth.h44
-rw-r--r--src/nm-manager.c2201
-rw-r--r--src/nm-manager.h35
-rw-r--r--src/nm-policy.c338
-rw-r--r--src/nm-policy.h16
-rw-r--r--src/nm-secrets-provider-interface.c224
-rw-r--r--src/nm-secrets-provider-interface.h90
-rw-r--r--src/nm-session-monitor.c602
-rw-r--r--src/nm-session-monitor.h64
-rw-r--r--src/nm-udev-manager.c42
-rw-r--r--src/nm-udev-manager.h1
-rw-r--r--src/nm-wifi-ap-utils.c731
-rw-r--r--src/nm-wifi-ap-utils.h45
-rw-r--r--src/nm-wifi-ap.c193
-rw-r--r--src/nm-wifi-ap.h11
-rw-r--r--src/ppp-manager/Makefile.in50
-rw-r--r--src/ppp-manager/nm-ppp-manager.c226
-rw-r--r--src/ppp-manager/nm-ppp-manager.h8
-rw-r--r--src/settings/Makefile.am89
-rw-r--r--src/settings/Makefile.in945
-rw-r--r--src/settings/nm-agent-manager.c1390
-rw-r--r--src/settings/nm-agent-manager.h88
-rw-r--r--src/settings/nm-default-wired-connection.c205
-rw-r--r--src/settings/nm-default-wired-connection.h (renamed from src/system-settings/nm-default-wired-connection.h)13
-rw-r--r--src/settings/nm-inotify-helper.c (renamed from src/system-settings/nm-inotify-helper.c)4
-rw-r--r--src/settings/nm-inotify-helper.h (renamed from src/system-settings/nm-inotify-helper.h)0
-rw-r--r--src/settings/nm-polkit-helpers.h (renamed from src/system-settings/nm-polkit-helpers.h)6
-rw-r--r--src/settings/nm-secret-agent.c398
-rw-r--r--src/settings/nm-secret-agent.h92
-rw-r--r--src/settings/nm-settings-connection.c1510
-rw-r--r--src/settings/nm-settings-connection.h129
-rw-r--r--src/settings/nm-settings-error.c83
-rw-r--r--src/settings/nm-settings-error.h53
-rw-r--r--src/settings/nm-settings-utils.c66
-rw-r--r--src/settings/nm-settings-utils.h26
-rw-r--r--src/settings/nm-settings.c1663
-rw-r--r--src/settings/nm-settings.h115
-rw-r--r--src/settings/nm-system-config-interface.c (renamed from src/system-settings/nm-system-config-interface.c)16
-rw-r--r--src/settings/nm-system-config-interface.h (renamed from src/system-settings/nm-system-config-interface.h)28
-rw-r--r--src/settings/plugins/Makefile.am21
-rw-r--r--src/settings/plugins/Makefile.in660
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.am76
-rw-r--r--src/settings/plugins/ifcfg-rh/Makefile.in978
-rw-r--r--src/settings/plugins/ifcfg-rh/common.h57
-rw-r--r--src/settings/plugins/ifcfg-rh/errors.c35
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c346
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h63
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf18
-rw-r--r--src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml31
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.c800
-rw-r--r--src/settings/plugins/ifcfg-rh/plugin.h50
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c3466
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.h (renamed from src/system-settings/nm-system-config-error.h)35
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.c396
-rw-r--r--src/settings/plugins/ifcfg-rh/shvar.h110
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.am53
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/Makefile.in826
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns121
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns221
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry35
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway21
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr21
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record18
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp33
-rwxr-xr-xsrc/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static35
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am90
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in543
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main7
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled9
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no5
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions8
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy12
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface7
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap17
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap17
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent17
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask17
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys18
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap20
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys18
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls25
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls28
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk19
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc16
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex19
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted19
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted219
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv215
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only11
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual19
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only14
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default11
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static13
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static20
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-1614
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-2414
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-814
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy15
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted22
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv22
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes2
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default4
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy3
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes8
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy7
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual1
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem118
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem27
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c164
-rw-r--r--src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c10849
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c362
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.h51
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c1746
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.h39
-rw-r--r--src/settings/plugins/ifcfg-suse/Makefile.am26
-rw-r--r--src/settings/plugins/ifcfg-suse/Makefile.in672
-rw-r--r--src/settings/plugins/ifcfg-suse/plugin.c322
-rw-r--r--src/settings/plugins/ifcfg-suse/plugin.h52
-rw-r--r--src/settings/plugins/ifnet/Makefile.am57
-rw-r--r--src/settings/plugins/ifnet/Makefile.in922
-rw-r--r--src/settings/plugins/ifnet/connection_parser.c3069
-rw-r--r--src/settings/plugins/ifnet/connection_parser.h46
-rw-r--r--src/settings/plugins/ifnet/net_parser.c639
-rw-r--r--src/settings/plugins/ifnet/net_parser.h46
-rw-r--r--src/settings/plugins/ifnet/net_utils.c974
-rw-r--r--src/settings/plugins/ifnet/net_utils.h80
-rw-r--r--src/settings/plugins/ifnet/nm-ifnet-connection.c191
-rw-r--r--src/settings/plugins/ifnet/nm-ifnet-connection.h51
-rw-r--r--src/settings/plugins/ifnet/plugin.c541
-rw-r--r--src/settings/plugins/ifnet/plugin.h47
-rw-r--r--src/settings/plugins/ifnet/tests/Makefile.am18
-rw-r--r--src/settings/plugins/ifnet/tests/Makefile.in716
-rw-r--r--src/settings/plugins/ifnet/tests/hostname2
-rw-r--r--src/settings/plugins/ifnet/tests/net147
-rw-r--r--src/settings/plugins/ifnet/tests/net.all864
-rw-r--r--src/settings/plugins/ifnet/tests/nm-system-settings.conf5
-rw-r--r--src/settings/plugins/ifnet/tests/test_all.c399
-rw-r--r--src/settings/plugins/ifnet/tests/wpa_supplicant.conf864
-rw-r--r--src/settings/plugins/ifnet/wpa_parser.c566
-rw-r--r--src/settings/plugins/ifnet/wpa_parser.h40
-rw-r--r--src/settings/plugins/ifupdown/Makefile.am53
-rw-r--r--src/settings/plugins/ifupdown/Makefile.in898
-rw-r--r--src/settings/plugins/ifupdown/interface_parser.c307
-rw-r--r--src/settings/plugins/ifupdown/interface_parser.h55
-rw-r--r--src/settings/plugins/ifupdown/nm-ifupdown-connection.c168
-rw-r--r--src/settings/plugins/ifupdown/nm-ifupdown-connection.h55
-rw-r--r--src/settings/plugins/ifupdown/parser.c577
-rw-r--r--src/settings/plugins/ifupdown/parser.h34
-rw-r--r--src/settings/plugins/ifupdown/plugin.c727
-rw-r--r--src/settings/plugins/ifupdown/plugin.h53
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.am32
-rw-r--r--src/settings/plugins/ifupdown/tests/Makefile.in632
-rw-r--r--src/settings/plugins/ifupdown/tests/test-ifupdown.c496
-rw-r--r--src/settings/plugins/ifupdown/tests/test16
-rw-r--r--src/settings/plugins/ifupdown/tests/test115
-rw-r--r--src/settings/plugins/ifupdown/tests/test125
-rw-r--r--src/settings/plugins/ifupdown/tests/test133
-rw-r--r--src/settings/plugins/ifupdown/tests/test145
-rw-r--r--src/settings/plugins/ifupdown/tests/test153
-rw-r--r--src/settings/plugins/ifupdown/tests/test162
-rw-r--r--src/settings/plugins/ifupdown/tests/test24
-rw-r--r--src/settings/plugins/ifupdown/tests/test35
-rw-r--r--src/settings/plugins/ifupdown/tests/test43
-rw-r--r--src/settings/plugins/ifupdown/tests/test53
-rw-r--r--src/settings/plugins/ifupdown/tests/test63
-rw-r--r--src/settings/plugins/ifupdown/tests/test73
-rw-r--r--src/settings/plugins/ifupdown/tests/test85
-rw-r--r--src/settings/plugins/ifupdown/tests/test910
-rw-r--r--src/settings/plugins/keyfile/Makefile.am61
-rw-r--r--src/settings/plugins/keyfile/Makefile.in865
-rw-r--r--src/settings/plugins/keyfile/common.h40
-rw-r--r--src/settings/plugins/keyfile/errors.c35
-rw-r--r--src/settings/plugins/keyfile/nm-keyfile-connection.c173
-rw-r--r--src/settings/plugins/keyfile/nm-keyfile-connection.h54
-rw-r--r--src/settings/plugins/keyfile/plugin.c654
-rw-r--r--src/settings/plugins/keyfile/plugin.h48
-rw-r--r--src/settings/plugins/keyfile/reader.c1266
-rw-r--r--src/settings/plugins/keyfile/reader.h30
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.am32
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.in782
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT23
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain20
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.am23
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.in475
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection41
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID11
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection32
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP620
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case32
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New22
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old22
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection22
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem27
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem118
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile.c2353
-rw-r--r--src/settings/plugins/keyfile/utils.c98
-rw-r--r--src/settings/plugins/keyfile/utils.h30
-rw-r--r--src/settings/plugins/keyfile/writer.c1044
-rw-r--r--src/settings/plugins/keyfile/writer.h41
-rw-r--r--src/settings/tests/Makefile.am32
-rw-r--r--src/settings/tests/Makefile.in632
-rw-r--r--src/settings/tests/test-wired-defname.c147
-rw-r--r--src/supplicant-manager/Makefile.in50
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c1588
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.h78
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.c427
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.h44
-rw-r--r--src/supplicant-manager/tests/Makefile.in50
-rw-r--r--src/system-settings/Makefile.am61
-rw-r--r--src/system-settings/nm-default-wired-connection.c309
-rw-r--r--src/system-settings/nm-sysconfig-connection.c662
-rw-r--r--src/system-settings/nm-sysconfig-connection.h56
-rw-r--r--src/system-settings/nm-sysconfig-settings.c1596
-rw-r--r--src/system-settings/nm-sysconfig-settings.h73
-rw-r--r--src/system-settings/nm-system-config-error.c59
-rw-r--r--src/tests/Makefile.am29
-rw-r--r--src/tests/Makefile.in107
-rw-r--r--src/tests/test-policy-hosts.c2
-rwxr-xr-xsrc/tests/test-secret-agent.py74
-rw-r--r--src/tests/test-wifi-ap-utils.c1432
-rw-r--r--src/vpn-manager/Makefile.in50
-rw-r--r--src/vpn-manager/nm-vpn-connection-base.c5
-rw-r--r--src/vpn-manager/nm-vpn-connection.c256
-rw-r--r--src/vpn-manager/nm-vpn-connection.h7
-rw-r--r--src/vpn-manager/nm-vpn-manager.c51
-rw-r--r--src/vpn-manager/nm-vpn-manager.h2
-rw-r--r--src/vpn-manager/nm-vpn-service.c7
-rw-r--r--src/vpn-manager/nm-vpn-service.h2
-rw-r--r--src/wimax/Makefile.am40
-rw-r--r--src/wimax/Makefile.in (renamed from src/system-settings/Makefile.in)243
-rw-r--r--src/wimax/iwmxsdk.c1479
-rw-r--r--src/wimax/iwmxsdk.h109
-rw-r--r--src/wimax/nm-device-wimax.c1566
-rw-r--r--src/wimax/nm-device-wimax.h82
-rw-r--r--src/wimax/nm-wimax-nsp.c246
-rw-r--r--src/wimax/nm-wimax-nsp.h63
-rw-r--r--src/wimax/nm-wimax-types.h31
-rw-r--r--src/wimax/nm-wimax-util.c82
-rw-r--r--src/wimax/nm-wimax-util.h38
333 files changed, 66484 insertions, 9421 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d7dccaaf1..94e1a8c0c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,32 +10,42 @@ SUBDIRS= \
dnsmasq-manager \
modem-manager \
bluez-manager \
- system-settings \
- . \
- tests
+ settings
-INCLUDES = -I${top_srcdir} \
- -I${top_srcdir}/include \
- -I${top_builddir}/marshallers \
+if WITH_WIMAX
+SUBDIRS += wimax
+endif
+
+SUBDIRS += . tests
+
+INCLUDES = -I${top_srcdir} \
+ -I${top_srcdir}/include \
+ -I${top_builddir}/marshallers \
-I${top_srcdir}/src/logging \
-I${top_srcdir}/src/dns-manager \
- -I${top_srcdir}/src/vpn-manager \
- -I${top_srcdir}/src/dhcp-manager \
- -I${top_srcdir}/src/ip6-manager \
- -I${top_srcdir}/src/supplicant-manager \
- -I${top_srcdir}/src/dnsmasq-manager \
- -I${top_srcdir}/src/modem-manager \
+ -I${top_srcdir}/src/vpn-manager \
+ -I${top_srcdir}/src/dhcp-manager \
+ -I${top_srcdir}/src/ip6-manager \
+ -I${top_srcdir}/src/supplicant-manager \
+ -I${top_srcdir}/src/dnsmasq-manager \
+ -I${top_srcdir}/src/modem-manager \
-I$(top_srcdir)/src/bluez-manager \
- -I$(top_srcdir)/src/system-settings \
+ -I$(top_srcdir)/src/settings \
-I${top_srcdir}/libnm-util \
- -I${top_srcdir}/libnm-glib \
-I${top_srcdir}/callouts
+if WITH_WIMAX
+INCLUDES += -I$(top_srcdir)/src/wimax
+endif
+
###########################################
# Test libraries
###########################################
-noinst_LTLIBRARIES = libtest-dhcp.la libtest-policy-hosts.la
+noinst_LTLIBRARIES = \
+ libtest-dhcp.la \
+ libtest-policy-hosts.la \
+ libtest-wifi-ap-utils.la
###########################################
# DHCP test library
@@ -77,6 +87,22 @@ libtest_policy_hosts_la_LIBADD = \
###########################################
+# Wifi ap utils
+###########################################
+
+libtest_wifi_ap_utils_la_SOURCES = \
+ nm-wifi-ap-utils.c \
+ nm-wifi-ap-utils.h
+
+libtest_wifi_ap_utils_la_CPPFLAGS = \
+ $(GLIB_CFLAGS)
+
+libtest_wifi_ap_utils_la_LIBADD = \
+ ${top_builddir}/libnm-util/libnm-util.la \
+ $(GLIB_LIBS)
+
+
+###########################################
# NetworkManager
###########################################
@@ -100,12 +126,10 @@ NetworkManager_SOURCES = \
nm-device-bt.h \
nm-device-modem.h \
nm-device-modem.c \
- nm-device-cdma.c \
- nm-device-cdma.h \
- nm-device-gsm.c \
- nm-device-gsm.h \
nm-wifi-ap.c \
nm-wifi-ap.h \
+ nm-wifi-ap-utils.c \
+ nm-wifi-ap-utils.h \
nm-dbus-manager.h \
nm-dbus-manager.c \
nm-udev-manager.c \
@@ -116,8 +140,6 @@ NetworkManager_SOURCES = \
nm-ip4-config.h \
nm-ip6-config.c \
nm-ip6-config.h \
- nm-secrets-provider-interface.c \
- nm-secrets-provider-interface.h \
nm-active-connection.h \
nm-active-connection.c \
main.c \
@@ -147,7 +169,9 @@ NetworkManager_SOURCES = \
nm-dhcp4-config.h \
nm-dhcp6-config.c \
nm-dhcp6-config.h \
- nm-rfkill.h
+ nm-rfkill.h \
+ nm-session-monitor.c \
+ nm-session-monitor.h
nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml
$(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $<
@@ -185,11 +209,8 @@ nm-dhcp4-config-glue.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
nm-dhcp6-config-glue.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml
$(AM_V_GEN) dbus-binding-tool --prefix=nm_dhcp6_config --mode=glib-server --output=$@ $<
-nm-device-cdma-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_cdma --mode=glib-server --output=$@ $<
-
-nm-device-gsm-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_gsm --mode=glib-server --output=$@ $<
+nm-device-modem-glue.h: $(top_srcdir)/introspection/nm-device-modem.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_modem --mode=glib-server --output=$@ $<
BUILT_SOURCES = \
nm-access-point-glue.h \
@@ -199,8 +220,7 @@ BUILT_SOURCES = \
nm-device-wifi-glue.h \
nm-device-olpc-mesh-glue.h \
nm-device-bt-glue.h \
- nm-device-cdma-glue.h \
- nm-device-gsm-glue.h \
+ nm-device-modem-glue.h \
nm-ip4-config-glue.h \
nm-ip6-config-glue.h \
nm-active-connection-glue.h \
@@ -225,6 +245,12 @@ NetworkManager_CPPFLAGS = \
-DNMLOCALEDIR=\"$(datadir)/locale\" \
-DARP_DEBUG
+
+WIMAX_LIBS=
+if WITH_WIMAX
+WIMAX_LIBS += ./wimax/libwimax.la
+endif
+
NetworkManager_LDADD = \
$(top_builddir)/marshallers/libmarshallers.la \
./logging/libnm-logging.la \
@@ -237,7 +263,8 @@ NetworkManager_LDADD = \
./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \
- ./system-settings/libsystem-settings.la \
+ ./settings/libsettings.la \
+ $(WIMAX_LIBS) \
./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(DBUS_LIBS) \
diff --git a/src/Makefile.in b/src/Makefile.in
index 3b8cc9611..8e0bb40bd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -36,17 +36,25 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@WITH_WIMAX_TRUE@am__append_1 = wimax
+@WITH_WIMAX_TRUE@am__append_2 = -I$(top_srcdir)/src/wimax
sbin_PROGRAMS = NetworkManager$(EXEEXT)
+@WITH_WIMAX_TRUE@am__append_3 = ./wimax/libwimax.la
libexec_PROGRAMS = nm-crash-logger$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -74,6 +82,12 @@ am_libtest_policy_hosts_la_OBJECTS = \
libtest_policy_hosts_la-nm-policy-hosts.lo
libtest_policy_hosts_la_OBJECTS = \
$(am_libtest_policy_hosts_la_OBJECTS)
+libtest_wifi_ap_utils_la_DEPENDENCIES = \
+ ${top_builddir}/libnm-util/libnm-util.la $(am__DEPENDENCIES_1)
+am_libtest_wifi_ap_utils_la_OBJECTS = \
+ libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo
+libtest_wifi_ap_utils_la_OBJECTS = \
+ $(am_libtest_wifi_ap_utils_la_OBJECTS)
am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" \
"$(DESTDIR)$(NetworkManagerdir)" "$(DESTDIR)$(dbusservicedir)"
PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
@@ -85,15 +99,13 @@ am_NetworkManager_OBJECTS = NetworkManager-nm-call-store.$(OBJEXT) \
NetworkManager-nm-device-olpc-mesh.$(OBJEXT) \
NetworkManager-nm-device-bt.$(OBJEXT) \
NetworkManager-nm-device-modem.$(OBJEXT) \
- NetworkManager-nm-device-cdma.$(OBJEXT) \
- NetworkManager-nm-device-gsm.$(OBJEXT) \
NetworkManager-nm-wifi-ap.$(OBJEXT) \
+ NetworkManager-nm-wifi-ap-utils.$(OBJEXT) \
NetworkManager-nm-dbus-manager.$(OBJEXT) \
NetworkManager-nm-udev-manager.$(OBJEXT) \
NetworkManager-nm-hostname-provider.$(OBJEXT) \
NetworkManager-nm-ip4-config.$(OBJEXT) \
NetworkManager-nm-ip6-config.$(OBJEXT) \
- NetworkManager-nm-secrets-provider-interface.$(OBJEXT) \
NetworkManager-nm-active-connection.$(OBJEXT) \
NetworkManager-main.$(OBJEXT) \
NetworkManager-nm-policy.$(OBJEXT) \
@@ -108,7 +120,8 @@ am_NetworkManager_OBJECTS = NetworkManager-nm-call-store.$(OBJEXT) \
NetworkManager-nm-properties-changed-signal.$(OBJEXT) \
NetworkManager-wpa.$(OBJEXT) \
NetworkManager-nm-dhcp4-config.$(OBJEXT) \
- NetworkManager-nm-dhcp6-config.$(OBJEXT)
+ NetworkManager-nm-dhcp6-config.$(OBJEXT) \
+ NetworkManager-nm-session-monitor.$(OBJEXT)
NetworkManager_OBJECTS = $(am_NetworkManager_OBJECTS)
NetworkManager_DEPENDENCIES = \
$(top_builddir)/marshallers/libmarshallers.la \
@@ -120,9 +133,8 @@ NetworkManager_DEPENDENCIES = \
./dnsmasq-manager/libdnsmasq-manager.la \
./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \
- ./bluez-manager/libbluez-manager.la \
- ./system-settings/libsystem-settings.la \
- ./backends/libnmbackend.la \
+ ./bluez-manager/libbluez-manager.la ./settings/libsettings.la \
+ $(WIMAX_LIBS) ./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
@@ -137,7 +149,7 @@ am_nm_crash_logger_OBJECTS = \
nm_crash_logger_OBJECTS = $(am_nm_crash_logger_OBJECTS)
nm_crash_logger_DEPENDENCIES = $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -163,10 +175,12 @@ AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libtest_dhcp_la_SOURCES) \
- $(libtest_policy_hosts_la_SOURCES) $(NetworkManager_SOURCES) \
+ $(libtest_policy_hosts_la_SOURCES) \
+ $(libtest_wifi_ap_utils_la_SOURCES) $(NetworkManager_SOURCES) \
$(nm_crash_logger_SOURCES)
DIST_SOURCES = $(libtest_dhcp_la_SOURCES) \
- $(libtest_policy_hosts_la_SOURCES) $(NetworkManager_SOURCES) \
+ $(libtest_policy_hosts_la_SOURCES) \
+ $(libtest_wifi_ap_utils_la_SOURCES) $(NetworkManager_SOURCES) \
$(nm_crash_logger_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
@@ -204,7 +218,10 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
distdir
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = logging dns-manager vpn-manager dhcp-manager \
+ ip6-manager supplicant-manager ppp-manager backends \
+ dnsmasq-manager modem-manager bluez-manager settings wimax . \
+ tests
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -232,7 +249,6 @@ am__relativize = \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -241,8 +257,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -259,6 +273,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -267,6 +282,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -275,8 +291,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -291,13 +307,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -305,6 +331,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -313,13 +341,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -345,12 +375,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -365,10 +392,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -417,44 +447,30 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-SUBDIRS = \
- logging \
- dns-manager \
- vpn-manager \
- dhcp-manager \
- ip6-manager \
- supplicant-manager \
- ppp-manager \
- backends \
- dnsmasq-manager \
- modem-manager \
- bluez-manager \
- system-settings \
- . \
- tests
-
-INCLUDES = -I${top_srcdir} \
- -I${top_srcdir}/include \
- -I${top_builddir}/marshallers \
- -I${top_srcdir}/src/logging \
- -I${top_srcdir}/src/dns-manager \
- -I${top_srcdir}/src/vpn-manager \
- -I${top_srcdir}/src/dhcp-manager \
- -I${top_srcdir}/src/ip6-manager \
- -I${top_srcdir}/src/supplicant-manager \
- -I${top_srcdir}/src/dnsmasq-manager \
- -I${top_srcdir}/src/modem-manager \
- -I$(top_srcdir)/src/bluez-manager \
- -I$(top_srcdir)/src/system-settings \
- -I${top_srcdir}/libnm-util \
- -I${top_srcdir}/libnm-glib \
- -I${top_srcdir}/callouts
-
+SUBDIRS = logging dns-manager vpn-manager dhcp-manager ip6-manager \
+ supplicant-manager ppp-manager backends dnsmasq-manager \
+ modem-manager bluez-manager settings $(am__append_1) . tests
+INCLUDES = -I${top_srcdir} -I${top_srcdir}/include \
+ -I${top_builddir}/marshallers -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/src/dns-manager \
+ -I${top_srcdir}/src/vpn-manager \
+ -I${top_srcdir}/src/dhcp-manager \
+ -I${top_srcdir}/src/ip6-manager \
+ -I${top_srcdir}/src/supplicant-manager \
+ -I${top_srcdir}/src/dnsmasq-manager \
+ -I${top_srcdir}/src/modem-manager \
+ -I$(top_srcdir)/src/bluez-manager -I$(top_srcdir)/src/settings \
+ -I${top_srcdir}/libnm-util -I${top_srcdir}/callouts \
+ $(am__append_2)
###########################################
# Test libraries
###########################################
-noinst_LTLIBRARIES = libtest-dhcp.la libtest-policy-hosts.la
+noinst_LTLIBRARIES = \
+ libtest-dhcp.la \
+ libtest-policy-hosts.la \
+ libtest-wifi-ap-utils.la
+
###########################################
# DHCP test library
@@ -493,6 +509,21 @@ libtest_policy_hosts_la_LIBADD = \
${top_builddir}/src/logging/libnm-logging.la \
$(GLIB_LIBS)
+
+###########################################
+# Wifi ap utils
+###########################################
+libtest_wifi_ap_utils_la_SOURCES = \
+ nm-wifi-ap-utils.c \
+ nm-wifi-ap-utils.h
+
+libtest_wifi_ap_utils_la_CPPFLAGS = \
+ $(GLIB_CFLAGS)
+
+libtest_wifi_ap_utils_la_LIBADD = \
+ ${top_builddir}/libnm-util/libnm-util.la \
+ $(GLIB_LIBS)
+
NetworkManager_SOURCES = \
nm-call-store.c \
nm-call-store.h \
@@ -511,12 +542,10 @@ NetworkManager_SOURCES = \
nm-device-bt.h \
nm-device-modem.h \
nm-device-modem.c \
- nm-device-cdma.c \
- nm-device-cdma.h \
- nm-device-gsm.c \
- nm-device-gsm.h \
nm-wifi-ap.c \
nm-wifi-ap.h \
+ nm-wifi-ap-utils.c \
+ nm-wifi-ap-utils.h \
nm-dbus-manager.h \
nm-dbus-manager.c \
nm-udev-manager.c \
@@ -527,8 +556,6 @@ NetworkManager_SOURCES = \
nm-ip4-config.h \
nm-ip6-config.c \
nm-ip6-config.h \
- nm-secrets-provider-interface.c \
- nm-secrets-provider-interface.h \
nm-active-connection.h \
nm-active-connection.c \
main.c \
@@ -558,7 +585,9 @@ NetworkManager_SOURCES = \
nm-dhcp4-config.h \
nm-dhcp6-config.c \
nm-dhcp6-config.h \
- nm-rfkill.h
+ nm-rfkill.h \
+ nm-session-monitor.c \
+ nm-session-monitor.h
BUILT_SOURCES = \
nm-access-point-glue.h \
@@ -568,8 +597,7 @@ BUILT_SOURCES = \
nm-device-wifi-glue.h \
nm-device-olpc-mesh-glue.h \
nm-device-bt-glue.h \
- nm-device-cdma-glue.h \
- nm-device-gsm-glue.h \
+ nm-device-modem-glue.h \
nm-ip4-config-glue.h \
nm-ip6-config-glue.h \
nm-active-connection-glue.h \
@@ -594,6 +622,7 @@ NetworkManager_CPPFLAGS = \
-DNMLOCALEDIR=\"$(datadir)/locale\" \
-DARP_DEBUG
+WIMAX_LIBS = $(am__append_3)
NetworkManager_LDADD = \
$(top_builddir)/marshallers/libmarshallers.la \
./logging/libnm-logging.la \
@@ -606,7 +635,8 @@ NetworkManager_LDADD = \
./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \
- ./system-settings/libsystem-settings.la \
+ ./settings/libsettings.la \
+ $(WIMAX_LIBS) \
./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(DBUS_LIBS) \
@@ -689,6 +719,8 @@ libtest-dhcp.la: $(libtest_dhcp_la_OBJECTS) $(libtest_dhcp_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libtest_dhcp_la_OBJECTS) $(libtest_dhcp_la_LIBADD) $(LIBS)
libtest-policy-hosts.la: $(libtest_policy_hosts_la_OBJECTS) $(libtest_policy_hosts_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) $(libtest_policy_hosts_la_OBJECTS) $(libtest_policy_hosts_la_LIBADD) $(LIBS)
+libtest-wifi-ap-utils.la: $(libtest_wifi_ap_utils_la_OBJECTS) $(libtest_wifi_ap_utils_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libtest_wifi_ap_utils_la_OBJECTS) $(libtest_wifi_ap_utils_la_LIBADD) $(LIBS)
install-libexecPROGRAMS: $(libexec_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
@@ -795,9 +827,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-call-store.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-dbus-manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-bt.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-cdma.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-ethernet.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-gsm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-interface.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-modem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-device-olpc-mesh.Po@am__quote@
@@ -815,9 +845,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy-hosts.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-policy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-properties-changed-signal.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-session-monitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-system.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-udev-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-nm-wifi-ap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkManager-wpa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-dbus-manager.Plo@am__quote@
@@ -825,6 +856,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-ip4-config.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_dhcp_la-nm-ip6-config.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_policy_hosts_la-nm-policy-hosts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_wifi_ap_utils_la-nm-wifi-ap-utils.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm_crash_logger-nm-crash-logger.Po@am__quote@
.c.o:
@@ -894,6 +926,14 @@ libtest_policy_hosts_la-nm-policy-hosts.lo: nm-policy-hosts.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_policy_hosts_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtest_policy_hosts_la-nm-policy-hosts.lo `test -f 'nm-policy-hosts.c' || echo '$(srcdir)/'`nm-policy-hosts.c
+libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo: nm-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_wifi_ap_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo -MD -MP -MF $(DEPDIR)/libtest_wifi_ap_utils_la-nm-wifi-ap-utils.Tpo -c -o libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo `test -f 'nm-wifi-ap-utils.c' || echo '$(srcdir)/'`nm-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtest_wifi_ap_utils_la-nm-wifi-ap-utils.Tpo $(DEPDIR)/libtest_wifi_ap_utils_la-nm-wifi-ap-utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wifi-ap-utils.c' object='libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_wifi_ap_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtest_wifi_ap_utils_la-nm-wifi-ap-utils.lo `test -f 'nm-wifi-ap-utils.c' || echo '$(srcdir)/'`nm-wifi-ap-utils.c
+
NetworkManager-nm-call-store.o: nm-call-store.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-call-store.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-call-store.Tpo -c -o NetworkManager-nm-call-store.o `test -f 'nm-call-store.c' || echo '$(srcdir)/'`nm-call-store.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-call-store.Tpo $(DEPDIR)/NetworkManager-nm-call-store.Po
@@ -1022,38 +1062,6 @@ NetworkManager-nm-device-modem.obj: nm-device-modem.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-modem.obj `if test -f 'nm-device-modem.c'; then $(CYGPATH_W) 'nm-device-modem.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-modem.c'; fi`
-NetworkManager-nm-device-cdma.o: nm-device-cdma.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-cdma.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-cdma.Tpo -c -o NetworkManager-nm-device-cdma.o `test -f 'nm-device-cdma.c' || echo '$(srcdir)/'`nm-device-cdma.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-cdma.Tpo $(DEPDIR)/NetworkManager-nm-device-cdma.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-cdma.c' object='NetworkManager-nm-device-cdma.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-cdma.o `test -f 'nm-device-cdma.c' || echo '$(srcdir)/'`nm-device-cdma.c
-
-NetworkManager-nm-device-cdma.obj: nm-device-cdma.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-cdma.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-cdma.Tpo -c -o NetworkManager-nm-device-cdma.obj `if test -f 'nm-device-cdma.c'; then $(CYGPATH_W) 'nm-device-cdma.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-cdma.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-cdma.Tpo $(DEPDIR)/NetworkManager-nm-device-cdma.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-cdma.c' object='NetworkManager-nm-device-cdma.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-cdma.obj `if test -f 'nm-device-cdma.c'; then $(CYGPATH_W) 'nm-device-cdma.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-cdma.c'; fi`
-
-NetworkManager-nm-device-gsm.o: nm-device-gsm.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-gsm.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-gsm.Tpo -c -o NetworkManager-nm-device-gsm.o `test -f 'nm-device-gsm.c' || echo '$(srcdir)/'`nm-device-gsm.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-gsm.Tpo $(DEPDIR)/NetworkManager-nm-device-gsm.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-gsm.c' object='NetworkManager-nm-device-gsm.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-gsm.o `test -f 'nm-device-gsm.c' || echo '$(srcdir)/'`nm-device-gsm.c
-
-NetworkManager-nm-device-gsm.obj: nm-device-gsm.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-device-gsm.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-device-gsm.Tpo -c -o NetworkManager-nm-device-gsm.obj `if test -f 'nm-device-gsm.c'; then $(CYGPATH_W) 'nm-device-gsm.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-gsm.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-device-gsm.Tpo $(DEPDIR)/NetworkManager-nm-device-gsm.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-gsm.c' object='NetworkManager-nm-device-gsm.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-device-gsm.obj `if test -f 'nm-device-gsm.c'; then $(CYGPATH_W) 'nm-device-gsm.c'; else $(CYGPATH_W) '$(srcdir)/nm-device-gsm.c'; fi`
-
NetworkManager-nm-wifi-ap.o: nm-wifi-ap.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-wifi-ap.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-wifi-ap.Tpo -c -o NetworkManager-nm-wifi-ap.o `test -f 'nm-wifi-ap.c' || echo '$(srcdir)/'`nm-wifi-ap.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-wifi-ap.Tpo $(DEPDIR)/NetworkManager-nm-wifi-ap.Po
@@ -1070,6 +1078,22 @@ NetworkManager-nm-wifi-ap.obj: nm-wifi-ap.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-wifi-ap.obj `if test -f 'nm-wifi-ap.c'; then $(CYGPATH_W) 'nm-wifi-ap.c'; else $(CYGPATH_W) '$(srcdir)/nm-wifi-ap.c'; fi`
+NetworkManager-nm-wifi-ap-utils.o: nm-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-wifi-ap-utils.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Tpo -c -o NetworkManager-nm-wifi-ap-utils.o `test -f 'nm-wifi-ap-utils.c' || echo '$(srcdir)/'`nm-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Tpo $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wifi-ap-utils.c' object='NetworkManager-nm-wifi-ap-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-wifi-ap-utils.o `test -f 'nm-wifi-ap-utils.c' || echo '$(srcdir)/'`nm-wifi-ap-utils.c
+
+NetworkManager-nm-wifi-ap-utils.obj: nm-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-wifi-ap-utils.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Tpo -c -o NetworkManager-nm-wifi-ap-utils.obj `if test -f 'nm-wifi-ap-utils.c'; then $(CYGPATH_W) 'nm-wifi-ap-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-wifi-ap-utils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Tpo $(DEPDIR)/NetworkManager-nm-wifi-ap-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wifi-ap-utils.c' object='NetworkManager-nm-wifi-ap-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-wifi-ap-utils.obj `if test -f 'nm-wifi-ap-utils.c'; then $(CYGPATH_W) 'nm-wifi-ap-utils.c'; else $(CYGPATH_W) '$(srcdir)/nm-wifi-ap-utils.c'; fi`
+
NetworkManager-nm-dbus-manager.o: nm-dbus-manager.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-dbus-manager.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-dbus-manager.Tpo -c -o NetworkManager-nm-dbus-manager.o `test -f 'nm-dbus-manager.c' || echo '$(srcdir)/'`nm-dbus-manager.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-dbus-manager.Tpo $(DEPDIR)/NetworkManager-nm-dbus-manager.Po
@@ -1150,22 +1174,6 @@ NetworkManager-nm-ip6-config.obj: nm-ip6-config.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-ip6-config.obj `if test -f 'nm-ip6-config.c'; then $(CYGPATH_W) 'nm-ip6-config.c'; else $(CYGPATH_W) '$(srcdir)/nm-ip6-config.c'; fi`
-NetworkManager-nm-secrets-provider-interface.o: nm-secrets-provider-interface.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-secrets-provider-interface.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Tpo -c -o NetworkManager-nm-secrets-provider-interface.o `test -f 'nm-secrets-provider-interface.c' || echo '$(srcdir)/'`nm-secrets-provider-interface.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Tpo $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-secrets-provider-interface.c' object='NetworkManager-nm-secrets-provider-interface.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-secrets-provider-interface.o `test -f 'nm-secrets-provider-interface.c' || echo '$(srcdir)/'`nm-secrets-provider-interface.c
-
-NetworkManager-nm-secrets-provider-interface.obj: nm-secrets-provider-interface.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-secrets-provider-interface.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Tpo -c -o NetworkManager-nm-secrets-provider-interface.obj `if test -f 'nm-secrets-provider-interface.c'; then $(CYGPATH_W) 'nm-secrets-provider-interface.c'; else $(CYGPATH_W) '$(srcdir)/nm-secrets-provider-interface.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Tpo $(DEPDIR)/NetworkManager-nm-secrets-provider-interface.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-secrets-provider-interface.c' object='NetworkManager-nm-secrets-provider-interface.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-secrets-provider-interface.obj `if test -f 'nm-secrets-provider-interface.c'; then $(CYGPATH_W) 'nm-secrets-provider-interface.c'; else $(CYGPATH_W) '$(srcdir)/nm-secrets-provider-interface.c'; fi`
-
NetworkManager-nm-active-connection.o: nm-active-connection.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-active-connection.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-active-connection.Tpo -c -o NetworkManager-nm-active-connection.o `test -f 'nm-active-connection.c' || echo '$(srcdir)/'`nm-active-connection.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-active-connection.Tpo $(DEPDIR)/NetworkManager-nm-active-connection.Po
@@ -1406,6 +1414,22 @@ NetworkManager-nm-dhcp6-config.obj: nm-dhcp6-config.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-dhcp6-config.obj `if test -f 'nm-dhcp6-config.c'; then $(CYGPATH_W) 'nm-dhcp6-config.c'; else $(CYGPATH_W) '$(srcdir)/nm-dhcp6-config.c'; fi`
+NetworkManager-nm-session-monitor.o: nm-session-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor.o -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo -c -o NetworkManager-nm-session-monitor.o `test -f 'nm-session-monitor.c' || echo '$(srcdir)/'`nm-session-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor.c' object='NetworkManager-nm-session-monitor.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor.o `test -f 'nm-session-monitor.c' || echo '$(srcdir)/'`nm-session-monitor.c
+
+NetworkManager-nm-session-monitor.obj: nm-session-monitor.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT NetworkManager-nm-session-monitor.obj -MD -MP -MF $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo -c -o NetworkManager-nm-session-monitor.obj `if test -f 'nm-session-monitor.c'; then $(CYGPATH_W) 'nm-session-monitor.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/NetworkManager-nm-session-monitor.Tpo $(DEPDIR)/NetworkManager-nm-session-monitor.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-session-monitor.c' object='NetworkManager-nm-session-monitor.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(NetworkManager_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o NetworkManager-nm-session-monitor.obj `if test -f 'nm-session-monitor.c'; then $(CYGPATH_W) 'nm-session-monitor.c'; else $(CYGPATH_W) '$(srcdir)/nm-session-monitor.c'; fi`
+
nm_crash_logger-nm-crash-logger.o: nm-crash-logger.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(nm_crash_logger_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nm_crash_logger-nm-crash-logger.o -MD -MP -MF $(DEPDIR)/nm_crash_logger-nm-crash-logger.Tpo -c -o nm_crash_logger-nm-crash-logger.o `test -f 'nm-crash-logger.c' || echo '$(srcdir)/'`nm-crash-logger.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/nm_crash_logger-nm-crash-logger.Tpo $(DEPDIR)/nm_crash_logger-nm-crash-logger.Po
@@ -1832,11 +1856,8 @@ nm-dhcp4-config-glue.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
nm-dhcp6-config-glue.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml
$(AM_V_GEN) dbus-binding-tool --prefix=nm_dhcp6_config --mode=glib-server --output=$@ $<
-nm-device-cdma-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_cdma --mode=glib-server --output=$@ $<
-
-nm-device-gsm-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_gsm --mode=glib-server --output=$@ $<
+nm-device-modem-glue.h: $(top_srcdir)/introspection/nm-device-modem.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_modem --mode=glib-server --output=$@ $<
install-data-hook:
$(mkinstalldirs) -m 0700 $(DESTDIR)$(rundir)
$(mkinstalldirs) -m 0700 $(DESTDIR)$(statedir)
diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf
index 1f1ed49b4..b256a444e 100644
--- a/src/NetworkManager.conf
+++ b/src/NetworkManager.conf
@@ -4,13 +4,12 @@
<busconfig>
<policy user="root">
<allow own="org.freedesktop.NetworkManager"/>
- <allow own="org.freedesktop.NetworkManagerSystemSettings"/>
-
<allow send_destination="org.freedesktop.NetworkManager"/>
- <allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
<allow send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager.PPP"/>
+
+ <allow send_interface="org.freedesktop.NetworkManager.SecretAgent"/>
</policy>
<policy at_console="true">
<allow send_destination="org.freedesktop.NetworkManager"/>
@@ -57,6 +56,9 @@
<allow send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager.VPN.Connection"/>
+ <allow send_destination="org.freedesktop.NetworkManager"
+ send_interface="org.freedesktop.NetworkManager.AgentManager"/>
+
<deny send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager"
send_member="SetLogging"/>
@@ -75,10 +77,14 @@
</policy>
<policy context="default">
<deny own="org.freedesktop.NetworkManager"/>
- <deny own="org.freedesktop.NetworkManagerSystemSettings"/>
<deny send_destination="org.freedesktop.NetworkManager"/>
- <allow send_destination="org.freedesktop.NetworkManagerSystemSettings"/>
+
+ <allow send_destination="org.freedesktop.NetworkManager"
+ send_interface="org.freedesktop.NetworkManager.Settings"/>
+
+ <allow send_destination="org.freedesktop.NetworkManager"
+ send_interface="org.freedesktop.NetworkManager.AgentManager"/>
<deny send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager"
@@ -95,10 +101,6 @@
<deny send_destination="org.freedesktop.NetworkManager"
send_interface="org.freedesktop.NetworkManager"
send_member="wake"/>
-
- <!-- The org.freedesktop.NetworkManagerSettings.Connection.Secrets
- interface is secured via PolicyKit.
- -->
</policy>
<limit name="max_replies_per_connection">512</limit>
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c
index 3a28467cc..3981a1db3 100644
--- a/src/NetworkManagerUtils.c
+++ b/src/NetworkManagerUtils.c
@@ -36,6 +36,9 @@
#include "nm-dbus-manager.h"
#include "nm-dispatcher-action.h"
#include "nm-dbus-glib-types.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-ip6-config.h"
#include <netlink/addr.h>
#include <netinet/in.h>
@@ -409,21 +412,10 @@ nm_utils_call_dispatcher (const char *action,
}
if (connection) {
- connection_hash = nm_connection_to_hash (connection);
+ connection_hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_NO_SECRETS);
connection_props = value_hash_create ();
- /* Service name */
- if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_USER) {
- value_hash_add_str (connection_props,
- NMD_CONNECTION_PROPS_SERVICE_NAME,
- NM_DBUS_SERVICE_USER_SETTINGS);
- } else if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
- value_hash_add_str (connection_props,
- NMD_CONNECTION_PROPS_SERVICE_NAME,
- NM_DBUS_SERVICE_SYSTEM_SETTINGS);
- }
-
/* path */
value_hash_add_object_path (connection_props,
NMD_CONNECTION_PROPS_PATH,
@@ -733,3 +725,117 @@ nm_utils_get_proc_sys_net_value (const char *path,
return success;
}
+static char *
+get_new_connection_name (const GSList *existing,
+ const char *format,
+ const char *preferred)
+{
+ GSList *names = NULL;
+ const GSList *iter;
+ char *cname = NULL;
+ int i = 0;
+ gboolean preferred_found = FALSE;
+
+ for (iter = existing; iter; iter = g_slist_next (iter)) {
+ NMConnection *candidate = NM_CONNECTION (iter->data);
+ const char *id;
+
+ id = nm_connection_get_id (candidate);
+ g_assert (id);
+ names = g_slist_append (names, (gpointer) id);
+
+ if (preferred && !preferred_found && (strcmp (preferred, id) == 0))
+ preferred_found = TRUE;
+ }
+
+ /* Return the preferred name if it was unique */
+ if (preferred && !preferred_found) {
+ g_slist_free (names);
+ return g_strdup (preferred);
+ }
+
+ /* Otherwise find the next available unique connection name using the given
+ * connection name template.
+ */
+ while (!cname && (i++ < 10000)) {
+ char *temp;
+ gboolean found = FALSE;
+
+ temp = g_strdup_printf (format, i);
+ for (iter = names; iter; iter = g_slist_next (iter)) {
+ if (!strcmp (iter->data, temp)) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ cname = temp;
+ else
+ g_free (temp);
+ }
+
+ g_slist_free (names);
+ return cname;
+}
+
+void
+nm_utils_complete_generic (NMConnection *connection,
+ const char *ctype,
+ const GSList *existing,
+ const char *format,
+ const char *preferred,
+ gboolean default_enable_ipv6)
+{
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ const char *method;
+ char *id, *uuid;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if (!s_con) {
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+ }
+ g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL);
+
+ if (!nm_setting_connection_get_uuid (s_con)) {
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL);
+ g_free (uuid);
+ }
+
+ /* Add a connection ID if absent */
+ if (!nm_setting_connection_get_id (s_con)) {
+ id = get_new_connection_name (existing, format, preferred);
+ g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL);
+ g_free (id);
+ }
+
+ /* Add an 'auto' IPv4 connection if present */
+ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+ if (!s_ip4) {
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+ }
+ method = nm_setting_ip4_config_get_method (s_ip4);
+ if (!method) {
+ g_object_set (G_OBJECT (s_ip4),
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+ }
+
+ /* Add an 'auto' IPv6 setting if allowed and not preset */
+ s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+ if (!s_ip6 && default_enable_ipv6) {
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+ }
+ if (s_ip6 && !nm_setting_ip6_config_get_method (s_ip6)) {
+ g_object_set (G_OBJECT (s_ip6),
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
+ NULL);
+ }
+}
+
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h
index 72c0e532b..6f48a7882 100644
--- a/src/NetworkManagerUtils.h
+++ b/src/NetworkManagerUtils.h
@@ -78,4 +78,11 @@ gboolean nm_utils_get_proc_sys_net_value (const char *path,
const char *iface,
guint32 *out_value);
+void nm_utils_complete_generic (NMConnection *connection,
+ const char *ctype,
+ const GSList *existing,
+ const char *format,
+ const char *preferred,
+ gboolean default_enable_ipv6);
+
#endif /* NETWORK_MANAGER_UTILS_H */
diff --git a/src/backends/Makefile.in b/src/backends/Makefile.in
index 2f6869a29..db2b3753a 100644
--- a/src/backends/Makefile.in
+++ b/src/backends/Makefile.in
@@ -51,11 +51,16 @@ subdir = src/backends
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -106,7 +111,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -137,7 +142,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -146,8 +150,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -164,6 +166,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -172,6 +175,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -180,8 +184,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -196,13 +200,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -210,6 +224,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -218,13 +234,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -250,12 +268,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -270,10 +285,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/bluez-manager/Makefile.in b/src/bluez-manager/Makefile.in
index fad2ec6e1..25aef190e 100644
--- a/src/bluez-manager/Makefile.in
+++ b/src/bluez-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/bluez-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -64,7 +69,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -95,7 +100,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -104,8 +108,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -122,6 +124,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -130,6 +133,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -138,8 +142,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -154,13 +158,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -168,6 +182,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -176,13 +192,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -208,12 +226,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -228,10 +243,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/bluez-manager/nm-bluez-device.c b/src/bluez-manager/nm-bluez-device.c
index 72acaa690..ecb6ce513 100644
--- a/src/bluez-manager/nm-bluez-device.c
+++ b/src/bluez-manager/nm-bluez-device.c
@@ -195,7 +195,7 @@ property_changed (DBusGProxy *proxy,
|| (priv->name && !str)
|| (priv->name && str && strcmp (priv->name, str))) {
g_free (priv->name);
- priv->name = str ? g_strdup (str) : NULL;
+ priv->name = g_strdup (str);
g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_NAME);
}
} else if (!strcmp (property, "RSSI")) {
diff --git a/src/bluez-manager/nm-bluez-manager.c b/src/bluez-manager/nm-bluez-manager.c
index 59849d3bd..5381151ea 100644
--- a/src/bluez-manager/nm-bluez-manager.c
+++ b/src/bluez-manager/nm-bluez-manager.c
@@ -317,12 +317,12 @@ nm_bluez_manager_init (NMBluezManager *self)
g_assert (priv->dbus_mgr);
g_signal_connect (priv->dbus_mgr,
- "name-owner-changed",
+ NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (name_owner_changed_cb),
self);
g_signal_connect (priv->dbus_mgr,
- "dbus-connection-changed",
+ NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED,
G_CALLBACK (dbus_connection_changed_cb),
self);
diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in
index cf331d6fd..98589db0f 100644
--- a/src/dhcp-manager/Makefile.in
+++ b/src/dhcp-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/dhcp-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -73,7 +78,7 @@ am_libdhcp_manager_la_OBJECTS = libdhcp_manager_la-nm-dhcp-client.lo \
libdhcp_manager_la-nm-dhcp-dhcpcd.lo
libdhcp_manager_la_OBJECTS = $(am_libdhcp_manager_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -143,7 +148,6 @@ am__relativize = \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -152,8 +156,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -170,6 +172,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -178,6 +181,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -186,8 +190,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -202,13 +206,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -216,6 +230,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -224,13 +240,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -256,12 +274,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -276,10 +291,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index 4c19b300a..3418bf3b2 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -136,10 +136,10 @@ watch_cleanup (NMDHCPClient *self)
}
}
-static void
-stop_process (GPid pid, const char *iface)
+void
+nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs)
{
- int i = 15; /* 3 seconds */
+ int i = (timeout_secs ? timeout_secs : 3) * 5; /* default 3 seconds */
g_return_if_fail (pid > 0);
@@ -183,7 +183,7 @@ stop_process (GPid pid, const char *iface)
}
static void
-real_stop (NMDHCPClient *self)
+real_stop (NMDHCPClient *self, gboolean release)
{
NMDHCPClientPrivate *priv;
@@ -196,7 +196,7 @@ real_stop (NMDHCPClient *self)
/* Clean up the watch handler since we're explicitly killing the daemon */
watch_cleanup (self);
- stop_process (priv->pid, priv->iface);
+ nm_dhcp_client_stop_pid (priv->pid, priv->iface, 0);
priv->info_only = FALSE;
}
@@ -376,7 +376,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name)
exe = proc_contents;
if (!strcmp (exe, binary_name))
- stop_process ((GPid) tmp, NULL);
+ nm_dhcp_client_stop_pid ((GPid) tmp, NULL, 0);
}
}
@@ -387,7 +387,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name)
}
void
-nm_dhcp_client_stop (NMDHCPClient *self)
+nm_dhcp_client_stop (NMDHCPClient *self, gboolean release)
{
NMDHCPClientPrivate *priv;
@@ -398,7 +398,7 @@ nm_dhcp_client_stop (NMDHCPClient *self)
/* Kill the DHCP client */
if (!priv->dead) {
- NM_DHCP_CLIENT_GET_CLASS (self)->stop (self);
+ NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release);
priv->dead = TRUE;
nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d",
diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h
index f357170b9..19c7365ed 100644
--- a/src/dhcp-manager/nm-dhcp-client.h
+++ b/src/dhcp-manager/nm-dhcp-client.h
@@ -76,18 +76,19 @@ typedef struct {
/* Methods */
- GPid (*ip4_start) (NMDHCPClient *self,
- NMSettingIP4Config *s_ip4,
- guint8 *anycast_addr,
- const char *hostname);
+ GPid (*ip4_start) (NMDHCPClient *self,
+ NMSettingIP4Config *s_ip4,
+ guint8 *anycast_addr,
+ const char *hostname);
- GPid (*ip6_start) (NMDHCPClient *self,
- NMSettingIP6Config *s_ip6,
- guint8 *anycast_addr,
- const char *hostname,
- gboolean info_only);
+ GPid (*ip6_start) (NMDHCPClient *self,
+ NMSettingIP6Config *s_ip6,
+ guint8 *anycast_addr,
+ const char *hostname,
+ gboolean info_only);
- void (*stop) (NMDHCPClient *self);
+ void (*stop) (NMDHCPClient *self,
+ gboolean release);
/* Signals */
void (*state_changed) (NMDHCPClient *self, NMDHCPState state);
@@ -116,7 +117,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self,
const char *hostname,
gboolean info_only);
-void nm_dhcp_client_stop (NMDHCPClient *self);
+void nm_dhcp_client_stop (NMDHCPClient *self, gboolean release);
void nm_dhcp_client_new_options (NMDHCPClient *self,
GHashTable *options,
@@ -133,5 +134,7 @@ NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test)
/* Backend helpers */
void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name);
+void nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs);
+
#endif /* NM_DHCP_CLIENT_H */
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
index f6f2a540d..88136a900 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient.c
@@ -353,7 +353,7 @@ create_dhclient_config (const char *iface,
GError *error = NULL;
gboolean success = FALSE;
- g_return_val_if_fail (iface != NULL, FALSE);
+ g_return_val_if_fail (iface != NULL, NULL);
#if defined(TARGET_SUSE)
orig = g_strdup (SYSCONFDIR "/dhclient.conf");
@@ -369,7 +369,7 @@ create_dhclient_config (const char *iface,
if (!orig) {
nm_log_warn (LOGD_DHCP, "(%s): not enough memory for dhclient options.", iface);
- return FALSE;
+ return NULL;
}
#if !defined(TARGET_SUSE) && !defined(TARGET_DEBIAN) && !defined(TARGET_GENTOO)
@@ -379,7 +379,7 @@ create_dhclient_config (const char *iface,
orig = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient-%s.conf", iface);
if (!orig) {
nm_log_warn (LOGD_DHCP, "(%s): not enough memory for dhclient options.", iface);
- return FALSE;
+ return NULL;
}
}
#endif
@@ -411,15 +411,15 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED)
static GPid
dhclient_start (NMDHCPClient *client,
- const char *ip_opt,
- const char *mode_opt)
+ const char *mode_opt,
+ gboolean release)
{
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
GPtrArray *argv = NULL;
GPid pid = -1;
GError *error = NULL;
const char *iface, *uuid;
- char *binary_name, *cmd_str;
+ char *binary_name, *cmd_str, *pid_file = NULL;
gboolean ipv6;
guint log_domain;
@@ -436,28 +436,33 @@ dhclient_start (NMDHCPClient *client,
nm_log_warn (log_domain, "(%s): ISC dhcp3 does not support IPv6", iface);
return -1;
}
-#else
- g_return_val_if_fail (ip_opt != NULL, -1);
#endif
- priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid",
- ipv6 ? "6" : "",
- iface);
- if (!priv->pid_file) {
- nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface);
+ if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) {
+ nm_log_warn (log_domain, "%s does not exist.", priv->path);
return -1;
}
- if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) {
- nm_log_warn (log_domain, "%s does not exist.", priv->path);
+ pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid",
+ ipv6 ? "6" : "",
+ iface);
+ if (!pid_file) {
+ nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface);
return -1;
}
/* Kill any existing dhclient from the pidfile */
binary_name = g_path_get_basename (priv->path);
- nm_dhcp_client_stop_existing (priv->pid_file, binary_name);
+ nm_dhcp_client_stop_existing (pid_file, binary_name);
g_free (binary_name);
+ if (release) {
+ /* release doesn't use the pidfile after killing an old client */
+ g_free (pid_file);
+ pid_file = NULL;
+ }
+
+ g_free (priv->lease_file);
priv->lease_file = get_leasefile_for_iface (iface, uuid, ipv6);
if (!priv->lease_file) {
nm_log_warn (log_domain, "(%s): not enough memory for dhclient options.", iface);
@@ -469,17 +474,26 @@ dhclient_start (NMDHCPClient *client,
g_ptr_array_add (argv, (gpointer) "-d");
+ if (release)
+ g_ptr_array_add (argv, (gpointer) "-r");
+
#if !defined(DHCLIENT_V3)
- g_ptr_array_add (argv, (gpointer) ip_opt);
- if (mode_opt)
- g_ptr_array_add (argv, (gpointer) mode_opt);
+ if (ipv6) {
+ g_ptr_array_add (argv, (gpointer) "-6");
+ if (mode_opt)
+ g_ptr_array_add (argv, (gpointer) mode_opt);
+ } else {
+ g_ptr_array_add (argv, (gpointer) "-4");
+ }
#endif
g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */
g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH );
- g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */
- g_ptr_array_add (argv, (gpointer) priv->pid_file);
+ if (pid_file) {
+ g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */
+ g_ptr_array_add (argv, (gpointer) pid_file);
+ }
g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */
g_ptr_array_add (argv, (gpointer) priv->lease_file);
@@ -501,8 +515,10 @@ dhclient_start (NMDHCPClient *client,
nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message);
g_error_free (error);
pid = -1;
- } else
+ } else {
nm_log_info (log_domain, "dhclient started with pid %d", pid);
+ priv->pid_file = pid_file;
+ }
g_ptr_array_free (argv, TRUE);
return pid;
@@ -525,7 +541,7 @@ real_ip4_start (NMDHCPClient *client,
return -1;
}
- return dhclient_start (client, "-4", NULL);
+ return dhclient_start (client, NULL, FALSE);
}
static GPid
@@ -535,21 +551,34 @@ real_ip6_start (NMDHCPClient *client,
const char *hostname,
gboolean info_only)
{
- return dhclient_start (client, "-6", info_only ? "-S" : "-N");
+ return dhclient_start (client, info_only ? "-S" : "-N", FALSE);
}
static void
-real_stop (NMDHCPClient *client)
+real_stop (NMDHCPClient *client, gboolean release)
{
NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client);
/* Chain up to parent */
- NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client);
+ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release);
if (priv->conf_file)
remove (priv->conf_file);
- if (priv->pid_file)
+ if (priv->pid_file) {
remove (priv->pid_file);
+ g_free (priv->pid_file);
+ priv->pid_file = NULL;
+ }
+
+ if (release) {
+ GPid rpid;
+
+ rpid = dhclient_start (client, NULL, TRUE);
+ if (rpid > 0) {
+ /* Wait a few seconds for the release to happen */
+ nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client), 5);
+ }
+ }
}
/***************************************************/
diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c
index 4fb703c48..237661fe4 100644
--- a/src/dhcp-manager/nm-dhcp-dhcpcd.c
+++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c
@@ -170,15 +170,17 @@ real_ip6_start (NMDHCPClient *client,
}
static void
-real_stop (NMDHCPClient *client)
+real_stop (NMDHCPClient *client, gboolean release)
{
NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client);
/* Chain up to parent */
- NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client);
+ NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release);
if (priv->pid_file)
remove (priv->pid_file);
+
+ /* FIXME: implement release... */
}
/***************************************************/
diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c
index 8ef961fad..e65f6935e 100644
--- a/src/dhcp-manager/nm-dhcp-manager.c
+++ b/src/dhcp-manager/nm-dhcp-manager.c
@@ -20,7 +20,7 @@
*
*/
-
+#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <dbus/dbus.h>
@@ -428,7 +428,7 @@ client_start (NMDHCPManager *self,
/* Kill any old client instance */
client = get_client_for_iface (self, iface, ipv6);
if (client) {
- nm_dhcp_client_stop (client);
+ nm_dhcp_client_stop (client, FALSE);
remove_client (self, client);
}
diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in
index e1393aa85..ee6312a70 100644
--- a/src/dhcp-manager/tests/Makefile.in
+++ b/src/dhcp-manager/tests/Makefile.in
@@ -39,11 +39,16 @@ subdir = src/dhcp-manager/tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -62,7 +67,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -93,7 +98,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -102,8 +106,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -120,6 +122,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -128,6 +131,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -136,8 +140,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -152,13 +156,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -166,6 +180,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -174,13 +190,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -206,12 +224,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -226,10 +241,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/dns-manager/Makefile.in b/src/dns-manager/Makefile.in
index 78d4765a4..c8bf51006 100644
--- a/src/dns-manager/Makefile.in
+++ b/src/dns-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/dns-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -64,7 +69,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -95,7 +100,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -104,8 +108,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -122,6 +124,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -130,6 +133,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -138,8 +142,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -154,13 +158,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -168,6 +182,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -176,13 +192,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -208,12 +226,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -228,10 +243,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/dns-manager/nm-dns-bind.c b/src/dns-manager/nm-dns-bind.c
index 9e3fc1739..fc7af7764 100644
--- a/src/dns-manager/nm-dns-bind.c
+++ b/src/dns-manager/nm-dns-bind.c
@@ -190,7 +190,7 @@ find_zone (GPtrArray *zones, const char *domain)
{
guint32 dhash, i;
- g_return_val_if_fail (domain != NULL, FALSE);
+ g_return_val_if_fail (domain != NULL, NULL);
dhash = g_str_hash (domain);
for (i = 0; i < zones->len; i++) {
diff --git a/src/dns-manager/nm-dns-manager.h b/src/dns-manager/nm-dns-manager.h
index eb1c73a7c..66ee59404 100644
--- a/src/dns-manager/nm-dns-manager.h
+++ b/src/dns-manager/nm-dns-manager.h
@@ -24,7 +24,6 @@
#ifndef NM_DNS_MANAGER_H
#define NM_DNS_MANAGER_H
-#include "config.h"
#include <glib-object.h>
#include <dbus/dbus.h>
#include "nm-ip4-config.h"
diff --git a/src/dnsmasq-manager/Makefile.in b/src/dnsmasq-manager/Makefile.in
index d158168fc..7ef4efe7a 100644
--- a/src/dnsmasq-manager/Makefile.in
+++ b/src/dnsmasq-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/dnsmasq-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -61,7 +66,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -92,7 +97,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -101,8 +105,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -119,6 +121,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -127,6 +130,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -135,8 +139,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -151,13 +155,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -165,6 +179,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -173,13 +189,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -205,12 +223,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -225,10 +240,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/ip6-manager/Makefile.in b/src/ip6-manager/Makefile.in
index d7190e930..7d001ce59 100644
--- a/src/ip6-manager/Makefile.in
+++ b/src/ip6-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/ip6-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -61,7 +66,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -92,7 +97,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -101,8 +105,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -119,6 +121,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -127,6 +130,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -135,8 +139,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -151,13 +155,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -165,6 +179,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -173,13 +189,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -205,12 +223,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -225,10 +240,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/logging/Makefile.in b/src/logging/Makefile.in
index 2bc4cbacc..0809dc71a 100644
--- a/src/logging/Makefile.in
+++ b/src/logging/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/logging
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -58,7 +63,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -89,7 +94,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -98,8 +102,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -116,6 +118,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -124,6 +127,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -132,8 +136,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -148,13 +152,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -162,6 +176,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -170,13 +186,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -202,12 +220,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -222,10 +237,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c
index 348845079..1e289d371 100644
--- a/src/logging/nm-logging.c
+++ b/src/logging/nm-logging.c
@@ -19,7 +19,8 @@
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
-#define _GNU_SOURCE
+#include "config.h"
+
#include <dlfcn.h>
#include <syslog.h>
#include <execinfo.h>
@@ -41,8 +42,9 @@ static guint32 log_level = LOGL_INFO | LOGL_WARN | LOGL_ERR;
static guint32 log_domains = \
LOGD_HW | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \
LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 | \
- LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_USER_SET | \
- LOGD_SYS_SET | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH;
+ LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_AGENTS | \
+ LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH | \
+ LOGD_WIMAX;
typedef struct {
guint32 num;
@@ -76,12 +78,13 @@ static const LogDesc domain_descs[] = {
{ LOGD_VPN, "VPN" },
{ LOGD_SHARING, "SHARING" },
{ LOGD_SUPPLICANT,"SUPPLICANT" },
- { LOGD_USER_SET, "USER_SET" },
- { LOGD_SYS_SET, "SYS_SET" },
+ { LOGD_AGENTS, "AGENTS" },
+ { LOGD_SETTINGS, "SETTINGS" },
{ LOGD_SUSPEND, "SUSPEND" },
{ LOGD_CORE, "CORE" },
{ LOGD_DEVICE, "DEVICE" },
{ LOGD_OLPC_MESH, "OLPC" },
+ { LOGD_WIMAX, "WIMAX" },
{ 0, NULL }
};
diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h
index b23f83a32..44e49a712 100644
--- a/src/logging/nm-logging.h
+++ b/src/logging/nm-logging.h
@@ -45,12 +45,13 @@ enum {
LOGD_VPN = 0x00004000,
LOGD_SHARING = 0x00008000, /* Connection sharing/dnsmasq */
LOGD_SUPPLICANT = 0x00010000, /* WiFi and 802.1x */
- LOGD_USER_SET = 0x00020000, /* User settings */
- LOGD_SYS_SET = 0x00040000, /* System settings */
+ LOGD_AGENTS = 0x00020000, /* Secret agents */
+ LOGD_SETTINGS = 0x00040000, /* Settings */
LOGD_SUSPEND = 0x00080000, /* Suspend/Resume */
LOGD_CORE = 0x00100000, /* Core daemon and policy stuff */
LOGD_DEVICE = 0x00200000, /* Device state and activation */
LOGD_OLPC_MESH = 0x00400000,
+ LOGD_WIMAX = 0x00800000,
};
#define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6)
diff --git a/src/main.c b/src/main.c
index b22c769df..39e03de21 100644
--- a/src/main.c
+++ b/src/main.c
@@ -307,6 +307,7 @@ parse_config_file (const char *filename,
GError **error)
{
GKeyFile *config;
+ gboolean success = FALSE;
config = g_key_file_new ();
if (!config) {
@@ -317,11 +318,11 @@ parse_config_file (const char *filename,
g_key_file_set_list_separator (config, ',');
if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error))
- return FALSE;
+ goto out;
*plugins = g_key_file_get_value (config, "main", "plugins", error);
if (*error)
- return FALSE;
+ goto out;
*dhcp_client = g_key_file_get_value (config, "main", "dhcp", NULL);
*dns_plugins = g_key_file_get_string_list (config, "main", "dns", NULL, NULL);
@@ -329,8 +330,11 @@ parse_config_file (const char *filename,
*log_level = g_key_file_get_value (config, "logging", "level", NULL);
*log_domains = g_key_file_get_value (config, "logging", "domains", NULL);
+ success = TRUE;
+
+out:
g_key_file_free (config);
- return TRUE;
+ return success;
}
static gboolean
@@ -338,15 +342,17 @@ parse_state_file (const char *filename,
gboolean *net_enabled,
gboolean *wifi_enabled,
gboolean *wwan_enabled,
+ gboolean *wimax_enabled,
GError **error)
{
GKeyFile *state_file;
GError *tmp_error = NULL;
- gboolean wifi, net, wwan;
+ gboolean wifi, net, wwan, wimax;
g_return_val_if_fail (net_enabled != NULL, FALSE);
g_return_val_if_fail (wifi_enabled != NULL, FALSE);
g_return_val_if_fail (wwan_enabled != NULL, FALSE);
+ g_return_val_if_fail (wimax_enabled != NULL, FALSE);
state_file = g_key_file_new ();
if (!state_file) {
@@ -385,6 +391,7 @@ parse_state_file (const char *filename,
g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled);
g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled);
g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled);
+ g_key_file_set_boolean (state_file, "main", "WimaxEnabled", *wimax_enabled);
data = g_key_file_to_data (state_file, &len, NULL);
if (data)
@@ -427,6 +434,14 @@ parse_state_file (const char *filename,
*wwan_enabled = wwan;
g_clear_error (&tmp_error);
+ wimax = g_key_file_get_boolean (state_file, "main", "WimaxEnabled", &tmp_error);
+ if (tmp_error) {
+ g_clear_error (error);
+ g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message);
+ } else
+ *wimax_enabled = wimax;
+ g_clear_error (&tmp_error);
+
g_key_file_free (state_file);
return TRUE;
@@ -446,7 +461,7 @@ main (int argc, char *argv[])
char *config = NULL, *plugins = NULL, *conf_plugins = NULL;
char *log_level = NULL, *log_domains = NULL;
char **dns = NULL;
- gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE;
+ gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE;
gboolean success;
NMPolicy *policy = NULL;
NMVPNManager *vpn_manager = NULL;
@@ -454,6 +469,7 @@ main (int argc, char *argv[])
NMDBusManager *dbus_mgr = NULL;
NMSupplicantManager *sup_mgr = NULL;
NMDHCPManager *dhcp_mgr = NULL;
+ NMSettings *settings = NULL;
GError *error = NULL;
gboolean wrote_pidfile = FALSE;
char *cfg_log_level = NULL, *cfg_log_domains = NULL;
@@ -581,7 +597,7 @@ main (int argc, char *argv[])
g_free (conf_plugins);
/* Parse the state file */
- if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) {
+ if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) {
fprintf (stderr, "State file %s parsing failed: (%d) %s\n",
state_file,
error ? error->code : -1,
@@ -673,20 +689,29 @@ main (int argc, char *argv[])
goto done;
}
- manager = nm_manager_get (config,
+ settings = nm_settings_new (config, plugins, &error);
+ if (!settings) {
+ nm_log_err (LOGD_CORE, "failed to initialize settings storage: %s",
+ error && error->message ? error->message : "(unknown)");
+ goto done;
+ }
+
+ manager = nm_manager_get (settings,
+ config,
plugins,
state_file,
net_enabled,
wifi_enabled,
wwan_enabled,
+ wimax_enabled,
&error);
if (manager == NULL) {
nm_log_err (LOGD_CORE, "failed to initialize the network manager: %s",
- error && error->message ? error->message : "(unknown)");
+ error && error->message ? error->message : "(unknown)");
goto done;
}
- policy = nm_policy_new (manager, vpn_manager);
+ policy = nm_policy_new (manager, vpn_manager, settings);
if (policy == NULL) {
nm_log_err (LOGD_CORE, "failed to initialize the policy.");
goto done;
@@ -737,6 +762,9 @@ done:
if (manager)
g_object_unref (manager);
+ if (settings)
+ g_object_unref (settings);
+
if (vpn_manager)
g_object_unref (vpn_manager);
diff --git a/src/modem-manager/Makefile.am b/src/modem-manager/Makefile.am
index 22ed809fe..db680aeae 100644
--- a/src/modem-manager/Makefile.am
+++ b/src/modem-manager/Makefile.am
@@ -26,10 +26,3 @@ libmodem_manager_la_LIBADD = \
$(top_builddir)/src/logging/libnm-logging.la \
$(DBUS_LIBS)
-nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $<
-
-BUILT_SOURCES = \
- nm-serial-device-glue.h
-
-CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/modem-manager/Makefile.in b/src/modem-manager/Makefile.in
index 5d33ee268..ffe360bf8 100644
--- a/src/modem-manager/Makefile.in
+++ b/src/modem-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/modem-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -64,7 +69,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -95,7 +100,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -104,8 +108,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -122,6 +124,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -130,6 +133,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -138,8 +142,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -154,13 +158,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -168,6 +182,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -176,13 +192,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -208,12 +226,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -228,10 +243,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -307,12 +325,7 @@ libmodem_manager_la_LIBADD = \
$(top_builddir)/src/logging/libnm-logging.la \
$(DBUS_LIBS)
-BUILT_SOURCES = \
- nm-serial-device-glue.h
-
-CLEANFILES = $(BUILT_SOURCES)
-all: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) all-am
+all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -517,12 +530,10 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
-check: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) check-am
+check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
-install: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) install-am
+install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@@ -539,7 +550,6 @@ install-strip:
mostlyclean-generic:
clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -548,7 +558,6 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
- -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
@@ -620,7 +629,7 @@ ps-am:
uninstall-am:
-.MAKE: all check install install-am install-strip
+.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
@@ -636,9 +645,6 @@ uninstall-am:
pdf pdf-am ps ps-am tags uninstall uninstall-am
-nm-serial-device-glue.h: $(top_srcdir)/introspection/nm-device-serial.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_serial_device --mode=glib-server --output=$@ $<
-
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c
index c32c18222..5db6a84f3 100644
--- a/src/modem-manager/nm-modem-cdma.c
+++ b/src/modem-manager/nm-modem-cdma.c
@@ -15,16 +15,20 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
+#include "config.h"
+
#include <string.h>
+#include <glib/gi18n.h>
#include "nm-dbus-glib-types.h"
#include "nm-modem-cdma.h"
#include "nm-modem-types.h"
#include "nm-device.h"
+#include "nm-device-private.h"
#include "nm-dbus-manager.h"
#include "nm-setting-connection.h"
#include "nm-setting-cdma.h"
@@ -270,6 +274,33 @@ real_check_connection_compatible (NMModem *modem,
}
static gboolean
+real_complete_connection (NMModem *modem,
+ NMConnection *connection,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMSettingCdma *s_cdma;
+
+ s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
+ if (!s_cdma) {
+ s_cdma = (NMSettingCdma *) nm_setting_cdma_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_cdma));
+ }
+
+ if (!nm_setting_cdma_get_number (s_cdma))
+ g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL);
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_CDMA_SETTING_NAME,
+ existing_connections,
+ _("CDMA connection %d"),
+ NULL,
+ FALSE); /* No IPv6 yet by default */
+
+ return TRUE;
+}
+
+static gboolean
real_get_user_pass (NMModem *modem,
NMConnection *connection,
const char **user,
@@ -296,7 +327,7 @@ real_get_setting_name (NMModem *modem)
}
static void
-real_deactivate_quickly (NMModem *modem, NMDevice *device)
+real_deactivate (NMModem *modem, NMDevice *device)
{
NMModemCdmaPrivate *priv = NM_MODEM_CDMA_GET_PRIVATE (modem);
@@ -308,7 +339,7 @@ real_deactivate_quickly (NMModem *modem, NMDevice *device)
priv->call = NULL;
}
- NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate_quickly (modem, device);
+ NM_MODEM_CLASS (nm_modem_cdma_parent_class)->deactivate (modem, device);
}
/*****************************************************************************/
@@ -344,8 +375,9 @@ nm_modem_cdma_class_init (NMModemCdmaClass *klass)
modem_class->get_setting_name = real_get_setting_name;
modem_class->get_best_auto_connection = real_get_best_auto_connection;
modem_class->check_connection_compatible = real_check_connection_compatible;
+ modem_class->complete_connection = real_complete_connection;
modem_class->act_stage1_prepare = real_act_stage1_prepare;
- modem_class->deactivate_quickly = real_deactivate_quickly;
+ modem_class->deactivate = real_deactivate;
dbus_g_error_domain_register (NM_CDMA_ERROR, NULL, NM_TYPE_CDMA_ERROR);
}
diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c
index abb96db1f..9a96ae99c 100644
--- a/src/modem-manager/nm-modem-gsm.c
+++ b/src/modem-manager/nm-modem-gsm.c
@@ -15,14 +15,19 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
+#include "config.h"
+
#include <string.h>
+#include <glib/gi18n.h>
+
#include "nm-dbus-glib-types.h"
#include "nm-modem-gsm.h"
#include "nm-device.h"
+#include "nm-device-private.h"
#include "nm-setting-connection.h"
#include "nm-setting-gsm.h"
#include "nm-modem-types.h"
@@ -177,12 +182,10 @@ ask_for_pin (NMModemGsm *self, gboolean always_ask)
if (!always_ask)
tries = priv->pin_tries++;
- g_signal_emit_by_name (self, NM_MODEM_NEED_AUTH,
- NM_SETTING_GSM_SETTING_NAME,
- (tries || always_ask) ? TRUE : FALSE,
- SECRETS_CALLER_MOBILE_BROADBAND,
- NM_SETTING_GSM_PIN,
- NULL);
+ nm_modem_get_secrets (NM_MODEM (self),
+ NM_SETTING_GSM_SETTING_NAME,
+ (tries || always_ask) ? TRUE : FALSE,
+ NM_SETTING_GSM_PIN);
}
static void
@@ -470,6 +473,37 @@ real_check_connection_compatible (NMModem *modem,
}
static gboolean
+real_complete_connection (NMModem *modem,
+ NMConnection *connection,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMSettingGsm *s_gsm;
+
+ s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
+ if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) {
+ /* Need an APN at least */
+ g_set_error_literal (error,
+ NM_SETTING_GSM_ERROR,
+ NM_SETTING_GSM_ERROR_MISSING_PROPERTY,
+ NM_SETTING_GSM_APN);
+ return FALSE;
+ }
+
+ if (!nm_setting_gsm_get_number (s_gsm))
+ g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_GSM_SETTING_NAME,
+ existing_connections,
+ _("GSM connection %d"),
+ NULL,
+ FALSE); /* No IPv6 yet by default */
+
+ return TRUE;
+}
+
+static gboolean
real_get_user_pass (NMModem *modem,
NMConnection *connection,
const char **user,
@@ -496,7 +530,7 @@ real_get_setting_name (NMModem *modem)
}
static void
-real_deactivate_quickly (NMModem *modem, NMDevice *device)
+real_deactivate (NMModem *modem, NMDevice *device)
{
NMModemGsmPrivate *priv = NM_MODEM_GSM_GET_PRIVATE (modem);
@@ -510,7 +544,7 @@ real_deactivate_quickly (NMModem *modem, NMDevice *device)
priv->pin_tries = 0;
- NM_MODEM_CLASS (nm_modem_gsm_parent_class)->deactivate_quickly (modem, device);
+ NM_MODEM_CLASS (nm_modem_gsm_parent_class)->deactivate (modem, device);
}
@@ -547,8 +581,9 @@ nm_modem_gsm_class_init (NMModemGsmClass *klass)
modem_class->get_setting_name = real_get_setting_name;
modem_class->get_best_auto_connection = real_get_best_auto_connection;
modem_class->check_connection_compatible = real_check_connection_compatible;
+ modem_class->complete_connection = real_complete_connection;
modem_class->act_stage1_prepare = real_act_stage1_prepare;
- modem_class->deactivate_quickly = real_deactivate_quickly;
+ modem_class->deactivate = real_deactivate;
dbus_g_error_domain_register (NM_GSM_ERROR, NULL, NM_TYPE_GSM_ERROR);
}
diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c
index 28f7b94d0..f5ade50c0 100644
--- a/src/modem-manager/nm-modem-manager.c
+++ b/src/modem-manager/nm-modem-manager.c
@@ -371,7 +371,7 @@ nm_modem_manager_init (NMModemManager *self)
priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
priv->dbus_mgr = nm_dbus_manager_get ();
- g_signal_connect (priv->dbus_mgr, "name-owner-changed",
+ g_signal_connect (priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (nm_modem_manager_name_owner_changed),
self);
diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index b3f7eaa1c..449370eb6 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
@@ -33,8 +33,6 @@
#include "nm-device-interface.h"
#include "nm-dbus-glib-types.h"
-#include "nm-serial-device-glue.h"
-
G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT)
#define NM_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MODEM, NMModemPrivate))
@@ -62,7 +60,9 @@ typedef struct {
char *device;
char *iface;
+ NMActRequest *act_request;
guint32 secrets_tries;
+ guint32 secrets_id;
DBusGProxyCall *call;
@@ -78,7 +78,8 @@ enum {
PPP_FAILED,
PREPARE_RESULT,
IP4_CONFIG_RESULT,
- NEED_AUTH,
+ AUTH_REQUESTED,
+ AUTH_RESULT,
LAST_SIGNAL
};
@@ -475,67 +476,60 @@ nm_modem_stage4_get_ip4_config (NMModem *self,
return ret;
}
-gboolean
-nm_modem_connection_secrets_updated (NMModem *self,
- NMActRequest *req,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller)
+static void
+cancel_get_secrets (NMModem *self)
{
- NMModemPrivate *priv;
- gboolean found = FALSE;
- const char *setting_name;
- GSList *iter;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (NM_IS_MODEM (self), FALSE);
- g_return_val_if_fail (req != NULL, FALSE);
- g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
-
- priv = NM_MODEM_GET_PRIVATE (self);
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
- if (caller == SECRETS_CALLER_PPP) {
- const char *user = NULL;
- const char *pass = NULL;
-
- g_return_val_if_fail (priv->ppp_manager != NULL, FALSE);
-
- if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &user, &pass)) {
- /* Shouldn't ever happen */
- nm_ppp_manager_update_secrets (priv->ppp_manager,
- priv->iface,
- NULL,
- NULL,
- "missing GSM/CDMA setting; no secrets could be found.");
- } else {
- nm_ppp_manager_update_secrets (priv->ppp_manager,
- priv->iface,
- user ? user : "",
- pass ? pass : "",
- NULL);
- }
- return TRUE;
+ if (priv->secrets_id) {
+ nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
+ priv->secrets_id = 0;
}
+}
- g_return_val_if_fail (caller == SECRETS_CALLER_MOBILE_BROADBAND, FALSE);
+static void
+modem_secrets_cb (NMActRequest *req,
+ guint32 call_id,
+ NMConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ NMModem *self = NM_MODEM (user_data);
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
- g_assert (NM_MODEM_GET_CLASS (self)->get_setting_name);
- setting_name = NM_MODEM_GET_CLASS (self)->get_setting_name (self);
+ g_return_if_fail (call_id == priv->secrets_id);
- for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
- const char *candidate_setting_name = (const char *) iter->data;
+ priv->secrets_id = 0;
- if (!strcmp (candidate_setting_name, setting_name))
- found = TRUE;
- else {
- nm_log_warn (LOGD_MB, "ignoring updated secrets for setting '%s'.",
- candidate_setting_name);
- }
- }
+ if (error)
+ nm_log_warn (LOGD_MB, "%s", error->message);
- return found;
+ g_signal_emit (self, signals[AUTH_RESULT], 0, error);
+}
+
+gboolean
+nm_modem_get_secrets (NMModem *self,
+ const char *setting_name,
+ gboolean request_new,
+ const char *hint)
+{
+ NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+
+ cancel_get_secrets (self);
+
+ if (request_new)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+ priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
+ setting_name,
+ flags,
+ hint,
+ modem_secrets_cb,
+ self);
+ if (priv->secrets_id)
+ g_signal_emit (self, signals[AUTH_REQUESTED], 0);
+
+ return !!(priv->secrets_id);
}
static NMActStageReturn
@@ -558,6 +552,11 @@ nm_modem_act_stage1_prepare (NMModem *self,
NMActStageReturn ret;
GPtrArray *hints = NULL;
const char *setting_name = NULL;
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+
+ if (priv->act_request)
+ g_object_unref (priv->act_request);
+ priv->act_request = g_object_ref (req);
ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self,
req,
@@ -565,23 +564,22 @@ nm_modem_act_stage1_prepare (NMModem *self,
&setting_name,
reason);
if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
- const char *hint1 = NULL, *hint2 = NULL;
-
- /* Need some secrets */
- if (hints) {
- if (hints->len > 0)
- hint1 = g_ptr_array_index (hints, 0);
- if (hints->len > 1)
- hint2 = g_ptr_array_index (hints, 1);
+ if (priv->secrets_tries++)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+
+ priv->secrets_id = nm_act_request_get_secrets (req,
+ setting_name,
+ flags,
+ hints ? g_ptr_array_index (hints, 0) : NULL,
+ modem_secrets_cb,
+ self);
+ if (priv->secrets_id)
+ g_signal_emit (self, signals[AUTH_REQUESTED], 0);
+ else {
+ *reason = NM_DEVICE_STATE_REASON_NO_SECRETS;
+ ret = NM_ACT_STAGE_RETURN_FAILURE;
}
- g_signal_emit (self, signals[NEED_AUTH], 0,
- setting_name,
- priv->secrets_tries++ ? TRUE : FALSE,
- SECRETS_CALLER_MOBILE_BROADBAND,
- hint1,
- hint2);
-
if (hints)
g_ptr_array_free (hints, TRUE);
}
@@ -624,8 +622,19 @@ nm_modem_check_connection_compatible (NMModem *self,
return FALSE;
}
+gboolean
+nm_modem_complete_connection (NMModem *self,
+ NMConnection *connection,
+ const GSList *existing_connections,
+ GError **error)
+{
+ if (NM_MODEM_GET_CLASS (self)->complete_connection)
+ return NM_MODEM_GET_CLASS (self)->complete_connection (self, connection, existing_connections, error);
+ return FALSE;
+}
+
static void
-real_deactivate_quickly (NMModem *self, NMDevice *device)
+real_deactivate (NMModem *self, NMDevice *device)
{
NMModemPrivate *priv;
const char *iface;
@@ -639,6 +648,12 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
priv->secrets_tries = 0;
+ if (priv->act_request) {
+ cancel_get_secrets (self);
+ g_object_unref (priv->act_request);
+ priv->act_request = NULL;
+ }
+
if (priv->call) {
dbus_g_proxy_cancel_call (priv->proxy, priv->call);
priv->call = NULL;
@@ -673,9 +688,9 @@ real_deactivate_quickly (NMModem *self, NMDevice *device)
}
void
-nm_modem_deactivate_quickly (NMModem *self, NMDevice *device)
+nm_modem_deactivate (NMModem *self, NMDevice *device)
{
- NM_MODEM_GET_CLASS (self)->deactivate_quickly (self, device);
+ NM_MODEM_GET_CLASS (self)->deactivate (self, device);
}
static void
@@ -697,6 +712,7 @@ nm_modem_device_state_changed (NMModem *self,
NMDeviceStateReason reason)
{
gboolean was_connected = FALSE;
+ NMModemPrivate *priv;
g_return_if_fail (self != NULL);
g_return_if_fail (NM_IS_MODEM (self));
@@ -704,16 +720,26 @@ nm_modem_device_state_changed (NMModem *self,
if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED))
was_connected = TRUE;
+ priv = NM_MODEM_GET_PRIVATE (self);
+
/* Make sure we don't leave the serial device open */
switch (new_state) {
case NM_DEVICE_STATE_NEED_AUTH:
- if (NM_MODEM_GET_PRIVATE (self)->ppp_manager)
+ if (priv->ppp_manager)
break;
/* else fall through */
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_FAILED:
case NM_DEVICE_STATE_DISCONNECTED:
+ if (new_state != NM_DEVICE_STATE_NEED_AUTH) {
+ if (priv->act_request) {
+ cancel_get_secrets (self);
+ g_object_unref (priv->act_request);
+ priv->act_request = NULL;
+ }
+ }
+
if (was_connected) {
dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM),
"Disconnect",
@@ -728,6 +754,12 @@ nm_modem_device_state_changed (NMModem *self,
}
}
+static gboolean
+_state_is_active (NMDeviceState state)
+{
+ return (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING);
+}
+
gboolean
nm_modem_hw_is_up (NMModem *self, NMDevice *device)
{
@@ -738,7 +770,7 @@ nm_modem_hw_is_up (NMModem *self, NMDevice *device)
NMDeviceState state;
state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
- if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
+ if (priv->pending_ip4_config || _state_is_active (state))
return nm_system_device_is_up (device);
}
@@ -755,7 +787,7 @@ nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware)
NMDeviceState state;
state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device));
- if (priv->pending_ip4_config || state == NM_DEVICE_STATE_IP_CONFIG || state == NM_DEVICE_STATE_ACTIVATED)
+ if (priv->pending_ip4_config || _state_is_active (state))
return nm_system_device_set_up_down (device, TRUE, no_firmware);
}
@@ -1022,6 +1054,9 @@ finalize (GObject *object)
{
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object);
+ if (priv->act_request)
+ g_object_unref (priv->act_request);
+
if (priv->proxy)
g_object_unref (priv->proxy);
@@ -1051,7 +1086,7 @@ nm_modem_class_init (NMModemClass *klass)
object_class->finalize = finalize;
klass->act_stage1_prepare = real_act_stage1_prepare;
- klass->deactivate_quickly = real_deactivate_quickly;
+ klass->deactivate = real_deactivate;
/* Properties */
g_object_class_install_property
@@ -1134,20 +1169,22 @@ nm_modem_class_init (NMModemClass *klass)
_nm_marshal_VOID__BOOLEAN_UINT,
G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT);
- signals[NEED_AUTH] =
- g_signal_new (NM_MODEM_NEED_AUTH,
+ signals[AUTH_REQUESTED] =
+ g_signal_new (NM_MODEM_AUTH_REQUESTED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMModemClass, need_auth),
+ G_STRUCT_OFFSET (NMModemClass, auth_requested),
NULL, NULL,
- _nm_marshal_VOID__STRING_BOOLEAN_UINT_STRING_STRING,
- G_TYPE_NONE, 5,
- G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
-}
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
-const DBusGObjectInfo *
-nm_modem_get_serial_dbus_info (void)
-{
- return &dbus_glib_nm_serial_device_object_info;
+ signals[AUTH_RESULT] =
+ g_signal_new (NM_MODEM_AUTH_RESULT,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMModemClass, auth_result),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
}
diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h
index a2aed57e0..a46a198c1 100644
--- a/src/modem-manager/nm-modem.h
+++ b/src/modem-manager/nm-modem.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
* Copyright (C) 2009 Novell, Inc.
*/
@@ -46,7 +46,8 @@ G_BEGIN_DECLS
#define NM_MODEM_PPP_FAILED "ppp-failed"
#define NM_MODEM_PREPARE_RESULT "prepare-result"
#define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result"
-#define NM_MODEM_NEED_AUTH "need-auth"
+#define NM_MODEM_AUTH_REQUESTED "auth-requested"
+#define NM_MODEM_AUTH_RESULT "auth-result"
typedef struct {
GObject parent;
@@ -66,6 +67,11 @@ typedef struct {
NMConnection *connection,
GError **error);
+ gboolean (*complete_connection) (NMModem *modem,
+ NMConnection *connection,
+ const GSList *existing_connections,
+ GError **error);
+
NMConnection * (*get_best_auto_connection) (NMModem *modem,
GSList *connections,
char **specific_object);
@@ -76,7 +82,7 @@ typedef struct {
const char **out_setting_name,
NMDeviceStateReason *reason);
- void (*deactivate_quickly) (NMModem *self, NMDevice *device);
+ void (*deactivate) (NMModem *self, NMDevice *device);
/* Signals */
void (*ppp_stats) (NMModem *self, guint32 in_bytes, guint32 out_bytes);
@@ -85,12 +91,8 @@ typedef struct {
void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason);
void (*ip4_config_result) (NMModem *self, const char *iface, NMIP4Config *config, GError *error);
- void (*need_auth) (NMModem *self,
- const char *setting_name,
- gboolean retry,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2);
+ void (*auth_requested) (NMModem *self);
+ void (*auth_result) (NMModem *self, GError *error);
} NMModemClass;
GType nm_modem_get_type (void);
@@ -110,6 +112,11 @@ gboolean nm_modem_check_connection_compatible (NMModem *self,
NMConnection *connection,
GError **error);
+gboolean nm_modem_complete_connection (NMModem *self,
+ NMConnection *connection,
+ const GSList *existing_connections,
+ GError **error);
+
NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem,
NMActRequest *req,
NMDeviceStateReason *reason);
@@ -129,7 +136,12 @@ NMActStageReturn nm_modem_stage4_get_ip4_config (NMModem *modem,
NMIP4Config **config,
NMDeviceStateReason *reason);
-void nm_modem_deactivate_quickly (NMModem *modem, NMDevice *device);
+gboolean nm_modem_get_secrets (NMModem *modem,
+ const char *setting_name,
+ gboolean request_new,
+ const char *hint);
+
+void nm_modem_deactivate (NMModem *modem, NMDevice *device);
void nm_modem_device_state_changed (NMModem *modem,
NMDeviceState new_state,
@@ -140,14 +152,6 @@ gboolean nm_modem_hw_is_up (NMModem *modem, NMDevice *device);
gboolean nm_modem_hw_bring_up (NMModem *modem, NMDevice *device, gboolean *no_firmware);
-gboolean nm_modem_connection_secrets_updated (NMModem *modem,
- NMActRequest *req,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller);
-
-const DBusGObjectInfo *nm_modem_get_serial_dbus_info (void);
-
gboolean nm_modem_get_mm_enabled (NMModem *self);
void nm_modem_set_mm_enabled (NMModem *self, gboolean enabled);
diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c
index 7d1314014..fb42de685 100644
--- a/src/nm-activation-request.c
+++ b/src/nm-activation-request.c
@@ -15,10 +15,12 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2007 - 2008 Novell, Inc.
*/
+#include "config.h"
+
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
@@ -36,24 +38,19 @@
#include "nm-active-connection.h"
#include "nm-dbus-glib-types.h"
#include "nm-active-connection-glue.h"
+#include "nm-settings-connection.h"
-static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
-
-G_DEFINE_TYPE_EXTENDED (NMActRequest, nm_act_request, G_TYPE_OBJECT, 0,
- G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
- secrets_provider_interface_init))
+G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT)
-#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate))
+#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_ACT_REQUEST, \
+ NMActRequestPrivate))
enum {
- CONNECTION_SECRETS_UPDATED,
- CONNECTION_SECRETS_FAILED,
PROPERTIES_CHANGED,
-
LAST_SIGNAL
};
-
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
@@ -65,11 +62,13 @@ typedef struct {
gboolean disposed;
NMConnection *connection;
- guint32 secrets_call_id;
+
+ GSList *secrets_calls;
char *specific_object;
NMDevice *device;
gboolean user_requested;
+ gulong user_uid;
NMActiveConnectionState state;
gboolean is_default;
@@ -84,7 +83,6 @@ typedef struct {
enum {
PROP_0,
- PROP_SERVICE_NAME,
PROP_CONNECTION,
PROP_SPECIFIC_OBJECT,
PROP_DEVICES,
@@ -96,357 +94,101 @@ enum {
LAST_PROP
};
+/*******************************************************************/
-static void
-device_state_changed (NMDevice *device,
- NMDeviceState new_state,
- NMDeviceState old_state,
- NMDeviceStateReason reason,
- gpointer user_data)
-{
- NMActRequest *self = NM_ACT_REQUEST (user_data);
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
- NMActiveConnectionState new_ac_state;
- gboolean new_default = FALSE, new_default6 = FALSE;
-
- /* Set NMActiveConnection state based on the device's state */
- switch (new_state) {
- case NM_DEVICE_STATE_PREPARE:
- case NM_DEVICE_STATE_CONFIG:
- case NM_DEVICE_STATE_NEED_AUTH:
- case NM_DEVICE_STATE_IP_CONFIG:
- new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
- break;
- case NM_DEVICE_STATE_ACTIVATED:
- new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
- new_default = priv->is_default;
- new_default6 = priv->is_default6;
- break;
- default:
- new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
- break;
- }
-
- if (new_ac_state != priv->state) {
- priv->state = new_ac_state;
- g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
- }
-
- if (new_default != priv->is_default) {
- priv->is_default = new_default;
- g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
- }
-
- if (new_default6 != priv->is_default6) {
- priv->is_default6 = new_default6;
- g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
- }
-}
-
-NMActRequest *
-nm_act_request_new (NMConnection *connection,
- const char *specific_object,
- gboolean user_requested,
- gboolean assumed,
- gpointer *device)
-{
- GObject *object;
- NMActRequestPrivate *priv;
-
- g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
- g_return_val_if_fail (NM_DEVICE (device), NULL);
-
- object = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
- if (!object)
- return NULL;
-
- priv = NM_ACT_REQUEST_GET_PRIVATE (object);
-
- priv->connection = g_object_ref (connection);
- if (specific_object)
- priv->specific_object = g_strdup (specific_object);
-
- priv->device = NM_DEVICE (device);
- g_signal_connect (device, "state-changed",
- G_CALLBACK (device_state_changed),
- NM_ACT_REQUEST (object));
-
- priv->user_requested = user_requested;
- priv->assumed = assumed;
-
- return NM_ACT_REQUEST (object);
-}
+typedef struct {
+ NMActRequest *self;
+ guint32 call_id;
+ NMActRequestSecretsFunc callback;
+ gpointer callback_data;
+} GetSecretsInfo;
static void
-nm_act_request_init (NMActRequest *req)
+get_secrets_cb (NMSettingsConnection *connection,
+ guint32 call_id,
+ const char *agent_username,
+ const char *setting_name,
+ GError *error,
+ gpointer user_data)
{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
- NMDBusManager *dbus_mgr;
+ GetSecretsInfo *info = user_data;
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
- priv->ac_path = nm_active_connection_get_next_object_path ();
- priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
+ g_return_if_fail (info->call_id == call_id);
+ priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
- dbus_mgr = nm_dbus_manager_get ();
- dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
- priv->ac_path,
- G_OBJECT (req));
- g_object_unref (dbus_mgr);
+ info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data);
+ g_free (info);
}
-static void
-dispose (GObject *object)
+guint32
+nm_act_request_get_secrets (NMActRequest *self,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMActRequestSecretsFunc callback,
+ gpointer callback_data)
{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
-
- if (priv->disposed) {
- G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
- return;
- }
- priv->disposed = TRUE;
-
- g_assert (priv->connection);
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device),
- G_CALLBACK (device_state_changed),
- NM_ACT_REQUEST (object));
-
- /* Clear any share rules */
- nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
-
- g_object_unref (priv->connection);
-
- G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
+ NMActRequestPrivate *priv;
+ GetSecretsInfo *info;
+ guint32 call_id;
+
+ g_return_val_if_fail (self, 0);
+ g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
+
+ priv = NM_ACT_REQUEST_GET_PRIVATE (self);
+
+ info = g_malloc0 (sizeof (GetSecretsInfo));
+ info->self = self;
+ info->callback = callback;
+ info->callback_data = callback_data;
+
+ call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
+ priv->user_requested,
+ priv->user_uid,
+ setting_name,
+ flags,
+ hint,
+ get_secrets_cb,
+ info,
+ NULL);
+ if (call_id > 0) {
+ info->call_id = call_id;
+ priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
+ } else
+ g_free (info);
+
+ return call_id;
}
-static void
-clear_share_rules (NMActRequest *req)
+void
+nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+ NMActRequestPrivate *priv;
GSList *iter;
- for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) {
- ShareRule *rule = (ShareRule *) iter->data;
-
- g_free (rule->table);
- g_free (rule->rule);
- g_free (rule);
- }
-
- g_slist_free (priv->share_rules);
- priv->share_rules = NULL;
-}
-
-static void
-finalize (GObject *object)
-{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
-
- g_free (priv->specific_object);
- g_free (priv->ac_path);
-
- clear_share_rules (NM_ACT_REQUEST (object));
-
- G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
- GPtrArray *devices;
-
- switch (prop_id) {
- case PROP_SERVICE_NAME:
- nm_active_connection_scope_to_value (priv->connection, value);
- break;
- case PROP_CONNECTION:
- g_value_set_boxed (value, nm_connection_get_path (priv->connection));
- break;
- case PROP_SPECIFIC_OBJECT:
- if (priv->specific_object)
- g_value_set_boxed (value, priv->specific_object);
- else
- g_value_set_boxed (value, "/");
- break;
- case PROP_DEVICES:
- devices = g_ptr_array_sized_new (1);
- g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device)));
- g_value_take_boxed (value, devices);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_DEFAULT:
- g_value_set_boolean (value, priv->is_default);
- break;
- case PROP_DEFAULT6:
- g_value_set_boolean (value, priv->is_default6);
- break;
- case PROP_VPN:
- g_value_set_boolean (value, FALSE);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_act_request_class_init (NMActRequestClass *req_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+ g_return_if_fail (self);
+ g_return_if_fail (NM_IS_ACT_REQUEST (self));
+ g_return_if_fail (call_id > 0);
- g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
+ priv = NM_ACT_REQUEST_GET_PRIVATE (self);
- /* virtual methods */
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = finalize;
+ for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
+ GetSecretsInfo *info = iter->data;
- /* properties */
- nm_active_connection_install_properties (object_class,
- PROP_SERVICE_NAME,
- PROP_CONNECTION,
- PROP_SPECIFIC_OBJECT,
- PROP_DEVICES,
- PROP_STATE,
- PROP_DEFAULT,
- PROP_DEFAULT6,
- PROP_VPN);
-
- /* Signals */
- signals[CONNECTION_SECRETS_UPDATED] =
- g_signal_new ("connection-secrets-updated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMActRequestClass, secrets_updated),
- NULL, NULL,
- _nm_marshal_VOID__OBJECT_POINTER_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT);
-
- signals[CONNECTION_SECRETS_FAILED] =
- g_signal_new ("connection-secrets-failed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMActRequestClass, secrets_failed),
- NULL, NULL,
- _nm_marshal_VOID__OBJECT_STRING_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_UINT);
-
- signals[PROPERTIES_CHANGED] =
- nm_properties_changed_signal_new (object_class,
- G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
+ /* Remove the matching info */
+ if (info->call_id == call_id) {
+ priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter);
+ g_slist_free (iter);
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class),
- &dbus_glib_nm_active_connection_object_info);
-}
-
-static gboolean
-secrets_update_setting (NMSecretsProviderInterface *interface,
- const char *setting_name,
- GHashTable *new)
-{
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (interface);
- NMSetting *setting = NULL;
- GError *error = NULL;
- GType type;
-
- g_return_val_if_fail (priv->connection != NULL, FALSE);
-
- /* Check whether a complete & valid NMSetting object was returned. If
- * yes, replace the setting object in the connection. If not, just try
- * updating the secrets.
- */
- type = nm_connection_lookup_setting_type (setting_name);
- if (type == 0)
- return FALSE;
-
- setting = nm_setting_new_from_hash (type, new);
- if (setting) {
- NMSetting *s_8021x = NULL;
- GSList *all_settings = NULL;
-
- /* The wireless-security setting might need the 802.1x setting in
- * the all_settings argument of the verify function. Ugh.
- */
- s_8021x = nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_802_1X);
- if (s_8021x)
- all_settings = g_slist_append (all_settings, s_8021x);
-
- if (!nm_setting_verify (setting, all_settings, NULL)) {
- /* Just try updating secrets */
- g_object_unref (setting);
- setting = NULL;
+ nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), call_id);
+ g_free (info);
+ break;
}
-
- g_slist_free (all_settings);
- }
-
- if (setting)
- nm_connection_add_setting (priv->connection, setting);
- else {
- if (!nm_connection_update_secrets (priv->connection, setting_name, new, &error)) {
- nm_log_warn (LOGD_DEVICE, "Failed to update connection secrets: %d %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(none)");
- g_clear_error (&error);
- }
- }
-
- return TRUE;
-}
-
-static void
-secrets_result (NMSecretsProviderInterface *interface,
- const char *setting_name,
- RequestSecretsCaller caller,
- const GSList *updated,
- GError *error)
-{
- NMActRequest *self = NM_ACT_REQUEST (interface);
- NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
-
- g_return_if_fail (priv->connection != NULL);
-
- if (error) {
- g_signal_emit (self, signals[CONNECTION_SECRETS_FAILED], 0,
- priv->connection, setting_name, caller);
- } else {
- g_signal_emit (self, signals[CONNECTION_SECRETS_UPDATED], 0,
- priv->connection, updated, caller);
}
}
-static void
-secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
-{
- /* interface implementation */
- sp_interface_class->update_setting = secrets_update_setting;
- sp_interface_class->result = secrets_result;
-}
-
-gboolean
-nm_act_request_get_secrets (NMActRequest *self,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2)
-{
- g_return_val_if_fail (self, FALSE);
- g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE);
-
- return nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
- nm_act_request_get_connection (self),
- setting_name,
- request_new,
- caller,
- hint1,
- hint2);
-}
+/*******************************************************************/
NMConnection *
nm_act_request_get_connection (NMActRequest *req)
@@ -475,8 +217,7 @@ nm_act_request_set_specific_object (NMActRequest *req,
priv = NM_ACT_REQUEST_GET_PRIVATE (req);
- if (priv->specific_object)
- g_free (priv->specific_object);
+ g_free (priv->specific_object);
priv->specific_object = g_strdup (specific_object);
}
@@ -542,6 +283,42 @@ nm_act_request_get_default6 (NMActRequest *req)
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6;
}
+GObject *
+nm_act_request_get_device (NMActRequest *req)
+{
+ g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL);
+
+ return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device);
+}
+
+gboolean
+nm_act_request_get_assumed (NMActRequest *req)
+{
+ g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
+
+ return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed;
+}
+
+/********************************************************************/
+
+static void
+clear_share_rules (NMActRequest *req)
+{
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+ GSList *iter;
+
+ for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) {
+ ShareRule *rule = (ShareRule *) iter->data;
+
+ g_free (rule->table);
+ g_free (rule->rule);
+ g_free (rule);
+ }
+
+ g_slist_free (priv->share_rules);
+ priv->share_rules = NULL;
+}
+
static void
share_child_setup (gpointer user_data G_GNUC_UNUSED)
{
@@ -628,26 +405,236 @@ nm_act_request_add_share_rule (NMActRequest *req,
g_return_if_fail (NM_IS_ACT_REQUEST (req));
g_return_if_fail (table != NULL);
g_return_if_fail (table_rule != NULL);
-
+
rule = g_malloc0 (sizeof (ShareRule));
rule->table = g_strdup (table);
rule->rule = g_strdup (table_rule);
priv->share_rules = g_slist_append (priv->share_rules, rule);
}
-GObject *
-nm_act_request_get_device (NMActRequest *req)
+/********************************************************************/
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ gpointer user_data)
{
- g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
+ NMActRequest *self = NM_ACT_REQUEST (user_data);
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
+ NMActiveConnectionState new_ac_state;
+ gboolean new_default = FALSE, new_default6 = FALSE;
- return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device);
+ /* Set NMActiveConnection state based on the device's state */
+ switch (new_state) {
+ case NM_DEVICE_STATE_PREPARE:
+ case NM_DEVICE_STATE_CONFIG:
+ case NM_DEVICE_STATE_NEED_AUTH:
+ case NM_DEVICE_STATE_IP_CONFIG:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
+ new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING;
+ break;
+ case NM_DEVICE_STATE_ACTIVATED:
+ new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
+ new_default = priv->is_default;
+ new_default6 = priv->is_default6;
+ break;
+ case NM_DEVICE_STATE_DEACTIVATING:
+ new_ac_state = NM_ACTIVE_CONNECTION_STATE_DEACTIVATING;
+ break;
+ default:
+ new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
+ new_default = new_default6 = FALSE;
+ break;
+ }
+
+ if (new_ac_state != priv->state) {
+ priv->state = new_ac_state;
+ g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE);
+ }
+
+ if (new_default != priv->is_default) {
+ priv->is_default = new_default;
+ g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
+ }
+
+ if (new_default6 != priv->is_default6) {
+ priv->is_default6 = new_default6;
+ g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
+ }
}
-gboolean
-nm_act_request_get_assumed (NMActRequest *req)
+/********************************************************************/
+
+NMActRequest *
+nm_act_request_new (NMConnection *connection,
+ const char *specific_object,
+ gboolean user_requested,
+ gulong user_uid,
+ gboolean assumed,
+ gpointer *device)
{
- g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
+ GObject *object;
+ NMActRequestPrivate *priv;
- return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed;
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
+ g_return_val_if_fail (NM_DEVICE (device), NULL);
+
+ object = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
+ if (!object)
+ return NULL;
+
+ priv = NM_ACT_REQUEST_GET_PRIVATE (object);
+
+ priv->connection = g_object_ref (connection);
+ if (specific_object)
+ priv->specific_object = g_strdup (specific_object);
+
+ priv->device = NM_DEVICE (device);
+ g_signal_connect (device, "state-changed",
+ G_CALLBACK (device_state_changed),
+ NM_ACT_REQUEST (object));
+
+ priv->user_uid = user_uid;
+ priv->user_requested = user_requested;
+ priv->assumed = assumed;
+
+ return NM_ACT_REQUEST (object);
+}
+
+static void
+nm_act_request_init (NMActRequest *req)
+{
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
+ NMDBusManager *dbus_mgr;
+
+ priv->ac_path = nm_active_connection_get_next_object_path ();
+ priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
+
+ dbus_mgr = nm_dbus_manager_get ();
+ dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
+ priv->ac_path,
+ G_OBJECT (req));
+ g_object_unref (dbus_mgr);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
+ GPtrArray *devices;
+
+ switch (prop_id) {
+ case PROP_CONNECTION:
+ g_value_set_boxed (value, nm_connection_get_path (priv->connection));
+ break;
+ case PROP_SPECIFIC_OBJECT:
+ if (priv->specific_object)
+ g_value_set_boxed (value, priv->specific_object);
+ else
+ g_value_set_boxed (value, "/");
+ break;
+ case PROP_DEVICES:
+ devices = g_ptr_array_sized_new (1);
+ g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device)));
+ g_value_take_boxed (value, devices);
+ break;
+ case PROP_STATE:
+ g_value_set_uint (value, priv->state);
+ break;
+ case PROP_DEFAULT:
+ g_value_set_boolean (value, priv->is_default);
+ break;
+ case PROP_DEFAULT6:
+ g_value_set_boolean (value, priv->is_default6);
+ break;
+ case PROP_VPN:
+ g_value_set_boolean (value, FALSE);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
+ GSList *iter;
+
+ if (priv->disposed) {
+ G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
+ return;
+ }
+ priv->disposed = TRUE;
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device),
+ G_CALLBACK (device_state_changed),
+ NM_ACT_REQUEST (object));
+
+ /* Clear any share rules */
+ nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
+
+ /* Kill any in-progress secrets requests */
+ g_assert (priv->connection);
+ for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
+ GetSecretsInfo *info = iter->data;
+
+ nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), info->call_id);
+ g_free (info);
+ }
+ g_slist_free (priv->secrets_calls);
+
+ g_object_unref (priv->connection);
+
+ G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object);
+
+ g_free (priv->specific_object);
+ g_free (priv->ac_path);
+
+ clear_share_rules (NM_ACT_REQUEST (object));
+
+ G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
+}
+
+static void
+nm_act_request_class_init (NMActRequestClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (NMActRequestPrivate));
+
+ /* virtual methods */
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ /* properties */
+ nm_active_connection_install_properties (object_class,
+ PROP_CONNECTION,
+ PROP_SPECIFIC_OBJECT,
+ PROP_DEVICES,
+ PROP_STATE,
+ PROP_DEFAULT,
+ PROP_DEFAULT6,
+ PROP_VPN);
+
+ /* Signals */
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class,
+ G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class),
+ &dbus_glib_nm_active_connection_object_info);
}
diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h
index a24369452..dac9d89af 100644
--- a/src/nm-activation-request.h
+++ b/src/nm-activation-request.h
@@ -25,7 +25,7 @@
#include <glib-object.h>
#include "nm-connection.h"
#include "nm-active-connection.h"
-#include "nm-secrets-provider-interface.h"
+#include "nm-settings-flags.h"
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ())
#define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest))
@@ -42,15 +42,6 @@ typedef struct {
GObjectClass parent;
/* Signals */
- void (*secrets_updated) (NMActRequest *req,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller);
- void (*secrets_failed) (NMActRequest *req,
- NMConnection *connection,
- const char *setting,
- RequestSecretsCaller caller);
-
void (*properties_changed) (NMActRequest *req, GHashTable *properties);
} NMActRequestClass;
@@ -59,6 +50,7 @@ GType nm_act_request_get_type (void);
NMActRequest *nm_act_request_new (NMConnection *connection,
const char *specific_object,
gboolean user_requested,
+ gulong user_uid,
gboolean assumed,
gpointer *device); /* An NMDevice */
@@ -92,12 +84,22 @@ GObject * nm_act_request_get_device (NMActRequest *req);
gboolean nm_act_request_get_assumed (NMActRequest *req);
-gboolean nm_act_request_get_secrets (NMActRequest *req,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2);
+/* Secrets handling */
+
+typedef void (*NMActRequestSecretsFunc) (NMActRequest *req,
+ guint32 call_id,
+ NMConnection *connection,
+ GError *error,
+ gpointer user_data);
+
+guint32 nm_act_request_get_secrets (NMActRequest *req,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMActRequestSecretsFunc callback,
+ gpointer callback_data);
+
+void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id);
#endif /* NM_ACTIVATION_REQUEST_H */
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 90495bd2c..2f9a8f97d 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -33,29 +33,7 @@ nm_active_connection_get_next_object_path (void)
}
void
-nm_active_connection_scope_to_value (NMConnection *connection, GValue *value)
-{
- if (!connection) {
- g_value_set_string (value, "");
- return;
- }
-
- switch (nm_connection_get_scope (connection)) {
- case NM_CONNECTION_SCOPE_SYSTEM:
- g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS);
- break;
- case NM_CONNECTION_SCOPE_USER:
- g_value_set_string (value, NM_DBUS_SERVICE_USER_SETTINGS);
- break;
- default:
- nm_log_err (LOGD_CORE, "unknown connection scope!");
- break;
- }
-}
-
-void
nm_active_connection_install_properties (GObjectClass *object_class,
- guint prop_service_name,
guint prop_connection,
guint prop_specific_object,
guint prop_devices,
@@ -64,13 +42,6 @@ nm_active_connection_install_properties (GObjectClass *object_class,
guint prop_default6,
guint prop_vpn)
{
- g_object_class_install_property (object_class, prop_service_name,
- g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME,
- "Service name",
- "Service name",
- NULL,
- G_PARAM_READABLE));
-
g_object_class_install_property (object_class, prop_connection,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION,
"Connection",
@@ -97,7 +68,7 @@ nm_active_connection_install_properties (GObjectClass *object_class,
"State",
"State",
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
- NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
+ NM_ACTIVE_CONNECTION_STATE_DEACTIVATING,
NM_ACTIVE_CONNECTION_STATE_UNKNOWN,
G_PARAM_READABLE));
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index 5dde30875..d39fcbd75 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -24,7 +24,6 @@
#include <glib-object.h>
#include "nm-connection.h"
-#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name"
#define NM_ACTIVE_CONNECTION_CONNECTION "connection"
#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object"
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
@@ -35,10 +34,7 @@
char *nm_active_connection_get_next_object_path (void);
-void nm_active_connection_scope_to_value (NMConnection *connection, GValue *value);
-
void nm_active_connection_install_properties (GObjectClass *object_class,
- guint prop_service_name,
guint prop_connection,
guint prop_specific_object,
guint prop_devices,
diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c
index 9b621b42b..8552f559e 100644
--- a/src/nm-dbus-manager.c
+++ b/src/nm-dbus-manager.c
@@ -105,7 +105,7 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass)
object_class->dispose = nm_dbus_manager_dispose;
signals[DBUS_CONNECTION_CHANGED] =
- g_signal_new ("dbus-connection-changed",
+ g_signal_new (NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMDBusManagerClass, dbus_connection_changed),
@@ -113,7 +113,7 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass)
G_TYPE_NONE, 1, G_TYPE_POINTER);
signals[NAME_OWNER_CHANGED] =
- g_signal_new ("name-owner-changed",
+ g_signal_new (NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMDBusManagerClass, name_owner_changed),
@@ -339,24 +339,6 @@ nm_dbus_manager_start_service (NMDBusManager *self)
return FALSE;
}
- if (!dbus_g_proxy_call (priv->proxy, "RequestName", &err,
- G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
- G_TYPE_INVALID,
- G_TYPE_UINT, &result,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_CORE, "Could not acquire the NetworkManagerSystemSettings service.\n"
- " Message: '%s'", err->message);
- g_error_free (err);
- return FALSE;
- }
-
- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- nm_log_warn (LOGD_CORE, "Could not acquire the NetworkManagerSystemSettings service "
- "as it is already taken.");
- return FALSE;
- }
-
priv->started = TRUE;
return priv->started;
}
diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h
index 275ae4e09..83ffa9667 100644
--- a/src/nm-dbus-manager.h
+++ b/src/nm-dbus-manager.h
@@ -22,7 +22,6 @@
#ifndef __NM_DBUS_MANAGER_H__
#define __NM_DBUS_MANAGER_H__
-#include "config.h"
#include <glib-object.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
@@ -40,6 +39,9 @@ typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection,
#define NM_IS_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DBUS_MANAGER))
#define NM_DBUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass))
+#define NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED "dbus-connection-changed"
+#define NM_DBUS_MANAGER_NAME_OWNER_CHANGED "name-owner-changed"
+
typedef struct {
GObject parent;
} NMDBusManager;
diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c
index 3ef08de8b..c36e0c0ba 100644
--- a/src/nm-device-bt.c
+++ b/src/nm-device-bt.c
@@ -15,12 +15,17 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
*/
+#include "config.h"
+
#include <stdio.h>
#include <string.h>
#include <net/ethernet.h>
+#include <netinet/ether.h>
+
+#include <glib/gi18n.h>
#include "nm-glib-compat.h"
#include "nm-bluez-common.h"
@@ -36,6 +41,8 @@
#include "nm-setting-bluetooth.h"
#include "nm-setting-cdma.h"
#include "nm-setting-gsm.h"
+#include "nm-setting-serial.h"
+#include "nm-setting-ppp.h"
#include "nm-device-bt-glue.h"
#include "NetworkManagerUtils.h"
@@ -46,6 +53,8 @@ G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE)
#define NM_DEVICE_BT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BT, NMDeviceBtPrivate))
+static gboolean modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason);
+
typedef struct {
char *bdaddr;
char *name;
@@ -248,6 +257,147 @@ real_check_connection_compatible (NMDevice *device,
return addr_match;
}
+static gboolean
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
+ NMSettingBluetooth *s_bt;
+ const GByteArray *setting_bdaddr;
+ struct ether_addr *devaddr = ether_aton (priv->bdaddr);
+ const char *ctype;
+ gboolean is_dun = FALSE, is_pan = FALSE;
+ NMSettingGsm *s_gsm;
+ NMSettingCdma *s_cdma;
+ NMSettingSerial *s_serial;
+ NMSettingPPP *s_ppp;
+ const char *format = NULL, *preferred = NULL;
+
+ s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM);
+ s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA);
+ s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL);
+ s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP);
+
+ s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+ if (!s_bt) {
+ s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_bt));
+ }
+
+ ctype = nm_setting_bluetooth_get_connection_type (s_bt);
+ if (ctype) {
+ if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_DUN))
+ is_dun = TRUE;
+ else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_PANU))
+ is_pan = TRUE;
+ } else {
+ if (s_gsm || s_cdma)
+ is_dun = TRUE;
+ else if (priv->capabilities & NM_BT_CAPABILITY_NAP)
+ is_pan = TRUE;
+ }
+
+ if (is_pan) {
+ /* Make sure the device supports PAN */
+ if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ "PAN required but Bluetooth device does not support NAP");
+ return FALSE;
+ }
+
+ /* PAN can't use any DUN-related settings */
+ if (s_gsm || s_cdma || s_serial || s_ppp) {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ "PAN incompatible with GSM, CDMA, or serial settings");
+ return FALSE;
+ }
+
+ g_object_set (G_OBJECT (s_bt),
+ NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
+ NULL);
+
+ format = _("PAN connection %d");
+ } else if (is_dun) {
+ /* Make sure the device supports PAN */
+ if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ "DUN required but Bluetooth device does not support DUN");
+ return FALSE;
+ }
+
+ /* Need at least a GSM or a CDMA setting */
+ if (!s_gsm && !s_cdma) {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ "Setting requires DUN but no GSM or CDMA setting is present");
+ return FALSE;
+ }
+
+ g_object_set (G_OBJECT (s_bt),
+ NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN,
+ NULL);
+
+ if (s_gsm) {
+ format = _("GSM connection %d");
+ if (!nm_setting_gsm_get_number (s_gsm))
+ g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
+ } else if (s_cdma) {
+ format = _("CDMA connection %d");
+ if (!nm_setting_cdma_get_number (s_cdma))
+ g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL);
+ } else
+ format = _("DUN connection %d");
+ } else {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ "Unknown/unhandled Bluetooth connection type");
+ return FALSE;
+ }
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ existing_connections,
+ format,
+ preferred,
+ is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */
+
+ setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
+ if (setting_bdaddr) {
+ /* Make sure the setting BT Address (if any) matches the device's */
+ if (memcmp (setting_bdaddr->data, devaddr->ether_addr_octet, ETH_ALEN)) {
+ g_set_error_literal (error,
+ NM_SETTING_BLUETOOTH_ERROR,
+ NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
+ NM_SETTING_BLUETOOTH_BDADDR);
+ return FALSE;
+ }
+ } else {
+ GByteArray *bdaddr;
+ const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ /* Lock the connection to this device by default */
+ if (memcmp (devaddr->ether_addr_octet, null_mac, ETH_ALEN)) {
+ bdaddr = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bdaddr, devaddr->ether_addr_octet, ETH_ALEN);
+ g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL);
+ g_byte_array_free (bdaddr, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
static guint32
real_get_generic_capabilities (NMDevice *dev)
{
@@ -275,6 +425,8 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
case NM_DEVICE_STATE_ACTIVATED:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
break;
@@ -291,22 +443,30 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
}
static void
-modem_need_auth (NMModem *modem,
- const char *setting_name,
- gboolean retry,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2,
- gpointer user_data)
+modem_auth_requested (NMModem *modem, gpointer user_data)
{
- NMDeviceBt *self = NM_DEVICE_BT (user_data);
- NMActRequest *req;
+ nm_device_state_changed (NM_DEVICE (user_data),
+ NM_DEVICE_STATE_NEED_AUTH,
+ NM_DEVICE_STATE_REASON_NONE);
+}
- req = nm_device_get_act_request (NM_DEVICE (self));
- g_assert (req);
+static void
+modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
+{
+ NMDevice *device = NM_DEVICE (user_data);
+ NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
+ NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
- nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
- nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2);
+ if (error) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_NO_SECRETS);
+ } else {
+ /* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */
+ g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
+ if (!modem_stage1 (NM_DEVICE_BT (device), priv->modem, &reason))
+ nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
+ }
}
static void
@@ -412,41 +572,6 @@ modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason)
return FALSE;
}
-static void
-real_connection_secrets_updated (NMDevice *device,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller)
-{
- NMDeviceBt *self = NM_DEVICE_BT (device);
- NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self);
- NMActRequest *req;
- NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
-
- g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device)));
-
- req = nm_device_get_act_request (device);
- g_assert (req);
-
- if (!nm_modem_connection_secrets_updated (priv->modem,
- req,
- connection,
- updated_settings,
- caller)) {
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
- return;
- }
-
- /* PPP handles stuff itself... */
- if (caller == SECRETS_CALLER_PPP)
- return;
-
- /* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */
- g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
- if (!modem_stage1 (self, priv->modem, &reason))
- nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason);
-}
-
/*****************************************************************************/
gboolean
@@ -511,7 +636,8 @@ nm_device_bt_modem_added (NMDeviceBt *self,
g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self);
- g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self);
+ g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
+ g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);
/* Kick off the modem connection */
if (!modem_stage1 (self, modem, &reason))
@@ -831,7 +957,7 @@ real_act_stage4_get_ip4_config (NMDevice *device,
}
static void
-real_deactivate_quickly (NMDevice *device)
+real_deactivate (NMDevice *device)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
@@ -841,7 +967,7 @@ real_deactivate_quickly (NMDevice *device)
if (priv->bt_type == NM_BT_CAPABILITY_DUN) {
if (priv->modem) {
- nm_modem_deactivate_quickly (priv->modem, device);
+ nm_modem_deactivate (priv->modem, device);
/* Since we're killing the Modem object before it'll get the
* state change signal, simulate the state change here.
@@ -890,8 +1016,8 @@ real_deactivate_quickly (NMDevice *device)
g_free (priv->rfcomm_iface);
priv->rfcomm_iface = NULL;
- if (NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate_quickly)
- NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate_quickly (device);
+ if (NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate)
+ NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate (device);
}
/*****************************************************************************/
@@ -1019,12 +1145,12 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
device_class->get_best_auto_connection = real_get_best_auto_connection;
device_class->get_generic_capabilities = real_get_generic_capabilities;
- device_class->connection_secrets_updated = real_connection_secrets_updated;
- device_class->deactivate_quickly = real_deactivate_quickly;
+ device_class->deactivate = real_deactivate;
device_class->act_stage2_config = real_act_stage2_config;
device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
device_class->check_connection_compatible = real_check_connection_compatible;
+ device_class->complete_connection = real_complete_connection;
/* Properties */
g_object_class_install_property
diff --git a/src/nm-device-cdma.c b/src/nm-device-cdma.c
deleted file mode 100644
index 45771f429..000000000
--- a/src/nm-device-cdma.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-
-#include "nm-modem-cdma.h"
-#include "nm-device-interface.h"
-#include "nm-device-cdma.h"
-#include "nm-properties-changed-signal.h"
-#include "nm-rfkill.h"
-
-#include "nm-device-cdma-glue.h"
-
-G_DEFINE_TYPE (NMDeviceCdma, nm_device_cdma, NM_TYPE_DEVICE_MODEM)
-
-enum {
- PROPERTIES_CHANGED,
- LAST_SIGNAL
-};
-static guint signals[LAST_SIGNAL] = { 0 };
-
-NMDevice *
-nm_device_cdma_new (NMModemCdma *modem, const char *driver)
-{
- g_return_val_if_fail (modem != NULL, NULL);
- g_return_val_if_fail (NM_IS_MODEM_CDMA (modem), NULL);
- g_return_val_if_fail (driver != NULL, NULL);
-
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_CDMA,
- NM_DEVICE_INTERFACE_UDI, nm_modem_get_path (NM_MODEM (modem)),
- NM_DEVICE_INTERFACE_IFACE, nm_modem_get_iface (NM_MODEM (modem)),
- NM_DEVICE_INTERFACE_DRIVER, driver,
- NM_DEVICE_INTERFACE_TYPE_DESC, "CDMA",
- NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_CDMA,
- NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WWAN,
- NM_DEVICE_MODEM_MODEM, modem,
- NULL);
-}
-
-static void
-nm_device_cdma_init (NMDeviceCdma *self)
-{
-}
-
-static void
-nm_device_cdma_class_init (NMDeviceCdmaClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- /* Signals */
- signals[PROPERTIES_CHANGED] =
- nm_properties_changed_signal_new (object_class,
- G_STRUCT_OFFSET (NMDeviceCdmaClass, properties_changed));
-
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
- &dbus_glib_nm_device_cdma_object_info);
-}
-
diff --git a/src/nm-device-cdma.h b/src/nm-device-cdma.h
deleted file mode 100644
index f0bf34567..000000000
--- a/src/nm-device-cdma.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef NM_DEVICE_CDMA_H
-#define NM_DEVICE_CDMA_H
-
-#include "nm-device-modem.h"
-#include "nm-modem-cdma.h"
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_DEVICE_CDMA (nm_device_cdma_get_type ())
-#define NM_DEVICE_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_CDMA, NMDeviceCdma))
-#define NM_DEVICE_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_CDMA, NMDeviceCdmaClass))
-#define NM_IS_DEVICE_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_CDMA))
-#define NM_IS_DEVICE_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_CDMA))
-#define NM_DEVICE_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_CDMA, NMDeviceCdmaClass))
-
-typedef struct {
- NMDeviceModem parent;
-} NMDeviceCdma;
-
-typedef struct {
- NMDeviceModemClass parent;
-
- /* Signals */
- void (*signal_quality) (NMDeviceCdma *self, guint32 quality);
-
- void (*properties_changed) (NMDeviceCdma *self, GHashTable *properties);
-} NMDeviceCdmaClass;
-
-GType nm_device_cdma_get_type (void);
-
-NMDevice *nm_device_cdma_new (NMModemCdma *modem, const char *driver);
-
-G_END_DECLS
-
-#endif /* NM_DEVICE_CDMA_H */
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index c4f62f396..f470e090c 100644
--- a/src/nm-device-ethernet.c
+++ b/src/nm-device-ethernet.c
@@ -15,10 +15,11 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
+#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <netinet/in.h>
@@ -34,7 +35,6 @@
#include <linux/if.h>
#include <errno.h>
-#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include <netlink/route/addr.h>
@@ -78,30 +78,17 @@ typedef enum
#define NM_ETHERNET_ERROR (nm_ethernet_error_quark ())
#define NM_TYPE_ETHERNET_ERROR (nm_ethernet_error_get_type ())
-typedef struct SupplicantStateTask {
- NMDeviceEthernet *self;
- guint32 new_state;
- guint32 old_state;
- gboolean mgr_task;
- guint source_id;
-} SupplicantStateTask;
-
typedef struct Supplicant {
NMSupplicantManager *mgr;
NMSupplicantInterface *iface;
/* signal handler ids */
- guint mgr_state_id;
guint iface_error_id;
guint iface_state_id;
- guint iface_con_state_id;
/* Timeouts and idles */
guint iface_con_error_cb_id;
guint con_timeout_id;
-
- GSList *iface_tasks;
- GSList *mgr_tasks;
} Supplicant;
typedef struct {
@@ -929,67 +916,6 @@ real_get_best_auto_connection (NMDevice *dev,
return NULL;
}
-static void
-real_connection_secrets_updated (NMDevice *dev,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller)
-{
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (dev);
- NMActRequest *req;
- gboolean valid = FALSE;
- GSList *iter;
-
- g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (dev)));
-
- /* PPPoE? */
- if (caller == SECRETS_CALLER_PPP) {
- NMSettingPPPOE *s_pppoe;
-
- g_assert (priv->ppp_manager);
-
- s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
- if (!s_pppoe) {
- nm_ppp_manager_update_secrets (priv->ppp_manager,
- nm_device_get_iface (dev),
- NULL,
- NULL,
- "missing PPPoE setting; no secrets could be found.");
- } else {
- const char *pppoe_username = nm_setting_pppoe_get_username (s_pppoe);
- const char *pppoe_password = nm_setting_pppoe_get_password (s_pppoe);
-
- nm_ppp_manager_update_secrets (priv->ppp_manager,
- nm_device_get_iface (dev),
- pppoe_username ? pppoe_username : "",
- pppoe_password ? pppoe_password : "",
- NULL);
- }
- return;
- }
-
- /* Only caller could be ourselves for 802.1x */
- g_return_if_fail (caller == SECRETS_CALLER_ETHERNET);
- g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
-
- for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
- const char *setting_name = (const char *) iter->data;
-
- if (!strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
- valid = TRUE;
- } else {
- nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.",
- setting_name);
- }
- }
-
- req = nm_device_get_act_request (dev);
- g_assert (req);
-
- g_return_if_fail (nm_act_request_get_connection (req) == connection);
- nm_device_activate_schedule_stage1_device_prepare (dev);
-}
-
/* FIXME: Move it to nm-device.c and then get rid of all foo_device_get_setting() all around.
It's here now to keep the patch short. */
static NMSetting *
@@ -1030,30 +956,6 @@ remove_supplicant_timeouts (NMDeviceEthernet *self)
}
static void
-finish_supplicant_task (SupplicantStateTask *task, gboolean remove_source)
-{
- NMDeviceEthernet *self = task->self;
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
-
- /* idle/timeout handlers should pass FALSE for remove_source, since they
- * will tell glib to remove their source from the mainloop by returning
- * FALSE when they exit. When called from this NMDevice's dispose handler,
- * remove_source should be TRUE to cancel all outstanding idle/timeout
- * handlers asynchronously.
- */
- if (task->source_id && remove_source)
- g_source_remove (task->source_id);
-
- if (task->mgr_task)
- priv->supplicant.mgr_tasks = g_slist_remove (priv->supplicant.mgr_tasks, task);
- else
- priv->supplicant.iface_tasks = g_slist_remove (priv->supplicant.iface_tasks, task);
-
- memset (task, 0, sizeof (SupplicantStateTask));
- g_slice_free (SupplicantStateTask, task);
-}
-
-static void
remove_supplicant_interface_error_handler (NMDeviceEthernet *self)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -1077,32 +979,40 @@ supplicant_interface_release (NMDeviceEthernet *self)
remove_supplicant_timeouts (self);
remove_supplicant_interface_error_handler (self);
- /* Clean up all pending supplicant interface state idle tasks */
- while (priv->supplicant.iface_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
-
- if (priv->supplicant.iface_con_state_id) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_con_state_id);
- priv->supplicant.iface_con_state_id = 0;
- }
-
if (priv->supplicant.iface_state_id > 0) {
g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
priv->supplicant.iface_state_id = 0;
}
- if (priv->supplicant.mgr_state_id) {
- g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
- priv->supplicant.mgr_state_id = 0;
- }
-
if (priv->supplicant.iface) {
nm_supplicant_interface_disconnect (priv->supplicant.iface);
- nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
+ nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
priv->supplicant.iface = NULL;
}
}
+static void
+wired_secrets_cb (NMActRequest *req,
+ guint32 call_id,
+ NMConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ NMDevice *dev = NM_DEVICE (user_data);
+
+ g_return_if_fail (req == nm_device_get_act_request (dev));
+ g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
+ g_return_if_fail (nm_act_request_get_connection (req) == connection);
+
+ if (error) {
+ nm_log_warn (LOGD_ETHER, "%s", error->message);
+ nm_device_state_changed (dev,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_NO_SECRETS);
+ } else
+ nm_device_activate_schedule_stage1_device_prepare (dev);
+}
+
static gboolean
link_timeout_cb (gpointer user_data)
{
@@ -1145,10 +1055,10 @@ link_timeout_cb (gpointer user_data)
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
setting_name,
- TRUE,
- SECRETS_CALLER_ETHERNET,
+ NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW,
NULL,
- NULL);
+ wired_secrets_cb,
+ self);
return FALSE;
@@ -1160,77 +1070,6 @@ time_out:
return FALSE;
}
-static gboolean
-schedule_state_handler (NMDeviceEthernet *self,
- GSourceFunc handler,
- guint32 new_state,
- guint32 old_state,
- gboolean mgr_task)
-{
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
- SupplicantStateTask *task;
-
- if (new_state == old_state)
- return TRUE;
-
- task = g_slice_new0 (SupplicantStateTask);
- if (!task) {
- nm_log_err (LOGD_DEVICE, "Not enough memory to process supplicant manager state change.");
- return FALSE;
- }
-
- task->self = self;
- task->new_state = new_state;
- task->old_state = old_state;
- task->mgr_task = mgr_task;
-
- task->source_id = g_idle_add (handler, task);
- if (mgr_task)
- priv->supplicant.mgr_tasks = g_slist_append (priv->supplicant.mgr_tasks, task);
- else
- priv->supplicant.iface_tasks = g_slist_append (priv->supplicant.iface_tasks, task);
- return TRUE;
-}
-
-static gboolean
-supplicant_mgr_state_cb_handler (gpointer user_data)
-{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDevice *device = NM_DEVICE (task->self);
-
- /* If the supplicant went away, release the supplicant interface */
- if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
- supplicant_interface_release (task->self);
-
- if (nm_device_get_state (device) > NM_DEVICE_STATE_UNAVAILABLE) {
- nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
- }
- }
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-static void
-supplicant_mgr_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data)
-{
- nm_log_info (LOGD_DEVICE | LOGD_ETHER,
- "(%s): supplicant manager state: %s -> %s",
- nm_device_get_iface (NM_DEVICE (user_data)),
- nm_supplicant_manager_state_to_string (old_state),
- nm_supplicant_manager_state_to_string (new_state));
-
- schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
- supplicant_mgr_state_cb_handler,
- new_state,
- old_state,
- TRUE);
-}
-
static NMSupplicantConfig *
build_supplicant_config (NMDeviceEthernet *self)
{
@@ -1257,20 +1096,33 @@ build_supplicant_config (NMDeviceEthernet *self)
return config;
}
-static gboolean
-supplicant_iface_state_cb_handler (gpointer user_data)
+static void
+supplicant_iface_state_cb (NMSupplicantInterface *iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
- NMDevice *device = NM_DEVICE (task->self);
+ NMDeviceEthernet *self = NM_DEVICE_ETHERNET (user_data);
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
+ NMDevice *device = NM_DEVICE (self);
+ NMSupplicantConfig *config;
+ gboolean success = FALSE;
+ NMDeviceState devstate;
+
+ if (new_state == old_state)
+ return;
+
+ nm_log_info (LOGD_DEVICE | LOGD_ETHER,
+ "(%s): supplicant interface state: %s -> %s",
+ nm_device_get_iface (device),
+ nm_supplicant_interface_state_to_string (old_state),
+ nm_supplicant_interface_state_to_string (new_state));
- if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
- NMSupplicantConfig *config;
- const char *iface;
- gboolean success = FALSE;
+ devstate = nm_device_get_state (device);
- iface = nm_device_get_iface (device);
- config = build_supplicant_config (task->self);
+ switch (new_state) {
+ case NM_SUPPLICANT_INTERFACE_STATE_READY:
+ config = build_supplicant_config (self);
if (config) {
success = nm_supplicant_interface_set_config (priv->supplicant.iface, config);
g_object_unref (config);
@@ -1279,99 +1131,54 @@ supplicant_iface_state_cb_handler (gpointer user_data)
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't send security "
"configuration to the supplicant.",
- iface);
+ nm_device_get_iface (device));
}
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): couldn't build security configuration.",
- iface);
+ nm_device_get_iface (device));
}
- if (!success)
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
- } else if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
- NMDeviceState state = nm_device_get_state (device);
-
- supplicant_interface_release (task->self);
-
- if (nm_device_is_activating (device) || state == NM_DEVICE_STATE_ACTIVATED)
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
- }
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-static void
-supplicant_iface_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data)
-{
-
- nm_log_info (LOGD_DEVICE | LOGD_ETHER,
- "(%s): supplicant interface state: %s -> %s",
- nm_device_get_iface (NM_DEVICE (user_data)),
- nm_supplicant_interface_state_to_string (old_state),
- nm_supplicant_interface_state_to_string (new_state));
-
- schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
- supplicant_iface_state_cb_handler,
- new_state,
- old_state,
- FALSE);
-}
-
-static gboolean
-supplicant_iface_connection_state_cb_handler (gpointer user_data)
-{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDevice *dev = NM_DEVICE (task->self);
-
- if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
- remove_supplicant_interface_error_handler (task->self);
- remove_supplicant_timeouts (task->self);
+ if (!success) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED);
+ }
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
+ remove_supplicant_interface_error_handler (self);
+ remove_supplicant_timeouts (self);
/* If this is the initial association during device activation,
* schedule the next activation stage.
*/
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
+ if (devstate == NM_DEVICE_STATE_CONFIG) {
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired) Stage 2 of 5 (Device Configure) successful.",
- nm_device_get_iface (dev));
- nm_device_activate_schedule_stage3_ip_config_start (dev);
+ nm_device_get_iface (device));
+ nm_device_activate_schedule_stage3_ip_config_start (device);
}
- } else if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (task->self);
-
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
+ if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
/* Start the link timeout so we allow some time for reauthentication */
if (!priv->supplicant_timeout_id)
- priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, dev);
+ priv->supplicant_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, device);
}
- }
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-static void
-supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data)
-{
- nm_log_info (LOGD_DEVICE | LOGD_ETHER,
- "(%s) supplicant connection state: %s -> %s",
- nm_device_get_iface (NM_DEVICE (user_data)),
- nm_supplicant_interface_connection_state_to_string (old_state),
- nm_supplicant_interface_connection_state_to_string (new_state));
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
+ supplicant_interface_release (self);
+ remove_supplicant_timeouts (self);
- schedule_state_handler (NM_DEVICE_ETHERNET (user_data),
- supplicant_iface_connection_state_cb_handler,
- new_state,
- old_state,
- FALSE);
+ if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ }
+ break;
+ default:
+ break;
+ }
}
static gboolean
@@ -1429,18 +1236,14 @@ handle_auth_or_fail (NMDeviceEthernet *self,
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) {
- gboolean get_new;
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
/* If the caller doesn't necessarily want completely new secrets,
* only ask for new secrets after the first failure.
*/
- get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
- nm_act_request_get_secrets (req,
- setting_name,
- get_new,
- SECRETS_CALLER_ETHERNET,
- NULL,
- NULL);
+ if (new_secrets || tries)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+ nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self);
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
} else {
@@ -1489,38 +1292,26 @@ supplicant_interface_init (NMDeviceEthernet *self)
iface = nm_device_get_iface (NM_DEVICE (self));
/* Create supplicant interface */
- priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr, iface, FALSE);
+ priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr, iface, FALSE);
if (!priv->supplicant.iface) {
nm_log_err (LOGD_DEVICE | LOGD_ETHER,
"Couldn't initialize supplicant interface for %s.",
iface);
supplicant_interface_release (self);
-
return FALSE;
}
/* Listen for it's state signals */
priv->supplicant.iface_state_id = g_signal_connect (priv->supplicant.iface,
- "state",
- G_CALLBACK (supplicant_iface_state_cb),
- self);
+ "state",
+ G_CALLBACK (supplicant_iface_state_cb),
+ self);
/* Hook up error signal handler to capture association errors */
priv->supplicant.iface_error_id = g_signal_connect (priv->supplicant.iface,
- "connection-error",
- G_CALLBACK (supplicant_iface_connection_error_cb),
- self);
-
- priv->supplicant.iface_con_state_id = g_signal_connect (priv->supplicant.iface,
- "connection-state",
- G_CALLBACK (supplicant_iface_connection_state_cb),
- self);
-
- /* Listen for supplicant manager state changes */
- priv->supplicant.mgr_state_id = g_signal_connect (priv->supplicant.mgr,
- "state",
- G_CALLBACK (supplicant_mgr_state_cb),
- self);
+ "connection-error",
+ G_CALLBACK (supplicant_iface_connection_error_cb),
+ self);
/* Set up a timeout on the connection attempt to fail it after 25 seconds */
priv->supplicant.con_timeout_id = g_timeout_add_seconds (25, supplicant_connection_timeout_cb, self);
@@ -1558,7 +1349,6 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{
NMConnection *connection;
NMSetting8021x *security;
- NMSettingConnection *s_connection;
const char *setting_name;
const char *iface;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
@@ -1572,7 +1362,6 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
}
iface = nm_device_get_iface (NM_DEVICE (self));
- s_connection = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
/* If we need secrets, get them */
setting_name = nm_connection_need_secrets (connection, NULL);
@@ -1581,7 +1370,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): connection '%s' has security, but secrets are required.",
- iface, nm_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
ret = handle_auth_or_fail (self, req, FALSE);
if (ret != NM_ACT_STAGE_RETURN_POSTPONE)
@@ -1589,7 +1378,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
} else {
nm_log_info (LOGD_DEVICE | LOGD_ETHER,
"Activation (%s/wired): connection '%s' requires no security. No secrets needed.",
- iface, nm_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
if (supplicant_interface_init (self))
ret = NM_ACT_STAGE_RETURN_POSTPONE;
@@ -1779,7 +1568,7 @@ real_act_stage4_get_ip4_config (NMDevice *device,
}
static void
-real_deactivate_quickly (NMDevice *device)
+real_deactivate (NMDevice *device)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
@@ -1864,6 +1653,68 @@ real_check_connection_compatible (NMDevice *device,
}
static gboolean
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
+ NMSettingWired *s_wired;
+ NMSettingPPPOE *s_pppoe;
+ const GByteArray *setting_mac;
+
+ s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
+
+ /* We can't telepathically figure out the service name or username, so if
+ * those weren't given, we can't complete the connection.
+ */
+ if (s_pppoe && !nm_setting_verify (NM_SETTING (s_pppoe), NULL, error))
+ return FALSE;
+
+ /* Default to an ethernet-only connection, but if a PPPoE setting was given
+ * then PPPoE should be our connection type.
+ */
+ nm_utils_complete_generic (connection,
+ s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_WIRED_SETTING_NAME,
+ existing_connections,
+ s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"),
+ NULL,
+ s_pppoe ? FALSE : TRUE); /* No IPv6 by default yet for PPPoE */
+
+ s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+ if (!s_wired) {
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+ }
+
+ setting_mac = nm_setting_wired_get_mac_address (s_wired);
+ if (setting_mac) {
+ /* Make sure the setting MAC (if any) matches the device's permanent MAC */
+ if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRED_ERROR,
+ NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ return FALSE;
+ }
+ } else {
+ GByteArray *mac;
+ const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ /* Lock the connection to this device by default */
+ if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) {
+ mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN);
+ g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
+ g_byte_array_free (mac, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
spec_match_list (NMDevice *device, const GSList *specs)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
@@ -1945,7 +1796,6 @@ static gboolean
ip4_match_config (NMDevice *self, NMConnection *connection)
{
NMSettingIP4Config *s_ip4;
- NMSettingConnection *s_con;
struct nl_handle *nlh = NULL;
struct nl_cache *addr_cache = NULL;
int i, num;
@@ -1957,10 +1807,6 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
ifindex = nm_device_get_ifindex (self);
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- g_assert (nm_setting_connection_get_uuid (s_con));
-
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
if (!s_ip4)
return FALSE;
@@ -1979,7 +1825,7 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
dhcp_mgr = nm_dhcp_manager_get ();
leases = nm_dhcp_manager_get_lease_config (dhcp_mgr,
nm_device_get_iface (self),
- nm_setting_connection_get_uuid (s_con));
+ nm_connection_get_uuid (connection));
g_object_unref (dhcp_mgr);
method = nm_setting_ip4_config_get_method (s_ip4);
@@ -2083,12 +1929,6 @@ dispose (GObject *object)
priv->disposed = TRUE;
- /* Clean up all pending supplicant tasks */
- while (priv->supplicant.iface_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
- while (priv->supplicant.mgr_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.mgr_tasks->data, TRUE);
-
if (priv->link_connected_id) {
g_signal_handler_disconnect (priv->monitor, priv->link_connected_id);
priv->link_connected_id = 0;
@@ -2177,14 +2017,14 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->update_initial_hw_address = real_update_initial_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
- parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
+ parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
parent_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
- parent_class->deactivate_quickly = real_deactivate_quickly;
+ parent_class->deactivate = real_deactivate;
parent_class->spec_match_list = spec_match_list;
parent_class->connection_match_config = connection_match_config;
@@ -2317,7 +2157,7 @@ supports_mii_carrier_detect (NMDeviceEthernet *self)
fd = socket (PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
nm_log_err (LOGD_HW, "couldn't open control socket.");
- return 0;
+ return FALSE;
}
memset (&ifr, 0, sizeof (struct ifreq));
diff --git a/src/nm-device-gsm.c b/src/nm-device-gsm.c
deleted file mode 100644
index 2a98a41f4..000000000
--- a/src/nm-device-gsm.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-
-#include "nm-modem-gsm.h"
-#include "nm-device-interface.h"
-#include "nm-device-gsm.h"
-#include "nm-properties-changed-signal.h"
-#include "nm-rfkill.h"
-
-#include "nm-device-gsm-glue.h"
-
-G_DEFINE_TYPE (NMDeviceGsm, nm_device_gsm, NM_TYPE_DEVICE_MODEM)
-
-enum {
- PROPERTIES_CHANGED,
- LAST_SIGNAL
-};
-static guint signals[LAST_SIGNAL] = { 0 };
-
-NMDevice *
-nm_device_gsm_new (NMModemGsm *modem, const char *driver)
-{
- g_return_val_if_fail (modem != NULL, NULL);
- g_return_val_if_fail (NM_IS_MODEM_GSM (modem), NULL);
- g_return_val_if_fail (driver != NULL, NULL);
-
- return (NMDevice *) g_object_new (NM_TYPE_DEVICE_GSM,
- NM_DEVICE_INTERFACE_UDI, nm_modem_get_path (NM_MODEM (modem)),
- NM_DEVICE_INTERFACE_IFACE, nm_modem_get_iface (NM_MODEM (modem)),
- NM_DEVICE_INTERFACE_DRIVER, driver,
- NM_DEVICE_INTERFACE_TYPE_DESC, "GSM",
- NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_GSM,
- NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WWAN,
- NM_DEVICE_MODEM_MODEM, modem,
- NULL);
-}
-
-static void
-nm_device_gsm_init (NMDeviceGsm *self)
-{
-}
-
-static void
-nm_device_gsm_class_init (NMDeviceGsmClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- /* Signals */
- signals[PROPERTIES_CHANGED] =
- nm_properties_changed_signal_new (object_class,
- G_STRUCT_OFFSET (NMDeviceGsmClass, properties_changed));
-
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
- &dbus_glib_nm_device_gsm_object_info);
-}
-
diff --git a/src/nm-device-gsm.h b/src/nm-device-gsm.h
deleted file mode 100644
index 9b403c63a..000000000
--- a/src/nm-device-gsm.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef NM_DEVICE_GSM_H
-#define NM_DEVICE_GSM_H
-
-#include "nm-device-modem.h"
-#include "nm-modem-gsm.h"
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_DEVICE_GSM (nm_device_gsm_get_type ())
-#define NM_DEVICE_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_GSM, NMDeviceGsm))
-#define NM_DEVICE_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_GSM, NMDeviceGsmClass))
-#define NM_IS_DEVICE_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_GSM))
-#define NM_IS_DEVICE_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_GSM))
-#define NM_DEVICE_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_GSM, NMDeviceGsmClass))
-
-typedef struct {
- NMDeviceModem parent;
-} NMDeviceGsm;
-
-typedef struct {
- NMDeviceModemClass parent;
-
- /* Signals */
- void (*signal_quality) (NMDeviceGsm *self, guint32 quality);
-
- void (*properties_changed) (NMDeviceGsm *self, GHashTable *properties);
-} NMDeviceGsmClass;
-
-GType nm_device_gsm_get_type (void);
-
-NMDevice *nm_device_gsm_new (NMModemGsm *modem, const char *driver);
-
-G_END_DECLS
-
-#endif /* NM_DEVICE_GSM_H */
diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c
index eb0e009e2..6d2b8762f 100644
--- a/src/nm-device-interface.c
+++ b/src/nm-device-interface.c
@@ -302,7 +302,6 @@ nm_device_interface_activate (NMDeviceInterface *device,
{
gboolean success;
NMConnection *connection;
- NMSettingConnection *s_con;
char *iface;
g_return_val_if_fail (NM_IS_DEVICE_INTERFACE (device), FALSE);
@@ -310,12 +309,10 @@ nm_device_interface_activate (NMDeviceInterface *device,
connection = nm_act_request_get_connection (req);
g_assert (connection);
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
iface = nm_device_interface_get_iface (device);
nm_log_info (LOGD_DEVICE, "Activation (%s) starting connection '%s'", iface,
- nm_setting_connection_get_id (s_con));
+ nm_connection_get_id (connection));
g_free (iface);
success = NM_DEVICE_INTERFACE_GET_INTERFACE (device)->activate (device, req, error);
diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c
index 441f92cec..076bfa49b 100644
--- a/src/nm-device-modem.c
+++ b/src/nm-device-modem.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
*/
#include <glib.h>
@@ -23,29 +23,38 @@
#include "nm-device-modem.h"
#include "nm-device-interface.h"
#include "nm-modem.h"
+#include "nm-modem-cdma.h"
+#include "nm-modem-gsm.h"
#include "nm-device-private.h"
#include "nm-properties-changed-signal.h"
+#include "nm-rfkill.h"
#include "nm-marshal.h"
#include "nm-logging.h"
static void device_interface_init (NMDeviceInterface *iface_class);
-G_DEFINE_TYPE_EXTENDED (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE, G_TYPE_FLAG_ABSTRACT,
+G_DEFINE_TYPE_EXTENDED (NMDeviceModem, nm_device_modem, NM_TYPE_DEVICE, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init))
#define NM_DEVICE_MODEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MODEM, NMDeviceModemPrivate))
+#include "nm-device-modem-glue.h"
+
typedef struct {
NMModem *modem;
+ NMDeviceModemCapabilities caps;
+ NMDeviceModemCapabilities current_caps;
} NMDeviceModemPrivate;
enum {
PROP_0,
- PROP_MODEM
+ PROP_MODEM,
+ PROP_CAPABILITIES,
+ PROP_CURRENT_CAPABILITIES,
};
enum {
- PPP_STATS,
+ PROPERTIES_CHANGED,
ENABLE_CHANGED,
LAST_SIGNAL
};
@@ -56,15 +65,6 @@ static void real_set_enabled (NMDeviceInterface *device, gboolean enabled);
/*****************************************************************************/
static void
-ppp_stats (NMModem *modem,
- guint32 in_bytes,
- guint32 out_bytes,
- gpointer user_data)
-{
- g_signal_emit (G_OBJECT (user_data), signals[PPP_STATS], 0, in_bytes, out_bytes);
-}
-
-static void
ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
{
NMDevice *device = NM_DEVICE (user_data);
@@ -73,6 +73,8 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data)
case NM_DEVICE_STATE_PREPARE:
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
case NM_DEVICE_STATE_ACTIVATED:
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
break;
@@ -107,22 +109,27 @@ modem_prepare_result (NMModem *modem,
}
static void
-modem_need_auth (NMModem *modem,
- const char *setting_name,
- gboolean retry,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2,
- gpointer user_data)
+modem_auth_requested (NMModem *modem, gpointer user_data)
{
- NMDeviceModem *self = NM_DEVICE_MODEM (user_data);
- NMActRequest *req;
+ nm_device_state_changed (NM_DEVICE (user_data),
+ NM_DEVICE_STATE_NEED_AUTH,
+ NM_DEVICE_STATE_REASON_NONE);
+}
- req = nm_device_get_act_request (NM_DEVICE (self));
- g_assert (req);
+static void
+modem_auth_result (NMModem *modem, GError *error, gpointer user_data)
+{
+ NMDevice *device = NM_DEVICE (user_data);
- nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE);
- nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2);
+ if (error) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_NO_SECRETS);
+ } else {
+ /* Otherwise, on success for modem secrets we need to schedule stage1 again */
+ g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
+ nm_device_activate_schedule_stage1_device_prepare (device);
+ }
}
static void
@@ -205,46 +212,26 @@ real_get_best_auto_connection (NMDevice *device,
return nm_modem_get_best_auto_connection (priv->modem, connections, specific_object);
}
-static void
-real_connection_secrets_updated (NMDevice *device,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller)
+static gboolean
+real_check_connection_compatible (NMDevice *device,
+ NMConnection *connection,
+ GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
- NMActRequest *req;
-
- g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device)));
-
- req = nm_device_get_act_request (device);
- g_assert (req);
- if (!nm_modem_connection_secrets_updated (priv->modem,
- req,
- connection,
- updated_settings,
- caller)) {
- nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
- return;
- }
-
- /* PPP handles stuff itself... */
- if (caller == SECRETS_CALLER_PPP)
- return;
-
- /* Otherwise, on success for modem secrets we need to schedule stage1 again */
- g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH);
- nm_device_activate_schedule_stage1_device_prepare (device);
+ return nm_modem_check_connection_compatible (priv->modem, connection, error);
}
static gboolean
-real_check_connection_compatible (NMDevice *device,
- NMConnection *connection,
- GError **error)
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device);
- return nm_modem_check_connection_compatible (priv->modem, connection, error);
+ return nm_modem_complete_connection (priv->modem, connection, existing_connections, error);
}
static gboolean
@@ -260,9 +247,9 @@ real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
}
static void
-real_deactivate_quickly (NMDevice *device)
+real_deactivate (NMDevice *device)
{
- nm_modem_deactivate_quickly (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device);
+ nm_modem_deactivate (NM_DEVICE_MODEM_GET_PRIVATE (device)->modem, device);
}
static NMActStageReturn
@@ -339,6 +326,40 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled)
/*****************************************************************************/
+NMDevice *
+nm_device_modem_new (NMModem *modem, const char *driver)
+{
+ NMDeviceModemCapabilities caps = NM_DEVICE_MODEM_CAPABILITY_NONE;
+ const char *type_desc = NULL;
+
+ g_return_val_if_fail (modem != NULL, NULL);
+ g_return_val_if_fail (NM_IS_MODEM (modem), NULL);
+ g_return_val_if_fail (driver != NULL, NULL);
+
+ if (NM_IS_MODEM_CDMA (modem)) {
+ caps = NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO;
+ type_desc = "CDMA/EVDO";
+ } else if (NM_IS_MODEM_GSM (modem)) {
+ caps = NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS;
+ type_desc = "GSM/UMTS";
+ } else {
+ nm_log_warn (LOGD_MB, "unhandled modem type %s", G_OBJECT_TYPE_NAME (modem));
+ return NULL;
+ }
+
+ return (NMDevice *) g_object_new (NM_TYPE_DEVICE_MODEM,
+ NM_DEVICE_INTERFACE_UDI, nm_modem_get_path (modem),
+ NM_DEVICE_INTERFACE_IFACE, nm_modem_get_iface (modem),
+ NM_DEVICE_INTERFACE_DRIVER, driver,
+ NM_DEVICE_INTERFACE_TYPE_DESC, type_desc,
+ NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_MODEM,
+ NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WWAN,
+ NM_DEVICE_MODEM_MODEM, modem,
+ NM_DEVICE_MODEM_CAPABILITIES, caps,
+ NM_DEVICE_MODEM_CURRENT_CAPABILITIES, caps,
+ NULL);
+}
+
static void
device_interface_init (NMDeviceInterface *iface_class)
{
@@ -361,11 +382,11 @@ set_modem (NMDeviceModem *self, NMModem *modem)
priv->modem = g_object_ref (modem);
- g_signal_connect (modem, NM_MODEM_PPP_STATS, G_CALLBACK (ppp_stats), self);
g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self);
g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self);
g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self);
- g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self);
+ g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self);
+ g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self);
g_signal_connect (modem, "notify::" NM_MODEM_ENABLED, G_CALLBACK (modem_enabled_cb), self);
}
@@ -373,11 +394,19 @@ static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
+ NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
+
switch (prop_id) {
case PROP_MODEM:
/* construct-only */
set_modem (NM_DEVICE_MODEM (object), g_value_get_object (value));
break;
+ case PROP_CAPABILITIES:
+ priv->caps = g_value_get_uint (value);
+ break;
+ case PROP_CURRENT_CAPABILITIES:
+ priv->current_caps = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -394,6 +423,12 @@ get_property (GObject *object, guint prop_id,
case PROP_MODEM:
g_value_set_object (value, priv->modem);
break;
+ case PROP_CAPABILITIES:
+ g_value_set_uint (value, priv->caps);
+ break;
+ case PROP_CURRENT_CAPABILITIES:
+ g_value_set_uint (value, priv->current_caps);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -426,11 +461,11 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
device_class->get_generic_capabilities = real_get_generic_capabilities;
device_class->get_best_auto_connection = real_get_best_auto_connection;
- device_class->connection_secrets_updated = real_connection_secrets_updated;
device_class->check_connection_compatible = real_check_connection_compatible;
+ device_class->complete_connection = real_complete_connection;
device_class->hw_is_up = real_hw_is_up;
device_class->hw_bring_up = real_hw_bring_up;
- device_class->deactivate_quickly = real_deactivate_quickly;
+ device_class->deactivate = real_deactivate;
device_class->act_stage1_prepare = real_act_stage1_prepare;
device_class->act_stage2_config = real_act_stage2_config;
device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
@@ -445,27 +480,34 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass)
NM_TYPE_MODEM,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
+ g_object_class_install_property (object_class, PROP_CAPABILITIES,
+ g_param_spec_uint (NM_DEVICE_MODEM_CAPABILITIES,
+ "Modem Capabilities",
+ "Modem Capabilities",
+ 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (object_class, PROP_CURRENT_CAPABILITIES,
+ g_param_spec_uint (NM_DEVICE_MODEM_CURRENT_CAPABILITIES,
+ "Current modem Capabilities",
+ "Current modem Capabilities",
+ 0, G_MAXUINT32, NM_DEVICE_MODEM_CAPABILITY_NONE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
/* Signals */
- signals[PPP_STATS] =
- g_signal_new ("ppp-stats",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMDeviceModemClass, ppp_stats),
- NULL, NULL,
- _nm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2,
- G_TYPE_UINT, G_TYPE_UINT);
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class,
+ G_STRUCT_OFFSET (NMDeviceModemClass, properties_changed));
signals[ENABLE_CHANGED] =
g_signal_new (NM_DEVICE_MODEM_ENABLE_CHANGED,
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL,
+ 0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (mclass),
- nm_modem_get_serial_dbus_info ());
+ &dbus_glib_nm_device_modem_object_info);
}
diff --git a/src/nm-device-modem.h b/src/nm-device-modem.h
index c6ef4d218..8453e3d94 100644
--- a/src/nm-device-modem.h
+++ b/src/nm-device-modem.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2010 Red Hat, Inc.
+ * Copyright (C) 2011 Red Hat, Inc.
*/
#ifndef NM_DEVICE_MODEM_H
@@ -35,6 +35,8 @@
#define NM_DEVICE_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MODEM, NMDeviceModemClass))
#define NM_DEVICE_MODEM_MODEM "modem"
+#define NM_DEVICE_MODEM_CAPABILITIES "modem-capabilities"
+#define NM_DEVICE_MODEM_CURRENT_CAPABILITIES "current-capabilities"
#define NM_DEVICE_MODEM_ENABLE_CHANGED "enable-changed"
@@ -45,11 +47,13 @@ typedef struct {
typedef struct {
NMDeviceClass parent;
- void (*ppp_stats) (NMDeviceModem *self, guint32 in_bytes, guint32 out_bytes);
+ void (*properties_changed) (NMDeviceModem *self, GHashTable *properties);
} NMDeviceModemClass;
GType nm_device_modem_get_type (void);
+NMDevice *nm_device_modem_new (NMModem *modem, const char *driver);
+
/* Private for subclases */
NMModem *nm_device_modem_get_modem (NMDeviceModem *self);
diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c
index 546ecfafe..8c8f9d0db 100644
--- a/src/nm-device-olpc-mesh.c
+++ b/src/nm-device-olpc-mesh.c
@@ -19,11 +19,12 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * (C) Copyright 2005 - 2010 Red Hat, Inc.
+ * (C) Copyright 2005 - 2011 Red Hat, Inc.
* (C) Copyright 2008 Collabora Ltd.
* (C) Copyright 2009 One Laptop per Child
*/
+#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <dbus/dbus.h>
@@ -381,6 +382,51 @@ real_check_connection_compatible (NMDevice *device,
return TRUE;
}
+#define DEFAULT_SSID "olpc-mesh"
+
+static gboolean
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMSettingOlpcMesh *s_mesh;
+ GByteArray *tmp;
+
+ s_mesh = (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH);
+ if (!s_mesh) {
+ s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_mesh));
+ }
+
+ if (!nm_setting_olpc_mesh_get_ssid (s_mesh)) {
+ tmp = g_byte_array_sized_new (strlen (DEFAULT_SSID));
+ g_byte_array_append (tmp, (const guint8 *) DEFAULT_SSID, strlen (DEFAULT_SSID));
+ g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, tmp, NULL);
+ g_byte_array_free (tmp, TRUE);
+ }
+
+ if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) {
+ const guint8 anycast[ETH_ALEN] = { 0xC0, 0x27, 0xC0, 0x27, 0xC0, 0x27 };
+
+ tmp = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (tmp, anycast, sizeof (anycast));
+ g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, tmp, NULL);
+ g_byte_array_free (tmp, TRUE);
+
+ }
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_OLPC_MESH_SETTING_NAME,
+ existing_connections,
+ _("Mesh %d"),
+ NULL,
+ FALSE); /* No IPv6 by default */
+
+ return TRUE;
+}
+
/*
* nm_device_olpc_mesh_get_address
*
@@ -652,7 +698,7 @@ dispose (GObject *object)
device_cleanup (self);
- manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
if (priv->device_added_id)
g_signal_handler_disconnect (manager, priv->device_added_id);
g_object_unref (manager);
@@ -722,6 +768,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
parent_class->take_down = real_take_down;
parent_class->update_hw_address = real_update_hw_address;
parent_class->check_connection_compatible = real_check_connection_compatible;
+ parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
@@ -812,7 +859,7 @@ companion_scan_allowed_cb (NMDeviceWifi *companion, gpointer user_data)
g_object_get (G_OBJECT (self), NM_DEVICE_INTERFACE_STATE, &state, NULL);
- /* Don't allow the companion to scan while configure the mesh interface */
+ /* Don't allow the companion to scan while configuring the mesh interface */
return (state < NM_DEVICE_STATE_PREPARE) || (state > NM_DEVICE_STATE_IP_CONFIG);
}
@@ -850,7 +897,7 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other)
priv->companion = other;
/* When we've found the companion, stop listening for other devices */
- manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
if (priv->device_added_id) {
g_signal_handler_disconnect (manager, priv->device_added_id);
priv->device_added_id = 0;
@@ -905,7 +952,7 @@ check_companion_cb (gpointer user_data)
if (priv->device_added_id != 0)
return FALSE;
- manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
priv->device_added_id = g_signal_connect (manager, "device-added",
G_CALLBACK (device_added_cb), self);
diff --git a/src/nm-device-private.h b/src/nm-device-private.h
index f4f968a94..a7d238b10 100644
--- a/src/nm-device-private.h
+++ b/src/nm-device-private.h
@@ -16,7 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
*/
#ifndef NM_DEVICE_PRIVATE_H
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index 2e278c7c7..626c2c0db 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -104,43 +104,18 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-typedef enum {
- NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0,
- NM_WIFI_ERROR_CONNECTION_INVALID,
- NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
-} NMWifiError;
-
-#define NM_WIFI_ERROR (nm_wifi_error_quark ())
-#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
-
-typedef struct SupplicantStateTask {
- NMDeviceWifi *self;
- guint32 new_state;
- guint32 old_state;
- gboolean mgr_task;
- guint source_id;
-} SupplicantStateTask;
+#define SUP_SIG_ID_LEN 5
typedef struct Supplicant {
NMSupplicantManager *mgr;
NMSupplicantInterface *iface;
- /* signal handler ids */
- guint mgr_state_id;
+ guint sig_ids[SUP_SIG_ID_LEN];
guint iface_error_id;
- guint iface_state_id;
- guint iface_scanned_ap_id;
- guint iface_scan_request_result_id;
- guint iface_scan_results_id;
- guint iface_con_state_id;
- guint iface_notify_scanning_id;
/* Timeouts and idles */
guint iface_con_error_cb_id;
guint con_timeout_id;
-
- GSList *mgr_tasks;
- GSList *iface_tasks;
} Supplicant;
struct _NMDeviceWifiPrivate {
@@ -191,40 +166,23 @@ static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
static void cancel_pending_scan (NMDeviceWifi *self);
-static int wireless_qual_to_percent (const struct iw_quality *qual,
- const struct iw_quality *max_qual);
-
static void cleanup_association_attempt (NMDeviceWifi * self,
gboolean disconnect);
static void remove_supplicant_timeouts (NMDeviceWifi *self);
-static void supplicant_iface_state_cb (NMSupplicantInterface * iface,
+static void supplicant_iface_state_cb (NMSupplicantInterface *iface,
guint32 new_state,
guint32 old_state,
- NMDeviceWifi *self);
-
-static void supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- NMDeviceWifi *self);
-
-static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
- GHashTable *properties,
- NMDeviceWifi * self);
+ gpointer user_data);
-static void supplicant_iface_scan_request_result_cb (NMSupplicantInterface * iface,
- gboolean success,
- NMDeviceWifi * self);
+static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface,
+ GHashTable *properties,
+ NMDeviceWifi * self);
-static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface,
- guint32 num_bssids,
- NMDeviceWifi * self);
-
-static void supplicant_mgr_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- NMDeviceWifi *self);
+static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface,
+ gboolean success,
+ NMDeviceWifi * self);
static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface,
GParamSpec * pspec,
@@ -234,6 +192,18 @@ static guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self);
static void cull_scan_list (NMDeviceWifi *self);
+/*****************************************************************/
+
+typedef enum {
+ NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0,
+ NM_WIFI_ERROR_CONNECTION_INVALID,
+ NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
+ NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND,
+} NMWifiError;
+
+#define NM_WIFI_ERROR (nm_wifi_error_quark ())
+#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ())
+
static GQuark
nm_wifi_error_quark (void)
{
@@ -259,6 +229,8 @@ nm_wifi_error_get_type (void)
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
/* Connection does not apply to this device. */
ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
+ /* Given access point was not in this device's scan list. */
+ ENUM_ENTRY (NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "AccessPointNotFound"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMWifiError", values);
@@ -266,6 +238,8 @@ nm_wifi_error_get_type (void)
return etype;
}
+/*****************************************************************/
+
/* IPW rfkill handling (until 2.6.33) */
RfKillState
nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self)
@@ -324,6 +298,109 @@ ipw_rfkill_state_work (gpointer user_data)
return TRUE;
}
+/*****************************************************************/
+
+/*
+ * wireless_qual_to_percent
+ *
+ * Convert an iw_quality structure from SIOCGIWSTATS into a magical signal
+ * strength percentage.
+ *
+ */
+static int
+wireless_qual_to_percent (const struct iw_quality *qual,
+ const struct iw_quality *max_qual)
+{
+ int percent = -1;
+ int level_percent = -1;
+
+ g_return_val_if_fail (qual != NULL, -1);
+ g_return_val_if_fail (max_qual != NULL, -1);
+
+ nm_log_dbg (LOGD_WIFI,
+ "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X",
+ (__s8) qual->qual, qual->qual, qual->qual,
+ (__s8) qual->level, qual->level, qual->level,
+ (__s8) qual->noise, qual->noise, qual->noise,
+ qual->updated,
+ (__s8) max_qual->qual, max_qual->qual, max_qual->qual,
+ (__s8) max_qual->level, max_qual->level, max_qual->level,
+ (__s8) max_qual->noise, max_qual->noise, max_qual->noise,
+ max_qual->updated);
+
+ /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is.
+ * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be
+ * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers
+ * are free to use whatever they want to calculate "Link Quality".
+ */
+ if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
+ percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
+
+ /* If the driver doesn't specify a complete and valid quality, we have two options:
+ *
+ * 1) dBm: driver must specify max_qual->level = 0, and have valid values for
+ * qual->level and (qual->noise OR max_qual->noise)
+ * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for
+ * qual->level and max_qual->level
+ *
+ * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise,
+ * If drivers don't conform to it, they are wrong and need to be fixed.
+ */
+
+ if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */
+ && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */
+ && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */
+ || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */
+ ) {
+ /* Absolute power values (dBm) */
+
+ /* Reasonable fallbacks for dumb drivers that don't specify either level. */
+ #define FALLBACK_NOISE_FLOOR_DBM -90
+ #define FALLBACK_SIGNAL_MAX_DBM -20
+ int max_level = FALLBACK_SIGNAL_MAX_DBM;
+ int noise = FALLBACK_NOISE_FLOOR_DBM;
+ int level = qual->level - 0x100;
+
+ level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
+
+ if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))
+ noise = qual->noise - 0x100;
+ else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID))
+ noise = max_qual->noise - 0x100;
+ noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
+
+ /* A sort of signal-to-noise ratio calculation */
+ level_percent = (int)(100 - 70 *(
+ ((double)max_level - (double)level) /
+ ((double)max_level - (double)noise)));
+ nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.",
+ level_percent, max_level, level, noise);
+ } else if ( (max_qual->level != 0)
+ && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */
+ && !(qual->updated & IW_QUAL_LEVEL_INVALID)) {
+ /* Relative power values (RSSI) */
+
+ int level = qual->level;
+
+ /* Signal level is relavtive (0 -> max_qual->level) */
+ level = CLAMP (level, 0, max_qual->level);
+ level_percent = (int)(100 * ((double)level / (double)max_qual->level));
+ nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.",
+ level_percent, max_qual->level, level);
+ } else if (percent == -1) {
+ nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy.");
+ }
+
+ /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
+ if ((percent < 1) && (level_percent >= 0))
+ percent = level_percent;
+
+ nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).",
+ percent, CLAMP (percent, 0, 100));
+ return (CLAMP (percent, 0, 100));
+}
+
+
/*
* nm_device_wifi_update_signal_strength
*
@@ -625,10 +702,7 @@ constructor (GType type,
/* Connect to the supplicant manager */
priv->supplicant.mgr = nm_supplicant_manager_get ();
- priv->supplicant.mgr_state_id = g_signal_connect (priv->supplicant.mgr,
- "state",
- G_CALLBACK (supplicant_mgr_state_cb),
- self);
+ g_assert (priv->supplicant.mgr);
/* The ipw2x00 drivers don't integrate with the kernel rfkill subsystem until
* 2.6.33. Thus all our nice libgudev magic is useless. So we get to poll.
@@ -657,17 +731,13 @@ static gboolean
supplicant_interface_acquire (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- guint id, mgr_state;
+ guint id, i = 0;
g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (priv->supplicant.mgr != NULL, FALSE);
/* interface already acquired? */
g_return_val_if_fail (priv->supplicant.iface == NULL, TRUE);
- mgr_state = nm_supplicant_manager_get_state (priv->supplicant.mgr);
- g_return_val_if_fail (mgr_state == NM_SUPPLICANT_MANAGER_STATE_IDLE, FALSE);
-
- priv->supplicant.iface = nm_supplicant_manager_get_iface (priv->supplicant.mgr,
+ priv->supplicant.iface = nm_supplicant_manager_iface_get (priv->supplicant.mgr,
nm_device_get_iface (NM_DEVICE (self)),
TRUE);
if (priv->supplicant.iface == NULL) {
@@ -676,70 +746,36 @@ supplicant_interface_acquire (NMDeviceWifi *self)
return FALSE;
}
- id = g_signal_connect (priv->supplicant.iface,
- "state",
- G_CALLBACK (supplicant_iface_state_cb),
- self);
- priv->supplicant.iface_state_id = id;
+ memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids));
id = g_signal_connect (priv->supplicant.iface,
- "scanned-ap",
- G_CALLBACK (supplicant_iface_scanned_ap_cb),
- self);
- priv->supplicant.iface_scanned_ap_id = id;
-
- id = g_signal_connect (priv->supplicant.iface,
- "scan-req-result",
- G_CALLBACK (supplicant_iface_scan_request_result_cb),
+ NM_SUPPLICANT_INTERFACE_STATE,
+ G_CALLBACK (supplicant_iface_state_cb),
self);
- priv->supplicant.iface_scan_request_result_id = id;
+ priv->supplicant.sig_ids[i++] = id;
id = g_signal_connect (priv->supplicant.iface,
- "scan-results",
- G_CALLBACK (supplicant_iface_scan_results_cb),
+ NM_SUPPLICANT_INTERFACE_NEW_BSS,
+ G_CALLBACK (supplicant_iface_new_bss_cb),
self);
- priv->supplicant.iface_scan_results_id = id;
+ priv->supplicant.sig_ids[i++] = id;
id = g_signal_connect (priv->supplicant.iface,
- "connection-state",
- G_CALLBACK (supplicant_iface_connection_state_cb),
+ NM_SUPPLICANT_INTERFACE_SCAN_DONE,
+ G_CALLBACK (supplicant_iface_scan_done_cb),
self);
- priv->supplicant.iface_con_state_id = id;
+ priv->supplicant.sig_ids[i++] = id;
id = g_signal_connect (priv->supplicant.iface,
"notify::scanning",
G_CALLBACK (supplicant_iface_notify_scanning_cb),
self);
- priv->supplicant.iface_notify_scanning_id = id;
+ priv->supplicant.sig_ids[i++] = id;
return TRUE;
}
static void
-finish_supplicant_task (SupplicantStateTask *task, gboolean remove_source)
-{
- NMDeviceWifi *self = task->self;
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- /* idle/timeout handlers should pass FALSE for remove_source, since they
- * will tell glib to remove their source from the mainloop by returning
- * FALSE when they exit. When called from this NMDevice's dispose handler,
- * remove_source should be TRUE to cancel all outstanding idle/timeout
- * handlers asynchronously.
- */
- if (task->source_id && remove_source)
- g_source_remove (task->source_id);
-
- if (task->mgr_task)
- priv->supplicant.mgr_tasks = g_slist_remove (priv->supplicant.mgr_tasks, task);
- else
- priv->supplicant.iface_tasks = g_slist_remove (priv->supplicant.iface_tasks, task);
-
- memset (task, 0, sizeof (SupplicantStateTask));
- g_slice_free (SupplicantStateTask, task);
-}
-
-static void
remove_supplicant_interface_error_handler (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
@@ -762,6 +798,7 @@ static void
supplicant_interface_release (NMDeviceWifi *self)
{
NMDeviceWifiPrivate *priv;
+ guint i;
g_return_if_fail (self != NULL);
@@ -777,49 +814,36 @@ supplicant_interface_release (NMDeviceWifi *self)
remove_supplicant_interface_error_handler (self);
- /* Clean up all pending supplicant interface state idle tasks */
- while (priv->supplicant.iface_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
-
- if (priv->supplicant.iface_state_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_state_id);
- priv->supplicant.iface_state_id = 0;
- }
-
- if (priv->supplicant.iface_scanned_ap_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scanned_ap_id);
- priv->supplicant.iface_scanned_ap_id = 0;
- }
-
- if (priv->supplicant.iface_scan_request_result_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_request_result_id);
- priv->supplicant.iface_scan_request_result_id = 0;
- }
-
- if (priv->supplicant.iface_scan_results_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_scan_results_id);
- priv->supplicant.iface_scan_results_id = 0;
- }
-
- if (priv->supplicant.iface_con_state_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_con_state_id);
- priv->supplicant.iface_con_state_id = 0;
- }
-
- if (priv->supplicant.iface_notify_scanning_id > 0) {
- g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.iface_notify_scanning_id);
- priv->supplicant.iface_notify_scanning_id = 0;
+ /* Clear supplicant interface signal handlers */
+ for (i = 0; i < SUP_SIG_ID_LEN; i++) {
+ if (priv->supplicant.sig_ids[i] > 0)
+ g_signal_handler_disconnect (priv->supplicant.iface, priv->supplicant.sig_ids[i]);
}
+ memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids));
if (priv->supplicant.iface) {
/* Tell the supplicant to disconnect from the current AP */
nm_supplicant_interface_disconnect (priv->supplicant.iface);
- nm_supplicant_manager_release_iface (priv->supplicant.mgr, priv->supplicant.iface);
+ nm_supplicant_manager_iface_release (priv->supplicant.mgr, priv->supplicant.iface);
priv->supplicant.iface = NULL;
}
}
+
+static NMAccessPoint *
+get_ap_by_path (NMDeviceWifi *self, const char *path)
+{
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
+ if (strcmp (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0)
+ return NM_AP (iter->data);
+ }
+ return NULL;
+}
+
static NMAccessPoint *
get_active_ap (NMDeviceWifi *self,
NMAccessPoint *ignore_ap,
@@ -1226,7 +1250,7 @@ real_take_down (NMDevice *dev)
}
static void
-real_deactivate_quickly (NMDevice *dev)
+real_deactivate (NMDevice *dev)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
@@ -1262,16 +1286,11 @@ real_deactivate_quickly (NMDevice *dev)
/* Reset MAC address back to initial address */
_set_hw_addr (self, priv->initial_hw_addr, "reset");
-}
-
-static void
-real_deactivate (NMDevice *dev)
-{
- NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
+ /* Ensure we're in infrastructure mode after deactivation; some devices
+ * (usually older ones) don't scan well in adhoc mode.
+ */
nm_device_wifi_set_mode (self, NM_802_11_MODE_INFRA);
- /* FIXME: Should we reset the scan interval here? */
-/* nm_device_wifi_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); */
}
static gboolean
@@ -1318,6 +1337,170 @@ real_check_connection_compatible (NMDevice *device,
return TRUE;
}
+/*
+ * List of manufacturer default SSIDs that are often unchanged by users.
+ *
+ * NOTE: this list should *not* contain networks that you would like to
+ * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot".
+ */
+static const char *
+manf_defaults[] = {
+ "linksys",
+ "linksys-a",
+ "linksys-g",
+ "default",
+ "belkin54g",
+ "NETGEAR",
+ "o2DSL",
+ "WLAN",
+ "ALICE-WLAN",
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
+
+static gboolean
+is_manf_default_ssid (const GByteArray *ssid)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE (manf_defaults); i++) {
+ if (ssid->len == strlen (manf_defaults[i])) {
+ if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMDeviceWifi *self = NM_DEVICE_WIFI (device);
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ const GByteArray *setting_mac;
+ char *format, *str_ssid = NULL;
+ NMAccessPoint *ap = NULL;
+ const GByteArray *ssid = NULL;
+ GSList *iter;
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+
+ if (!specific_object) {
+ /* If not given a specific object, we need at minimum an SSID */
+ if (!s_wifi) {
+ g_set_error_literal (error,
+ NM_WIFI_ERROR,
+ NM_WIFI_ERROR_CONNECTION_INVALID,
+ "A 'wireless' setting is required if no AP path was given.");
+ return FALSE;
+ }
+
+ ssid = nm_setting_wireless_get_ssid (s_wifi);
+ if (!ssid || !ssid->len) {
+ g_set_error_literal (error,
+ NM_WIFI_ERROR,
+ NM_WIFI_ERROR_CONNECTION_INVALID,
+ "A 'wireless' setting with a valid SSID is required if no AP path was given.");
+ return FALSE;
+ }
+
+ /* Find a compatible AP in the scan list */
+ for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
+ if (nm_ap_check_compatible (NM_AP (iter->data), connection)) {
+ ap = NM_AP (iter->data);
+ break;
+ }
+ }
+
+ /* If we still don't have an AP, then the WiFI settings needs to be
+ * fully specified by the client. Might not be able to find an AP
+ * if the network isn't broadcasting the SSID for example.
+ */
+ if (!ap) {
+ GSList *settings = NULL;
+ gboolean valid;
+
+ settings = g_slist_prepend (settings, s_wifi);
+ settings = g_slist_prepend (settings, s_wsec);
+ settings = g_slist_prepend (settings, s_8021x);
+ valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error);
+ g_slist_free (settings);
+ if (!valid)
+ return FALSE;
+ }
+ } else {
+ ap = get_ap_by_path (self, specific_object);
+ if (!ap) {
+ g_set_error (error,
+ NM_WIFI_ERROR,
+ NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND,
+ "The access point %s was not in the scan list.",
+ specific_object);
+ return FALSE;
+ }
+ }
+
+ if (ap) {
+ ssid = nm_ap_get_ssid (ap);
+
+ /* If the SSID is a well-known SSID, lock the connection to the AP's
+ * specific BSSID so NM doesn't autoconnect to some random wifi net.
+ */
+ if (!nm_ap_complete_connection (ap,
+ connection,
+ is_manf_default_ssid (ssid),
+ error))
+ return FALSE;
+ }
+
+ g_assert (ssid);
+ str_ssid = nm_utils_ssid_to_utf8 (ssid);
+ format = g_strdup_printf ("%s %%d", str_ssid);
+
+ nm_utils_complete_generic (connection,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ existing_connections,
+ format,
+ str_ssid,
+ TRUE);
+ g_free (str_ssid);
+ g_free (format);
+
+ setting_mac = nm_setting_wireless_get_mac_address (s_wifi);
+ if (setting_mac) {
+ /* Make sure the setting MAC (if any) matches the device's permanent MAC */
+ if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_ERROR,
+ NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ return FALSE;
+ }
+ } else {
+ GByteArray *mac;
+ const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ /* Lock the connection to this device by default */
+ if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) {
+ mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN);
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL);
+ g_byte_array_free (mac, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
static gboolean
real_is_available (NMDevice *dev)
{
@@ -1591,107 +1774,6 @@ nm_device_wifi_get_frequency (NMDeviceWifi *self)
}
/*
- * wireless_stats_to_percent
- *
- * Convert an iw_stats structure from a scan or the card into
- * a magical signal strength percentage.
- *
- */
-static int
-wireless_qual_to_percent (const struct iw_quality *qual,
- const struct iw_quality *max_qual)
-{
- int percent = -1;
- int level_percent = -1;
-
- g_return_val_if_fail (qual != NULL, -1);
- g_return_val_if_fail (max_qual != NULL, -1);
-
- nm_log_dbg (LOGD_WIFI,
- "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X",
- (__s8) qual->qual, qual->qual, qual->qual,
- (__s8) qual->level, qual->level, qual->level,
- (__s8) qual->noise, qual->noise, qual->noise,
- qual->updated,
- (__s8) max_qual->qual, max_qual->qual, max_qual->qual,
- (__s8) max_qual->level, max_qual->level, max_qual->level,
- (__s8) max_qual->noise, max_qual->noise, max_qual->noise,
- max_qual->updated);
-
- /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is.
- * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be
- * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers
- * are free to use whatever they want to calculate "Link Quality".
- */
- if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
- percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
-
- /* If the driver doesn't specify a complete and valid quality, we have two options:
- *
- * 1) dBm: driver must specify max_qual->level = 0, and have valid values for
- * qual->level and (qual->noise OR max_qual->noise)
- * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for
- * qual->level and max_qual->level
- *
- * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise,
- * If drivers don't conform to it, they are wrong and need to be fixed.
- */
-
- if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */
- && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */
- && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */
- || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */
- ) {
- /* Absolute power values (dBm) */
-
- /* Reasonable fallbacks for dumb drivers that don't specify either level. */
- #define FALLBACK_NOISE_FLOOR_DBM -90
- #define FALLBACK_SIGNAL_MAX_DBM -20
- int max_level = FALLBACK_SIGNAL_MAX_DBM;
- int noise = FALLBACK_NOISE_FLOOR_DBM;
- int level = qual->level - 0x100;
-
- level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
-
- if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))
- noise = qual->noise - 0x100;
- else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID))
- noise = max_qual->noise - 0x100;
- noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
-
- /* A sort of signal-to-noise ratio calculation */
- level_percent = (int)(100 - 70 *(
- ((double)max_level - (double)level) /
- ((double)max_level - (double)noise)));
- nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.",
- level_percent, max_level, level, noise);
- } else if ( (max_qual->level != 0)
- && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */
- && !(qual->updated & IW_QUAL_LEVEL_INVALID)) {
- /* Relative power values (RSSI) */
-
- int level = qual->level;
-
- /* Signal level is relavtive (0 -> max_qual->level) */
- level = CLAMP (level, 0, max_qual->level);
- level_percent = (int)(100 * ((double)level / (double)max_qual->level));
- nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.",
- level_percent, max_qual->level, level);
- } else if (percent == -1) {
- nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy.");
- }
-
- /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
- if ((percent < 1) && (level_percent >= 0))
- percent = level_percent;
-
- nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).",
- percent, CLAMP (percent, 0, 100));
- return (CLAMP (percent, 0, 100));
-}
-
-
-/*
* nm_device_wifi_get_ssid
*
* If a device is wireless, return the ssid that it is attempting
@@ -1828,6 +1910,9 @@ scanning_allowed (NMDeviceWifi *self)
case NM_DEVICE_STATE_CONFIG:
case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
+ case NM_DEVICE_STATE_DEACTIVATING:
/* Don't scan when unusable or activating */
return FALSE;
case NM_DEVICE_STATE_DISCONNECTED:
@@ -1840,11 +1925,11 @@ scanning_allowed (NMDeviceWifi *self)
}
/* Don't scan if the supplicant is busy */
- sup_state = nm_supplicant_interface_get_connection_state (priv->supplicant.iface);
- if ( sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING
- || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED
- || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE
- || sup_state == NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE
+ sup_state = nm_supplicant_interface_get_state (priv->supplicant.iface);
+ if ( sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING
+ || sup_state == NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED
+ || sup_state == NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE
+ || sup_state == NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE
|| nm_supplicant_interface_get_scanning (priv->supplicant.iface))
return FALSE;
@@ -2000,28 +2085,19 @@ cancel_pending_scan (NMDeviceWifi *self)
}
}
-
static void
-supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface,
- gboolean success,
- NMDeviceWifi *self)
+supplicant_iface_scan_done_cb (NMSupplicantInterface *iface,
+ gboolean success,
+ NMDeviceWifi *self)
{
- nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan request %s",
+ nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan %s",
nm_device_get_iface (NM_DEVICE (self)),
success ? "successful" : "failed");
if (check_scanning_allowed (self))
schedule_scan (self, TRUE);
-}
-static void
-supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
- guint32 num_results,
- NMDeviceWifi *self)
-{
- nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan results available (%d APs found)",
- nm_device_get_iface (NM_DEVICE (self)),
- num_results);
+#if 0
if (num_results == 0) {
/* ensure that old APs get culled, which otherwise only
* happens when there are actual scan results to process.
@@ -2029,6 +2105,7 @@ supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
cull_scan_list (self);
nm_device_wifi_ap_list_print (self);
}
+#endif
}
static gboolean
@@ -2248,48 +2325,10 @@ cull_scan_list (NMDeviceWifi *self)
removed, total);
}
-#define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \
- if (lc_member != -1) { \
- qual_item.lc_member = lc_member; \
- qual_item.updated |= IW_QUAL_##uc_member##_UPDATED; \
- } else { \
- qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \
- }
-
-static void
-set_ap_strength_from_properties (NMDeviceWifi *self,
- NMAccessPoint *ap,
- GHashTable *properties)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- int qual, level, noise;
- struct iw_quality quality;
- GValue *value;
- gint8 strength;
-
- value = (GValue *) g_hash_table_lookup (properties, "quality");
- qual = value ? g_value_get_int (value) : -1;
-
- value = (GValue *) g_hash_table_lookup (properties, "level");
- level = value ? g_value_get_int (value) : -1;
-
- value = (GValue *) g_hash_table_lookup (properties, "noise");
- noise = value ? g_value_get_int (value) : -1;
-
- /* Calculate and set the AP's signal quality */
- memset (&quality, 0, sizeof (struct iw_quality));
- SET_QUALITY_MEMBER (quality, qual, QUAL);
- SET_QUALITY_MEMBER (quality, level, LEVEL);
- SET_QUALITY_MEMBER (quality, noise, NOISE);
-
- strength = wireless_qual_to_percent (&quality, &priv->max_qual);
- nm_ap_set_strength (ap, strength);
-}
-
static void
-supplicant_iface_scanned_ap_cb (NMSupplicantInterface *iface,
- GHashTable *properties,
- NMDeviceWifi *self)
+supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
+ GHashTable *properties,
+ NMDeviceWifi *self)
{
NMDeviceState state;
NMAccessPoint *ap;
@@ -2305,8 +2344,6 @@ supplicant_iface_scanned_ap_cb (NMSupplicantInterface *iface,
ap = nm_ap_new_from_properties (properties);
if (ap) {
- set_ap_strength_from_properties (self, ap, properties);
-
nm_ap_print_self (ap, "AP: ");
/* Add the AP to the device's AP list */
@@ -2335,6 +2372,27 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect)
nm_supplicant_interface_disconnect (priv->supplicant.iface);
}
+static void
+wifi_secrets_cb (NMActRequest *req,
+ guint32 call_id,
+ NMConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ NMDevice *dev = NM_DEVICE (user_data);
+
+ g_return_if_fail (req == nm_device_get_act_request (dev));
+ g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH);
+ g_return_if_fail (nm_act_request_get_connection (req) == connection);
+
+ if (error) {
+ nm_log_warn (LOGD_WIFI, "%s", error->message);
+ nm_device_state_changed (dev,
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_NO_SECRETS);
+ } else
+ nm_device_activate_schedule_stage1_device_prepare (dev);
+}
static void
remove_link_timeout (NMDeviceWifi *self)
@@ -2431,10 +2489,10 @@ link_timeout_cb (gpointer user_data)
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
nm_act_request_get_secrets (req,
setting_name,
- TRUE,
- SECRETS_CALLER_WIFI,
+ NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW,
NULL,
- NULL);
+ wifi_secrets_cb,
+ self);
return FALSE;
}
@@ -2444,253 +2502,97 @@ time_out:
return FALSE;
}
-static gboolean
-schedule_state_handler (NMDeviceWifi *self,
- GSourceFunc handler,
- guint32 new_state,
- guint32 old_state,
- gboolean mgr_task)
+static void
+supplicant_iface_state_cb (NMSupplicantInterface *iface,
+ guint32 new_state,
+ guint32 old_state,
+ gpointer user_data)
{
- NMDeviceWifiPrivate *priv;
- SupplicantStateTask *task;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (handler != NULL, FALSE);
+ NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
+ NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ NMDevice *device = NM_DEVICE (self);
+ NMDeviceState devstate;
+ gboolean scanning;
if (new_state == old_state)
- return TRUE;
-
- priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- task = g_slice_new0 (SupplicantStateTask);
- if (!task) {
- nm_log_err (LOGD_WIFI, "Not enough memory to process supplicant manager state change.");
- return FALSE;
- }
-
- task->self = self;
- task->new_state = new_state;
- task->old_state = old_state;
- task->mgr_task = mgr_task;
-
- task->source_id = g_idle_add (handler, task);
- if (mgr_task)
- priv->supplicant.mgr_tasks = g_slist_append (priv->supplicant.mgr_tasks, task);
- else
- priv->supplicant.iface_tasks = g_slist_append (priv->supplicant.iface_tasks, task);
-
- return TRUE;
-}
-
-static gboolean
-supplicant_iface_state_cb_handler (gpointer user_data)
-{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDeviceWifi *self;
- NMDeviceWifiPrivate *priv;
-
- g_return_val_if_fail (task != NULL, FALSE);
+ return;
- self = task->self;
- priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
+ nm_log_info (LOGD_DEVICE | LOGD_WIFI,
+ "(%s): supplicant interface state: %s -> %s",
+ nm_device_get_iface (device),
+ nm_supplicant_interface_state_to_string (old_state),
+ nm_supplicant_interface_state_to_string (new_state));
- nm_log_info (LOGD_WIFI, "(%s): supplicant interface state: %s -> %s",
- nm_device_get_iface (NM_DEVICE (self)),
- nm_supplicant_interface_state_to_string (task->old_state),
- nm_supplicant_interface_state_to_string (task->new_state));
+ devstate = nm_device_get_state (device);
+ scanning = nm_supplicant_interface_get_scanning (iface);
- if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_READY) {
+ switch (new_state) {
+ case NM_SUPPLICANT_INTERFACE_STATE_READY:
priv->scan_interval = SCAN_INTERVAL_MIN;
/* If the interface can now be activated because the supplicant is now
* available, transition to DISCONNECTED.
*/
- if ( (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_UNAVAILABLE)
- && nm_device_is_available (NM_DEVICE (self))) {
- nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_DISCONNECTED,
+ if ((devstate == NM_DEVICE_STATE_UNAVAILABLE) && nm_device_is_available (device)) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_DISCONNECTED,
NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE);
}
- nm_log_dbg (LOGD_WIFI_SCAN, "(%s): supplicant ready, requesting initial scan",
- nm_device_get_iface (NM_DEVICE (self)));
+ nm_log_dbg (LOGD_WIFI_SCAN,
+ "(%s): supplicant ready, requesting initial scan",
+ nm_device_get_iface (device));
/* Request a scan to get latest results */
cancel_pending_scan (self);
request_wireless_scan (self);
- } else if (task->new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
- cleanup_association_attempt (self, FALSE);
- supplicant_interface_release (self);
- nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
- }
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-
-static void
-supplicant_iface_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- NMDeviceWifi *self)
-{
- g_return_if_fail (self != NULL);
-
- schedule_state_handler (self,
- supplicant_iface_state_cb_handler,
- new_state,
- old_state,
- FALSE);
-}
-
-
-static gboolean
-supplicant_iface_connection_state_cb_handler (gpointer user_data)
-{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDeviceWifi *self = task->self;
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- NMDevice *dev = NM_DEVICE (self);
- gboolean scanning;
-
- if (!nm_device_get_act_request (dev)) {
- /* The device is not activating or already activated; do nothing. */
- goto out;
- }
-
- nm_log_info (LOGD_WIFI, "(%s): supplicant connection state: %s -> %s",
- nm_device_get_iface (dev),
- nm_supplicant_interface_connection_state_to_string (task->old_state),
- nm_supplicant_interface_connection_state_to_string (task->new_state));
-
- scanning = nm_supplicant_interface_get_scanning (priv->supplicant.iface);
-
- if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED) {
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
remove_supplicant_interface_error_handler (self);
remove_supplicant_timeouts (self);
/* If this is the initial association during device activation,
* schedule the next activation stage.
*/
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
+ if (devstate == NM_DEVICE_STATE_CONFIG) {
NMAccessPoint *ap = nm_device_wifi_get_activation_ap (self);
- const GByteArray * ssid = nm_ap_get_ssid (ap);
+ const GByteArray *ssid = nm_ap_get_ssid (ap);
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless) Stage 2 of 5 (Device Configure) "
"successful. Connected to wireless network '%s'.",
- nm_device_get_iface (dev),
+ nm_device_get_iface (device),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
- nm_device_activate_schedule_stage3_ip_config_start (dev);
+ nm_device_activate_schedule_stage3_ip_config_start (device);
}
- } else if (task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED || nm_device_is_activating (dev)) {
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
+ if ((devstate == NM_DEVICE_STATE_ACTIVATED) || nm_device_is_activating (device)) {
/* Start the link timeout so we allow some time for reauthentication,
* use a longer timeout if we are scanning since some cards take a
* while to scan.
*/
if (!priv->link_timeout_id) {
priv->link_timeout_id = g_timeout_add_seconds (scanning ? 30 : 15,
- link_timeout_cb, self);
+ link_timeout_cb, self);
}
}
+ break;
+ case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
+ cleanup_association_attempt (self, FALSE);
+ supplicant_interface_release (self);
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
+ break;
+ default:
+ break;
}
-out:
/* Signal scanning state changes */
- if ( task->new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING
- || task->old_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING)
+ if ( new_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING
+ || old_state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
g_object_notify (G_OBJECT (self), "scanning");
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-
-static void
-supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- NMDeviceWifi *self)
-{
- g_return_if_fail (self != NULL);
-
- schedule_state_handler (self,
- supplicant_iface_connection_state_cb_handler,
- new_state,
- old_state,
- FALSE);
-}
-
-
-static gboolean
-supplicant_mgr_state_cb_handler (gpointer user_data)
-{
- SupplicantStateTask *task = (SupplicantStateTask *) user_data;
- NMDeviceWifi *self;
- NMDeviceWifiPrivate *priv;
- NMDevice *dev;
- NMDeviceState dev_state;
-
- g_return_val_if_fail (task != NULL, FALSE);
-
- self = task->self;
- priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- dev = NM_DEVICE (self);
-
- nm_log_info (LOGD_WIFI, "(%s): supplicant manager state: %s -> %s",
- nm_device_get_iface (NM_DEVICE (self)),
- nm_supplicant_manager_state_to_string (task->old_state),
- nm_supplicant_manager_state_to_string (task->new_state));
-
- /* If the supplicant went away, release the supplicant interface */
- if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
- if (priv->supplicant.iface) {
- cleanup_association_attempt (self, FALSE);
- supplicant_interface_release (self);
- }
-
- if (nm_device_get_state (dev) > NM_DEVICE_STATE_UNAVAILABLE) {
- nm_device_state_changed (dev, NM_DEVICE_STATE_UNAVAILABLE,
- NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED);
- }
- } else if (task->new_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
- dev_state = nm_device_get_state (dev);
- if ( priv->enabled
- && !priv->supplicant.iface
- && (dev_state >= NM_DEVICE_STATE_UNAVAILABLE)
- && (nm_device_get_firmware_missing (NM_DEVICE (self)) == FALSE)) {
- /* request a supplicant interface from the supplicant manager */
- supplicant_interface_acquire (self);
-
- /* if wireless is enabled and we have a supplicant interface,
- * we can transition to the DISCONNECTED state.
- */
- if (priv->supplicant.iface) {
- nm_device_state_changed (dev, NM_DEVICE_STATE_DISCONNECTED,
- NM_DEVICE_STATE_REASON_NONE);
- }
- }
- }
-
- finish_supplicant_task (task, FALSE);
- return FALSE;
-}
-
-static void
-supplicant_mgr_state_cb (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state,
- NMDeviceWifi *self)
-{
- g_return_if_fail (self != NULL);
-
- schedule_state_handler (self,
- supplicant_mgr_state_cb_handler,
- new_state,
- old_state,
- TRUE);
}
struct iface_con_error_cb_data {
@@ -2802,6 +2704,7 @@ handle_auth_or_fail (NMDeviceWifi *self,
guint32 tries;
NMAccessPoint *ap;
NMConnection *connection;
+ NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NM_ACT_STAGE_RETURN_FAILURE);
@@ -2825,24 +2728,21 @@ handle_auth_or_fail (NMDeviceWifi *self,
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, NULL);
if (setting_name) {
- gboolean get_new;
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
/* If the caller doesn't necessarily want completely new secrets,
* only ask for new secrets after the first failure.
*/
- get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE);
- nm_act_request_get_secrets (req,
- setting_name,
- get_new,
- SECRETS_CALLER_WIFI,
- NULL,
- NULL);
+ if (new_secrets || tries)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+ nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self);
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
- } else {
+ ret = NM_ACT_STAGE_RETURN_POSTPONE;
+ } else
nm_log_warn (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets.");
- }
- return NM_ACT_STAGE_RETURN_POSTPONE;
+
+ return ret;
}
/*
@@ -3212,42 +3112,6 @@ done:
return NM_ACT_STAGE_RETURN_SUCCESS;
}
-
-static void
-real_connection_secrets_updated (NMDevice *dev,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller)
-{
- NMActRequest *req;
- gboolean valid = FALSE;
- GSList *iter;
-
- g_return_if_fail (caller == SECRETS_CALLER_WIFI);
-
- if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH)
- return;
-
- for (iter = updated_settings; iter; iter = g_slist_next (iter)) {
- const char *setting_name = (const char *) iter->data;
-
- if ( !strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
- || !strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) {
- valid = TRUE;
- } else {
- nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.",
- setting_name);
- }
- }
-
- req = nm_device_get_act_request (dev);
- g_assert (req);
-
- g_return_if_fail (nm_act_request_get_connection (req) == connection);
-
- nm_device_activate_schedule_stage1_device_prepare (dev);
-}
-
static NMActStageReturn
real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
{
@@ -3260,7 +3124,6 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
NMActRequest *req;
NMAccessPoint *ap;
NMConnection *connection;
- NMSettingConnection *s_connection;
const char *setting_name;
NMSettingWireless *s_wireless;
@@ -3277,9 +3140,6 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
connection = nm_act_request_get_connection (req);
g_assert (connection);
- s_connection = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_assert (s_connection);
-
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
g_assert (s_wireless);
@@ -3289,7 +3149,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): access point '%s' has security,"
" but secrets are required.",
- iface, nm_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
ret = handle_auth_or_fail (self, req, FALSE);
if (ret == NM_ACT_STAGE_RETURN_FAILURE)
@@ -3302,12 +3162,12 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): connection '%s' has security"
", and secrets exist. No new secrets needed.",
- iface, nm_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
} else {
nm_log_info (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): connection '%s' requires no "
"security. No secrets needed.",
- iface, nm_setting_connection_get_id (s_connection));
+ iface, nm_connection_get_id (connection));
}
config = build_supplicant_config (self, connection, ap);
@@ -3321,7 +3181,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason)
/* Hook up error signal handler to capture association errors */
id = g_signal_connect (priv->supplicant.iface,
- "connection-error",
+ NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR,
G_CALLBACK (supplicant_iface_connection_error_cb),
self);
priv->supplicant.iface_error_id = id;
@@ -3413,16 +3273,12 @@ handle_ip_config_timeout (NMDeviceWifi *self,
*/
auth_enforced = ap_auth_enforced (connection, ap, &encrypted);
if (encrypted && !auth_enforced && !may_fail) {
- NMSettingConnection *s_con;
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
-
/* Activation failed, we must have bad encryption key */
nm_log_warn (LOGD_DEVICE | LOGD_WIFI,
"Activation (%s/wireless): could not get IP configuration for "
"connection '%s'.",
- nm_device_get_iface (NM_DEVICE (self)),
- nm_setting_connection_get_id (s_con));
+ nm_device_get_iface (NM_DEVICE (self)),
+ nm_connection_get_id (connection));
ret = handle_auth_or_fail (self, NULL, TRUE);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
@@ -3708,10 +3564,8 @@ device_state_changed (NMDevice *device,
NMAccessPoint *
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
{
- NMDeviceWifiPrivate *priv;
NMActRequest *req;
const char *ap_path;
- GSList * elt;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NULL);
@@ -3720,18 +3574,8 @@ nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
return NULL;
ap_path = nm_act_request_get_specific_object (req);
- if (!ap_path)
- return NULL;
-
- /* Find the AP by it's object path */
- priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- for (elt = priv->ap_list; elt; elt = g_slist_next (elt)) {
- NMAccessPoint *ap = NM_AP (elt->data);
- if (!strcmp (ap_path, nm_ap_get_dbus_path (ap)))
- return ap;
- }
- return NULL;
+ return ap_path ? get_ap_by_path (self, ap_path) : NULL;
}
static void
@@ -3781,12 +3625,11 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled)
/* Wait for some drivers like ipw3945 to come back to life */
success = wireless_get_range (self, &range, NULL);
- /* iface should be NULL here, but handle it anyway if it's not */
- g_warn_if_fail (priv->supplicant.iface == NULL);
+ /* Re-initialize the supplicant interface and wait for it to be ready */
if (priv->supplicant.iface)
supplicant_interface_release (self);
-
supplicant_interface_acquire (self);
+
nm_log_dbg (LOGD_WIFI, "(%s): enable waiting on supplicant state",
nm_device_get_iface (NM_DEVICE (device)));
} else {
@@ -3848,20 +3691,9 @@ dispose (GObject *object)
priv->periodic_source_id = 0;
}
- /* Clean up all pending supplicant tasks */
- while (priv->supplicant.iface_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.iface_tasks->data, TRUE);
- while (priv->supplicant.mgr_tasks)
- finish_supplicant_task ((SupplicantStateTask *) priv->supplicant.mgr_tasks->data, TRUE);
-
cleanup_association_attempt (self, TRUE);
supplicant_interface_release (self);
- if (priv->supplicant.mgr_state_id) {
- g_signal_handler_disconnect (priv->supplicant.mgr, priv->supplicant.mgr_state_id);
- priv->supplicant.mgr_state_id = 0;
- }
-
if (priv->supplicant.mgr) {
g_object_unref (priv->supplicant.mgr);
priv->supplicant.mgr = NULL;
@@ -3969,8 +3801,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->update_initial_hw_address = real_update_initial_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
- parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
+ parent_class->complete_connection = real_complete_connection;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
@@ -3978,7 +3810,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->act_stage4_ip4_config_timeout = real_act_stage4_ip4_config_timeout;
parent_class->act_stage4_ip6_config_timeout = real_act_stage4_ip6_config_timeout;
parent_class->deactivate = real_deactivate;
- parent_class->deactivate_quickly = real_deactivate_quickly;
parent_class->can_interrupt_activation = real_can_interrupt_activation;
parent_class->spec_match_list = spec_match_list;
diff --git a/src/nm-device.c b/src/nm-device.c
index 9c771c2ab..9b182c4d3 100644
--- a/src/nm-device.c
+++ b/src/nm-device.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -184,8 +184,8 @@ static NMActStageReturn dhcp6_start (NMDevice *self,
NMDeviceStateReason *reason);
static void addrconf6_cleanup (NMDevice *self);
-static void dhcp6_cleanup (NMDevice *self, gboolean stop);
-static void dhcp4_cleanup (NMDevice *self, gboolean stop);
+static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release);
+static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release);
static void
@@ -572,6 +572,38 @@ nm_device_get_best_auto_connection (NMDevice *dev,
return NM_DEVICE_GET_CLASS (dev)->get_best_auto_connection (dev, connections, specific_object);
}
+gboolean
+nm_device_complete_connection (NMDevice *self,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (connection != NULL, FALSE);
+
+ if (!NM_DEVICE_GET_CLASS (self)->complete_connection) {
+ g_set_error (error,
+ NM_DEVICE_INTERFACE_ERROR,
+ NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID,
+ "Device class %s had no complete_connection method",
+ G_OBJECT_TYPE_NAME (self));
+ return FALSE;
+ }
+
+ success = NM_DEVICE_GET_CLASS (self)->complete_connection (self,
+ connection,
+ specific_object,
+ existing_connections,
+ error);
+ if (success)
+ success = nm_connection_verify (connection, error);
+
+ return success;
+}
+
static void
dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data)
{
@@ -1158,6 +1190,8 @@ nm_device_handle_autoip4_event (NMDevice *self,
aipd_timeout_remove (self);
nm_device_activate_schedule_stage4_ip4_config_get (self);
break;
+ case NM_DEVICE_STATE_IP_CHECK:
+ case NM_DEVICE_STATE_SECONDARIES:
case NM_DEVICE_STATE_ACTIVATED:
priv->aipd_addr = ip.s_addr;
if (!handle_autoip_change (self, &reason))
@@ -1469,7 +1503,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data)
if (!nm_device_get_act_request (device))
return;
- nm_dhcp_client_stop (client);
+ nm_dhcp_client_stop (client, FALSE);
if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) {
if (nm_dhcp_client_get_ipv6 (client))
@@ -1480,15 +1514,84 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data)
}
static NMActStageReturn
+dhcp4_start (NMDevice *self,
+ NMConnection *connection,
+ NMDeviceStateReason *reason)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMSettingIP4Config *s_ip4;
+ guint8 *anycast = NULL;
+
+ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+
+ if (priv->dhcp_anycast_address)
+ anycast = priv->dhcp_anycast_address->data;
+
+ /* Clear old exported DHCP options */
+ if (priv->dhcp4_config)
+ g_object_unref (priv->dhcp4_config);
+ priv->dhcp4_config = nm_dhcp4_config_new ();
+
+ /* Begin DHCP on the interface */
+ g_warn_if_fail (priv->dhcp4_client == NULL);
+ priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager,
+ nm_device_get_ip_iface (self),
+ nm_connection_get_uuid (connection),
+ s_ip4,
+ priv->dhcp_timeout,
+ anycast);
+ if (!priv->dhcp4_client) {
+ *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+
+ priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
+ "state-changed",
+ G_CALLBACK (dhcp_state_changed),
+ self);
+ priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client,
+ "timeout",
+ G_CALLBACK (dhcp_timeout),
+ self);
+
+ /* DHCP devices will be notified by the DHCP manager when stuff happens */
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+}
+
+gboolean
+nm_device_dhcp4_renew (NMDevice *self, gboolean release)
+{
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMActStageReturn ret;
+ NMDeviceStateReason reason;
+ NMActRequest *req;
+ NMConnection *connection;
+
+ g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE);
+
+ /* Terminate old DHCP instance and release the old lease */
+ dhcp4_cleanup (self, TRUE, TRUE);
+
+ req = nm_device_get_act_request (self);
+ g_assert (req);
+ connection = nm_act_request_get_connection (req);
+ g_assert (connection);
+
+ /* Start DHCP again on the interface */
+ ret = dhcp4_start (self, connection, &reason);
+
+ return (ret != NM_ACT_STAGE_RETURN_FAILURE);
+}
+
+static NMActStageReturn
real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMConnection *connection;
- NMSettingConnection *s_con;
NMSettingIP4Config *s_ip4;
NMActRequest *req;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
- const char *ip_iface, *method = NULL, *uuid;
+ const char *ip_iface, *method = NULL;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
@@ -1501,9 +1604,6 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
req = nm_device_get_act_request (self);
connection = nm_act_request_get_connection (req);
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- uuid = nm_setting_connection_get_uuid (s_con);
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
@@ -1512,42 +1612,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
method = nm_setting_ip4_config_get_method (s_ip4);
if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
- guint8 *anycast = NULL;
-
- /* Begin a DHCP transaction on the interface */
-
- if (priv->dhcp_anycast_address)
- anycast = priv->dhcp_anycast_address->data;
-
- /* Clear old exported DHCP options */
- if (priv->dhcp4_config)
- g_object_unref (priv->dhcp4_config);
- priv->dhcp4_config = nm_dhcp4_config_new ();
-
- priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager,
- ip_iface,
- uuid,
- s_ip4,
- priv->dhcp_timeout,
- anycast);
- if (priv->dhcp4_client) {
- priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client,
- "state-changed",
- G_CALLBACK (dhcp_state_changed),
- self);
- priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client,
- "timeout",
- G_CALLBACK (dhcp_timeout),
- self);
-
- /* DHCP devices will be notified by the DHCP manager when
- * stuff happens.
- */
- ret = NM_ACT_STAGE_RETURN_POSTPONE;
- } else {
- *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED;
- ret = NM_ACT_STAGE_RETURN_FAILURE;
- }
+ ret = dhcp4_start (self, connection, reason);
} else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) {
GError *error = NULL;
const char *iface = nm_device_get_iface (self);
@@ -1586,8 +1651,6 @@ dhcp6_start (NMDevice *self,
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
guint8 *anycast = NULL;
NMSettingIP6Config *s_ip6;
- NMSettingConnection *s_con;
- const char *uuid;
const char *ip_iface;
const struct in6_addr dest = { { { 0xFF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
int err;
@@ -1623,16 +1686,12 @@ dhcp6_start (NMDevice *self,
priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror ());
}
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- uuid = nm_setting_connection_get_uuid (s_con);
-
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
ip_iface = nm_device_get_ip_iface (self);
priv->dhcp6_client = nm_dhcp_manager_start_ip6 (priv->dhcp_manager,
ip_iface,
- uuid,
+ nm_connection_get_uuid (connection),
s_ip6,
priv->dhcp_timeout,
anycast,
@@ -1953,9 +2012,7 @@ nm_device_activate_stage4_ip4_config_get (gpointer user_data)
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
NM_ACT_REQUEST_IP4_CONFIG, ip4_config);
-nm_log_info (LOGD_DEVICE | LOGD_IP4, "Scheduling stage 5");
nm_device_activate_schedule_stage5_ip_config_commit (self, AF_INET);
-nm_log_info (LOGD_DEVICE | LOGD_IP4, "Done scheduling stage 5");
out:
nm_log_info (LOGD_DEVICE | LOGD_IP4,
@@ -2670,7 +2727,7 @@ delayed_transitions_clear (NMDevice *self)
}
static void
-dhcp4_cleanup (NMDevice *self, gboolean stop)
+dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -2693,7 +2750,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop)
}
if (stop)
- nm_dhcp_client_stop (priv->dhcp4_client);
+ nm_dhcp_client_stop (priv->dhcp4_client, release);
g_object_unref (priv->dhcp4_client);
priv->dhcp4_client = NULL;
@@ -2701,7 +2758,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop)
}
static void
-dhcp6_cleanup (NMDevice *self, gboolean stop)
+dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
@@ -2725,7 +2782,7 @@ dhcp6_cleanup (NMDevice *self, gboolean stop)
}
if (stop)
- nm_dhcp_client_stop (priv->dhcp6_client);
+ nm_dhcp_client_stop (priv->dhcp6_client, release);
g_object_unref (priv->dhcp6_client);
priv->dhcp6_client = NULL;
@@ -2751,21 +2808,27 @@ dnsmasq_cleanup (NMDevice *self)
}
/*
- * nm_device_deactivate_quickly
+ * nm_device_deactivate
*
- * Quickly deactivate a device, for things like sleep, etc. Doesn't
- * clean much stuff up, and nm_device_deactivate() should be called
- * on the device eventually.
+ * Remove a device's routing table entries and IP address.
*
*/
-gboolean
-nm_device_deactivate_quickly (NMDevice *self)
+static void
+nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
{
- NMDevicePrivate *priv;
+ NMDevice *self = NM_DEVICE (device);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
+ gboolean tried_ipv6 = FALSE;
- g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
+ g_return_if_fail (self != NULL);
- priv = NM_DEVICE_GET_PRIVATE (self);
+ nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason: %d).",
+ nm_device_get_iface (self), reason);
+
+ /* Save whether or not we tried IPv6 for later */
+ if (NM_DEVICE_GET_PRIVATE (self)->ip6_manager)
+ tried_ipv6 = TRUE;
/* Break the activation chain */
activation_source_clear (self, TRUE, AF_INET);
@@ -2774,8 +2837,8 @@ nm_device_deactivate_quickly (NMDevice *self)
/* Clear any delayed transitions */
delayed_transitions_clear (self);
- dhcp4_cleanup (self, TRUE);
- dhcp6_cleanup (self, TRUE);
+ dhcp4_cleanup (self, TRUE, FALSE);
+ dhcp6_cleanup (self, TRUE, FALSE);
addrconf6_cleanup (self);
dnsmasq_cleanup (self);
aipd_cleanup (self);
@@ -2787,39 +2850,12 @@ nm_device_deactivate_quickly (NMDevice *self)
nm_utils_do_sysctl (priv->ip6_accept_ra_path, "0\n");
/* Call device type-specific deactivation */
- if (NM_DEVICE_GET_CLASS (self)->deactivate_quickly)
- NM_DEVICE_GET_CLASS (self)->deactivate_quickly (self);
+ if (NM_DEVICE_GET_CLASS (self)->deactivate)
+ NM_DEVICE_GET_CLASS (self)->deactivate (self);
/* Tear down an existing activation request */
clear_act_request (self);
- return TRUE;
-}
-
-/*
- * nm_device_deactivate
- *
- * Remove a device's routing table entries and IP address.
- *
- */
-static void
-nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
-{
- NMDevice *self = NM_DEVICE (device);
- NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE;
- gboolean tried_ipv6 = FALSE;
-
- g_return_if_fail (self != NULL);
-
- nm_log_info (LOGD_DEVICE, "(%s): deactivating device (reason: %d).",
- nm_device_get_iface (self), reason);
-
- /* Check this before deactivate_quickly is run */
- if (NM_DEVICE_GET_PRIVATE (self)->ip6_manager)
- tried_ipv6 = TRUE;
-
- nm_device_deactivate_quickly (self);
-
/* Take out any entries in the routing table and any IP address the device had. */
nm_system_device_flush_routes (self, tried_ipv6 ? AF_UNSPEC : AF_INET);
nm_system_device_flush_addresses (self, tried_ipv6 ? AF_UNSPEC : AF_INET);
@@ -2828,10 +2864,6 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason)
/* Clean up nameservers and addresses */
nm_device_set_ip4_config (self, NULL, FALSE, &ignored);
nm_device_set_ip6_config (self, NULL, FALSE, &ignored);
-
- /* Call device type-specific deactivation */
- if (NM_DEVICE_GET_CLASS (self)->deactivate)
- NM_DEVICE_GET_CLASS (self)->deactivate (self);
}
static gboolean
@@ -2858,31 +2890,6 @@ check_connection_compatible (NMDeviceInterface *dev_iface,
return TRUE;
}
-static void
-connection_secrets_updated_cb (NMActRequest *req,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller,
- gpointer user_data)
-{
- NMDevice *self = NM_DEVICE (user_data);
-
- if (NM_DEVICE_GET_CLASS (self)->connection_secrets_updated)
- NM_DEVICE_GET_CLASS (self)->connection_secrets_updated (self, connection, updated_settings, caller);
-}
-
-static void
-connection_secrets_failed_cb (NMActRequest *req,
- NMConnection *connection,
- const char *setting_name,
- RequestSecretsCaller caller,
- gpointer user_data)
-{
- NMDevice *self = NM_DEVICE (user_data);
-
- nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS);
-}
-
static gboolean
device_activation_precheck (NMDevice *self, NMConnection *connection, GError **error)
{
@@ -2925,14 +2932,6 @@ nm_device_activate (NMDeviceInterface *device,
}
priv->act_request = g_object_ref (req);
- priv->secrets_updated_id = g_signal_connect (req,
- "connection-secrets-updated",
- G_CALLBACK (connection_secrets_updated_cb),
- device);
- priv->secrets_failed_id = g_signal_connect (req,
- "connection-secrets-failed",
- G_CALLBACK (connection_secrets_failed_cb),
- device);
if (!nm_act_request_get_assumed (req)) {
/* HACK: update the state a bit early to avoid a race between the
@@ -2964,29 +2963,20 @@ gboolean
nm_device_is_activating (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+ NMDeviceState state;
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
- switch (nm_device_get_state (device)) {
- case NM_DEVICE_STATE_PREPARE:
- case NM_DEVICE_STATE_CONFIG:
- case NM_DEVICE_STATE_NEED_AUTH:
- case NM_DEVICE_STATE_IP_CONFIG:
+ state = nm_device_get_state (device);
+ if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_SECONDARIES)
return TRUE;
- break;
- default:
- break;
- }
/* There's a small race between the time when stage 1 is scheduled
* and when the device actually sets STATE_PREPARE when the activation
* handler is actually run. If there's an activation handler scheduled
* we're activating anyway.
*/
- if (priv->act_source_id)
- return TRUE;
-
- return FALSE;
+ return priv->act_source_id ? TRUE : FALSE;
}
@@ -3333,10 +3323,8 @@ dispose (GObject *object)
NMSettingIP4Config *s_ip4 = NULL;
const char *method = NULL;
- /* Only system connections can be left up */
connection = nm_act_request_get_connection (priv->act_request);
- if ( connection
- && (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM)) {
+ if (connection) {
/* Only static or DHCP IPv4 connections can be left up.
* All IPv6 connections can be left up, so we don't have
@@ -3356,8 +3344,8 @@ dispose (GObject *object)
delayed_transitions_clear (self);
/* Clean up and stop DHCP */
- dhcp4_cleanup (self, take_down);
- dhcp6_cleanup (self, take_down);
+ dhcp4_cleanup (self, take_down, FALSE);
+ dhcp6_cleanup (self, take_down, FALSE);
addrconf6_cleanup (self);
dnsmasq_cleanup (self);
@@ -3462,6 +3450,12 @@ set_property (GObject *object, guint prop_id,
}
}
+static gboolean
+_is_connected (NMDeviceState state)
+{
+ return (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_DEACTIVATING);
+}
+
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -3480,7 +3474,7 @@ get_property (GObject *object, guint prop_id,
g_value_set_string (value, priv->iface);
break;
case NM_DEVICE_INTERFACE_PROP_IP_IFACE:
- if ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG))
+ if (_is_connected (state))
g_value_set_string (value, nm_device_get_ip_iface (self));
else
g_value_set_string (value, NULL);
@@ -3498,33 +3492,25 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, priv->ip4_address);
break;
case NM_DEVICE_INTERFACE_PROP_IP4_CONFIG:
- if ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG)) {
- if (priv->ip4_config) {
- g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config));
- break;
- }
- }
- g_value_set_boxed (value, "/");
+ if (_is_connected (state) && priv->ip4_config)
+ g_value_set_boxed (value, nm_ip4_config_get_dbus_path (priv->ip4_config));
+ else
+ g_value_set_boxed (value, "/");
break;
case NM_DEVICE_INTERFACE_PROP_DHCP4_CONFIG:
- if ( ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG))
- && priv->dhcp4_client)
+ if (_is_connected (state) && priv->dhcp4_client)
g_value_set_boxed (value, nm_dhcp4_config_get_dbus_path (priv->dhcp4_config));
else
g_value_set_boxed (value, "/");
break;
case NM_DEVICE_INTERFACE_PROP_IP6_CONFIG:
- if ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG)) {
- if (priv->ip6_config) {
- g_value_set_boxed (value, nm_ip6_config_get_dbus_path (priv->ip6_config));
- break;
- }
- }
- g_value_set_boxed (value, "/");
+ if (_is_connected (state) && priv->ip6_config)
+ g_value_set_boxed (value, nm_ip6_config_get_dbus_path (priv->ip6_config));
+ else
+ g_value_set_boxed (value, "/");
break;
case NM_DEVICE_INTERFACE_PROP_DHCP6_CONFIG:
- if ( ((state == NM_DEVICE_STATE_ACTIVATED) || (state == NM_DEVICE_STATE_IP_CONFIG))
- && priv->dhcp6_client)
+ if (_is_connected (state) && priv->dhcp6_client)
g_value_set_boxed (value, nm_dhcp6_config_get_dbus_path (priv->dhcp6_config));
else
g_value_set_boxed (value, "/");
@@ -3877,7 +3863,7 @@ spec_match_list (NMDeviceInterface *device, const GSList *specs)
static NMConnection *
connection_match_config (NMDeviceInterface *device, const GSList *connections)
{
- g_return_val_if_fail (device != NULL, FALSE);
+ g_return_val_if_fail (device != NULL, NULL);
if (NM_DEVICE_GET_CLASS (device)->connection_match_config)
return NM_DEVICE_GET_CLASS (device)->connection_match_config (NM_DEVICE (device), connections);
diff --git a/src/nm-device.h b/src/nm-device.h
index db2b1b7db..1d080eda5 100644
--- a/src/nm-device.h
+++ b/src/nm-device.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2010 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -84,15 +84,16 @@ typedef struct {
GSList *connections,
char **specific_object);
- void (* connection_secrets_updated) (NMDevice *self,
- NMConnection *connection,
- GSList *updated_settings,
- RequestSecretsCaller caller);
-
gboolean (* check_connection_compatible) (NMDevice *self,
NMConnection *connection,
GError **error);
+ gboolean (* complete_connection) (NMDevice *self,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error);
+
NMActStageReturn (* act_stage1_prepare) (NMDevice *self,
NMDeviceStateReason *reason);
NMActStageReturn (* act_stage2_config) (NMDevice *self,
@@ -114,7 +115,6 @@ typedef struct {
NMIP6Config **config,
NMDeviceStateReason *reason);
void (* deactivate) (NMDevice *self);
- void (* deactivate_quickly) (NMDevice *self);
gboolean (* can_interrupt_activation) (NMDevice *self);
@@ -162,13 +162,18 @@ NMConnection * nm_device_get_best_auto_connection (NMDevice *dev,
GSList *connections,
char **specific_object);
+gboolean nm_device_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connection,
+ GError **error);
+
void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device);
void nm_device_activate_schedule_stage2_device_config (NMDevice *device);
void nm_device_activate_schedule_stage4_ip4_config_get (NMDevice *device);
void nm_device_activate_schedule_stage4_ip4_config_timeout (NMDevice *device);
void nm_device_activate_schedule_stage4_ip6_config_get (NMDevice *device);
void nm_device_activate_schedule_stage4_ip6_config_timeout (NMDevice *device);
-gboolean nm_device_deactivate_quickly (NMDevice *dev);
gboolean nm_device_is_activating (NMDevice *dev);
gboolean nm_device_can_interrupt_activation (NMDevice *self);
gboolean nm_device_autoconnect_allowed (NMDevice *self);
@@ -185,6 +190,8 @@ void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr);
void nm_device_clear_autoconnect_inhibit (NMDevice *device);
+gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release);
+
G_END_DECLS
#endif /* NM_DEVICE_H */
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 0ae3d1bee..ef284d80e 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -121,7 +121,7 @@ nm_ip4_config_export (NMIP4Config *config)
const char *
nm_ip4_config_get_dbus_path (NMIP4Config *config)
{
- g_return_val_if_fail (NM_IS_IP4_CONFIG (config), FALSE);
+ g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL);
return NM_IP4_CONFIG_GET_PRIVATE (config)->path;
}
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index 4c6c5c627..2f231638f 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -114,7 +114,7 @@ nm_ip6_config_export (NMIP6Config *config)
const char *
nm_ip6_config_get_dbus_path (NMIP6Config *config)
{
- g_return_val_if_fail (NM_IS_IP6_CONFIG (config), FALSE);
+ g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
return NM_IP6_CONFIG_GET_PRIVATE (config)->path;
}
diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c
index 44c82c23e..8515959eb 100644
--- a/src/nm-manager-auth.c
+++ b/src/nm-manager-auth.c
@@ -18,11 +18,13 @@
* Copyright (C) 2010 Red Hat, Inc.
*/
+#include <string.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <nm-setting-connection.h>
#include "nm-manager-auth.h"
#include "nm-logging.h"
-
-#include <dbus/dbus-glib-lowlevel.h>
-#include <string.h>
+#include "nm-dbus-manager.h"
struct NMAuthChain {
guint32 refcount;
@@ -78,12 +80,13 @@ _auth_chain_new (PolkitAuthority *authority,
DBusGMethodInvocation *context,
DBusGProxy *proxy,
DBusMessage *message,
+ const char *dbus_sender,
NMAuthChainResultFunc done_func,
gpointer user_data)
{
NMAuthChain *self;
- g_return_val_if_fail (context || proxy || message, NULL);
+ g_return_val_if_fail (context || proxy || message || dbus_sender, NULL);
self = g_malloc0 (sizeof (NMAuthChain));
self->refcount = 1;
@@ -100,6 +103,8 @@ _auth_chain_new (PolkitAuthority *authority,
self->owner = dbus_g_method_get_sender (context);
else if (message)
self->owner = g_strdup (dbus_message_get_sender (message));
+ else if (dbus_sender)
+ self->owner = g_strdup (dbus_sender);
if (!self->owner) {
/* Need an owner */
@@ -118,7 +123,7 @@ nm_auth_chain_new (PolkitAuthority *authority,
NMAuthChainResultFunc done_func,
gpointer user_data)
{
- return _auth_chain_new (authority, context, proxy, NULL, done_func, user_data);
+ return _auth_chain_new (authority, context, proxy, NULL, NULL, done_func, user_data);
}
NMAuthChain *
@@ -127,7 +132,16 @@ nm_auth_chain_new_raw_message (PolkitAuthority *authority,
NMAuthChainResultFunc done_func,
gpointer user_data)
{
- return _auth_chain_new (authority, NULL, NULL, message, done_func, user_data);
+ return _auth_chain_new (authority, NULL, NULL, message, NULL, done_func, user_data);
+}
+
+NMAuthChain *
+nm_auth_chain_new_dbus_sender (PolkitAuthority *authority,
+ const char *dbus_sender,
+ NMAuthChainResultFunc done_func,
+ gpointer user_data)
+{
+ return _auth_chain_new (authority, NULL, NULL, NULL, dbus_sender, done_func, user_data);
}
gpointer
@@ -164,6 +178,43 @@ nm_auth_chain_set_data (NMAuthChain *self,
}
}
+gulong
+nm_auth_chain_get_data_ulong (NMAuthChain *self, const char *tag)
+{
+ gulong *ptr;
+
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (tag != NULL, 0);
+
+ ptr = nm_auth_chain_get_data (self, tag);
+ return *ptr;
+}
+
+
+void
+nm_auth_chain_set_data_ulong (NMAuthChain *self,
+ const char *tag,
+ gulong data)
+{
+ gulong *ptr;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (tag != NULL);
+
+ ptr = g_malloc (sizeof (*ptr));
+ *ptr = data;
+ nm_auth_chain_set_data (self, tag, ptr, g_free);
+}
+
+NMAuthCallResult
+nm_auth_chain_get_result (NMAuthChain *self, const char *permission)
+{
+ g_return_val_if_fail (self != NULL, NM_AUTH_CALL_RESULT_UNKNOWN);
+ g_return_val_if_fail (permission != NULL, NM_AUTH_CALL_RESULT_UNKNOWN);
+
+ return GPOINTER_TO_UINT (nm_auth_chain_get_data (self, permission));
+}
+
static void
nm_auth_chain_check_done (NMAuthChain *self)
{
@@ -317,7 +368,7 @@ gboolean
nm_auth_get_caller_uid (DBusGMethodInvocation *context,
NMDBusManager *dbus_mgr,
gulong *out_uid,
- const char **out_error_desc)
+ char **out_error_desc)
{
DBusConnection *connection;
char *sender = NULL;
@@ -325,22 +376,27 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context,
DBusError dbus_error;
g_return_val_if_fail (context != NULL, FALSE);
- g_return_val_if_fail (dbus_mgr != NULL, FALSE);
g_return_val_if_fail (out_uid != NULL, FALSE);
+ if (!dbus_mgr) {
+ dbus_mgr = nm_dbus_manager_get ();
+ g_assert (dbus_mgr);
+ } else
+ g_object_ref (dbus_mgr);
+
*out_uid = G_MAXULONG;
sender = dbus_g_method_get_sender (context);
if (!sender) {
if (out_error_desc)
- *out_error_desc = "Could not determine D-Bus requestor";
+ *out_error_desc = g_strdup ("Could not determine D-Bus requestor");
goto out;
}
connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!connection) {
if (out_error_desc)
- *out_error_desc = "Could not get the D-Bus system bus";
+ *out_error_desc = g_strdup ("Could not get the D-Bus system bus");
goto out;
}
@@ -349,73 +405,55 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context,
*out_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error);
if (dbus_error_is_set (&dbus_error)) {
if (out_error_desc)
- *out_error_desc = "Could not determine the user ID of the requestor";
+ *out_error_desc = g_strdup_printf ("Could not determine the user ID of the requestor");
dbus_error_free (&dbus_error);
*out_uid = G_MAXULONG;
} else
success = TRUE;
out:
+ g_object_unref (dbus_mgr);
g_free (sender);
return success;
}
gboolean
-nm_auth_uid_authorized (gulong uid,
- NMDBusManager *dbus_mgr,
- DBusGProxy *user_proxy,
- const char **out_error_desc)
+nm_auth_uid_in_acl (NMConnection *connection,
+ NMSessionMonitor *smon,
+ gulong uid,
+ char **out_error_desc)
{
- DBusConnection *connection;
- DBusError dbus_error;
- char *service_owner = NULL;
- const char *service_name;
- gulong service_uid = G_MAXULONG;
-
- g_return_val_if_fail (dbus_mgr != NULL, FALSE);
- g_return_val_if_fail (out_error_desc != NULL, FALSE);
-
- /* Ensure the request to activate the user connection came from the
- * same session as the user settings service. FIXME: use ConsoleKit
- * too.
- */
-
- if (!user_proxy) {
- *out_error_desc = "No user settings service available";
+ NMSettingConnection *s_con;
+ const char *user = NULL;
+ GError *local = NULL;
+
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (smon != NULL, FALSE);
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+
+ /* Reject the request if the request comes from no session at all */
+ if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) {
+ if (out_error_desc) {
+ *out_error_desc = g_strdup_printf ("No session found for uid %lu (%s)",
+ uid,
+ local && local->message ? local->message : "unknown");
+ }
+ g_clear_error (&local);
return FALSE;
}
- service_name = dbus_g_proxy_get_bus_name (user_proxy);
- if (!service_name) {
- *out_error_desc = "Could not determine user settings service name";
- return FALSE;
- }
-
- connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!connection) {
- *out_error_desc = "Could not get the D-Bus system bus";
- return FALSE;
- }
-
- service_owner = nm_dbus_manager_get_name_owner (dbus_mgr, service_name, NULL);
- if (!service_owner) {
- *out_error_desc = "Could not determine D-Bus owner of the user settings service";
- return FALSE;
- }
-
- dbus_error_init (&dbus_error);
- service_uid = dbus_bus_get_unix_user (connection, service_owner, &dbus_error);
- g_free (service_owner);
-
- if (dbus_error_is_set (&dbus_error)) {
- dbus_error_free (&dbus_error);
- *out_error_desc = "Could not determine the Unix UID of the sender of the request";
+ if (!user) {
+ if (out_error_desc)
+ *out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid);
return FALSE;
}
- /* And finally, the actual UID check */
- if (uid != service_uid) {
- *out_error_desc = "Requestor UID does not match the UID of the user settings service";
+ /* Match the username returned by the session check to a user in the ACL */
+ if (!nm_setting_connection_permissions_user_allowed (s_con, user)) {
+ if (out_error_desc)
+ *out_error_desc = g_strdup_printf ("uid %lu has no permission to perform this operation", uid);
return FALSE;
}
diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h
index 6682f91ca..7e7ff7a12 100644
--- a/src/nm-manager-auth.h
+++ b/src/nm-manager-auth.h
@@ -25,14 +25,21 @@
#include <glib.h>
#include <dbus/dbus-glib.h>
+#include <nm-connection.h>
#include "nm-dbus-manager.h"
+#include "nm-session-monitor.h"
-#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network"
-#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake"
-#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi"
-#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan"
-#define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections"
-#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control"
+#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network"
+#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake"
+#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi"
+#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan"
+#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax"
+#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control"
+#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected"
+#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open"
+#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system"
+#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own"
+#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname"
typedef struct NMAuthChain NMAuthChain;
@@ -66,6 +73,11 @@ NMAuthChain *nm_auth_chain_new_raw_message (PolkitAuthority *authority,
NMAuthChainResultFunc done_func,
gpointer user_data);
+NMAuthChain *nm_auth_chain_new_dbus_sender (PolkitAuthority *authority,
+ const char *dbus_sender,
+ NMAuthChainResultFunc done_func,
+ gpointer user_data);
+
gpointer nm_auth_chain_get_data (NMAuthChain *chain, const char *tag);
void nm_auth_chain_set_data (NMAuthChain *chain,
@@ -73,6 +85,15 @@ void nm_auth_chain_set_data (NMAuthChain *chain,
gpointer data,
GDestroyNotify data_destroy);
+void nm_auth_chain_set_data_ulong (NMAuthChain *chain,
+ const char *tag,
+ gulong data);
+
+gulong nm_auth_chain_get_data_ulong (NMAuthChain *chain, const char *tag);
+
+NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain,
+ const char *permission);
+
gboolean nm_auth_chain_add_call (NMAuthChain *chain,
const char *permission,
gboolean allow_interaction);
@@ -83,12 +104,13 @@ void nm_auth_chain_unref (NMAuthChain *chain);
gboolean nm_auth_get_caller_uid (DBusGMethodInvocation *context,
NMDBusManager *dbus_mgr,
gulong *out_uid,
- const char **out_error_desc);
+ char **out_error_desc);
-gboolean nm_auth_uid_authorized (gulong uid,
- NMDBusManager *dbus_mgr,
- DBusGProxy *user_proxy,
- const char **out_error_desc);
+/* Caller must free returned error description */
+gboolean nm_auth_uid_in_acl (NMConnection *connection,
+ NMSessionMonitor *smon,
+ gulong uid,
+ char **out_error_desc);
#endif /* NM_MANAGER_AUTH_H */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 8b24aa516..aad650881 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -25,6 +25,7 @@
#include <string.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
+#include <glib/gi18n.h>
#include "nm-glib-compat.h"
#include "nm-manager.h"
@@ -38,8 +39,10 @@
#include "nm-device-ethernet.h"
#include "nm-device-wifi.h"
#include "nm-device-olpc-mesh.h"
-#include "nm-device-cdma.h"
-#include "nm-device-gsm.h"
+#if WITH_WIMAX
+#include "nm-device-wimax.h"
+#endif
+#include "nm-device-modem.h"
#include "nm-system.h"
#include "nm-properties-changed-signal.h"
#include "nm-setting-bluetooth.h"
@@ -52,11 +55,10 @@
#include "nm-hostname-provider.h"
#include "nm-bluez-manager.h"
#include "nm-bluez-common.h"
-#include "nm-sysconfig-settings.h"
-#include "nm-secrets-provider-interface.h"
-#include "nm-settings-interface.h"
-#include "nm-settings-system-interface.h"
+#include "nm-settings.h"
+#include "nm-settings-connection.h"
#include "nm-manager-auth.h"
+#include "NetworkManagerUtils.h"
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
#define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
@@ -65,12 +67,17 @@
static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err);
static void impl_manager_activate_connection (NMManager *manager,
- const char *service_name,
const char *connection_path,
const char *device_path,
const char *specific_object_path,
DBusGMethodInvocation *context);
+static void impl_manager_add_and_activate_connection (NMManager *manager,
+ GHashTable *settings,
+ const char *device_path,
+ const char *specific_object_path,
+ DBusGMethodInvocation *context);
+
static void impl_manager_deactivate_connection (NMManager *manager,
const char *connection_path,
DBusGMethodInvocation *context);
@@ -86,23 +93,17 @@ static void impl_manager_enable (NMManager *manager,
static void impl_manager_get_permissions (NMManager *manager,
DBusGMethodInvocation *context);
+static gboolean impl_manager_get_state (NMManager *manager,
+ guint32 *state,
+ GError **error);
+
static gboolean impl_manager_set_logging (NMManager *manager,
const char *level,
const char *domains,
GError **error);
-/* Legacy 0.6 compatibility interface */
-
-static void impl_manager_legacy_sleep (NMManager *manager, DBusGMethodInvocation *context);
-static void impl_manager_legacy_wake (NMManager *manager, DBusGMethodInvocation *context);
-static gboolean impl_manager_legacy_state (NMManager *manager, guint32 *state, GError **err);
-
#include "nm-manager-glue.h"
-static void connection_added_default_handler (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope);
-
static void udev_device_added_cb (NMUdevManager *udev_mgr,
GUdevDevice *device,
NMDeviceCreatorFn creator_fn,
@@ -135,6 +136,7 @@ static const char *internal_activate_device (NMManager *manager,
NMConnection *connection,
const char *specific_object,
gboolean user_requested,
+ gulong sender_uid,
gboolean assumed,
GError **error);
@@ -176,14 +178,10 @@ struct PendingActivation {
PendingActivationFunc callback;
NMAuthChain *chain;
- gboolean have_connection;
- gboolean authorized;
-
- NMConnectionScope scope;
char *connection_path;
+ NMConnection *connection;
char *specific_object_path;
char *device_path;
- guint timeout_id;
};
typedef struct {
@@ -209,19 +207,9 @@ typedef struct {
NMUdevManager *udev_mgr;
NMBluezManager *bluez_mgr;
- GHashTable *user_connections;
- DBusGProxy *user_proxy;
- NMAuthCallResult user_con_perm;
- NMAuthCallResult user_net_perm;
-
- GHashTable *system_connections;
- NMSysconfigSettings *sys_settings;
+ NMSettings *settings;
char *hostname;
- GSList *secrets_calls;
-
- GSList *pending_activations;
-
RadioState radio_states[RFKILL_TYPE_MAX];
gboolean sleeping;
gboolean net_enabled;
@@ -260,12 +248,7 @@ enum {
DEVICE_ADDED,
DEVICE_REMOVED,
STATE_CHANGED,
- STATE_CHANGE, /* DEPRECATED */
PROPERTIES_CHANGED,
- CONNECTIONS_ADDED,
- CONNECTION_ADDED,
- CONNECTION_UPDATED,
- CONNECTION_REMOVED,
CHECK_PERMISSIONS,
USER_PERMISSIONS_CHANGED,
@@ -283,6 +266,8 @@ enum {
PROP_WIRELESS_HARDWARE_ENABLED,
PROP_WWAN_ENABLED,
PROP_WWAN_HARDWARE_ENABLED,
+ PROP_WIMAX_ENABLED,
+ PROP_WIMAX_HARDWARE_ENABLED,
PROP_ACTIVE_CONNECTIONS,
/* Not exported */
@@ -292,17 +277,19 @@ enum {
LAST_PROP
};
-typedef enum
-{
+
+/************************************************************************/
+
+typedef enum {
NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0,
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
NM_MANAGER_ERROR_UNMANAGED_DEVICE,
- NM_MANAGER_ERROR_INVALID_SERVICE,
NM_MANAGER_ERROR_SYSTEM_CONNECTION,
NM_MANAGER_ERROR_PERMISSION_DENIED,
NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED,
+ NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE,
} NMManagerError;
#define NM_MANAGER_ERROR (nm_manager_error_quark ())
@@ -333,10 +320,6 @@ nm_manager_error_get_type (void)
ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_DEVICE, "UnknownDevice"),
/* Unmanaged device. */
ENUM_ENTRY (NM_MANAGER_ERROR_UNMANAGED_DEVICE, "UnmanagedDevice"),
- /* Invalid settings service (not a recognized system or user
- * settings service name)
- */
- ENUM_ENTRY (NM_MANAGER_ERROR_INVALID_SERVICE, "InvalidService"),
/* Connection was superceded by a system connection. */
ENUM_ENTRY (NM_MANAGER_ERROR_SYSTEM_CONNECTION, "SystemConnection"),
/* User does not have the permission to activate this connection. */
@@ -347,6 +330,8 @@ nm_manager_error_get_type (void)
ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "AlreadyAsleepOrAwake"),
/* The manager is already in the requested enabled/disabled state */
ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "AlreadyEnabledOrDisabled"),
+ /* The requested operation is unsupported for this type of connection */
+ ENUM_ENTRY (NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, "UnsupportedConnectionType"),
{ 0, 0, 0 },
};
etype = g_enum_register_static ("NMManagerError", values);
@@ -354,6 +339,36 @@ nm_manager_error_get_type (void)
return etype;
}
+/************************************************************************/
+
+static NMDevice *
+nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (udi != NULL, NULL);
+
+ for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
+ if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
+ return NM_DEVICE (iter->data);
+ }
+ return NULL;
+}
+
+static NMDevice *
+nm_manager_get_device_by_path (NMManager *manager, const char *path)
+{
+ GSList *iter;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
+ if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path))
+ return NM_DEVICE (iter->data);
+ }
+ return NULL;
+}
+
static gboolean
manager_sleeping (NMManager *self)
{
@@ -413,14 +428,8 @@ modem_added (NMModemManager *modem_manager,
return;
}
- /* Otherwise make a new top-level NMDevice for it */
- if (NM_IS_MODEM_GSM (modem))
- device = nm_device_gsm_new (NM_MODEM_GSM (modem), driver);
- else if (NM_IS_MODEM_CDMA (modem))
- device = nm_device_cdma_new (NM_MODEM_CDMA (modem), driver);
- else
- nm_log_info (LOGD_MB, "unhandled modem '%s'", ip_iface);
-
+ /* Make the new modem device */
+ device = nm_device_modem_new (modem, driver);
if (device)
add_device (self, device);
}
@@ -430,6 +439,7 @@ nm_manager_update_state (NMManager *manager)
{
NMManagerPrivate *priv;
NMState new_state = NM_STATE_DISCONNECTED;
+ GSList *iter;
g_return_if_fail (NM_IS_MANAGER (manager));
@@ -438,16 +448,21 @@ nm_manager_update_state (NMManager *manager)
if (manager_sleeping (manager))
new_state = NM_STATE_ASLEEP;
else {
- GSList *iter;
-
for (iter = priv->devices; iter; iter = iter->next) {
NMDevice *dev = NM_DEVICE (iter->data);
+ NMDeviceState state = nm_device_get_state (dev);
- if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
- new_state = NM_STATE_CONNECTED;
+ if (state == NM_DEVICE_STATE_ACTIVATED) {
+ /* FIXME: handle local-only and site too */
+ new_state = NM_STATE_CONNECTED_GLOBAL;
break;
- } else if (nm_device_is_activating (dev)) {
+ }
+
+ if (nm_device_is_activating (dev))
new_state = NM_STATE_CONNECTING;
+ else if (new_state != NM_STATE_CONNECTING) {
+ if (state == NM_DEVICE_STATE_DEACTIVATING)
+ new_state = NM_STATE_DISCONNECTING;
}
}
}
@@ -457,72 +472,7 @@ nm_manager_update_state (NMManager *manager)
g_object_notify (G_OBJECT (manager), NM_MANAGER_STATE);
g_signal_emit (manager, signals[STATE_CHANGED], 0, priv->state);
-
- /* Emit StateChange too for backwards compatibility */
- g_signal_emit (manager, signals[STATE_CHANGE], 0, priv->state);
- }
-}
-
-static void
-update_active_connection_timestamp (NMManager *manager, NMDevice *device)
-{
- NMActRequest *req;
- NMConnection *connection;
- NMSettingConnection *s_con;
- NMManagerPrivate *priv;
- const char *connection_uuid;
- guint64 timestamp;
- guint64 *ts_ptr;
- GKeyFile *timestamps_file;
- char *data, *tmp;
- gsize len;
- GError *error = NULL;
-
- g_return_if_fail (NM_IS_DEVICE (device));
-
- priv = NM_MANAGER_GET_PRIVATE (manager);
- req = nm_device_get_act_request (device);
- if (!req)
- return;
-
- connection = nm_act_request_get_connection (req);
- g_assert (connection);
-
- if (nm_connection_get_scope (connection) != NM_CONNECTION_SCOPE_SYSTEM)
- return;
-
- /* Update timestamp in connection's object data */
- timestamp = (guint64) time (NULL);
- ts_ptr = g_new (guint64, 1);
- *ts_ptr = timestamp;
- g_object_set_data_full (G_OBJECT (connection), NM_SYSCONFIG_SETTINGS_TIMESTAMP_TAG, ts_ptr, g_free);
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
- connection_uuid = nm_setting_connection_get_uuid (s_con);
-
- /* Save timestamp to timestamps database file */
- timestamps_file = g_key_file_new ();
- if (!g_key_file_load_from_file (timestamps_file, NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, &error)) {
- if (!(error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT))
- nm_log_warn (LOGD_SYS_SET, "error parsing timestamps file '%s': %s", NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, error->message);
- g_clear_error (&error);
- }
-
- tmp = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
- g_key_file_set_value (timestamps_file, "timestamps", connection_uuid, tmp);
- g_free (tmp);
-
- data = g_key_file_to_data (timestamps_file, &len, &error);
- if (data) {
- g_file_set_contents (NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, data, len, &error);
- g_free (data);
- }
- if (error) {
- nm_log_warn (LOGD_SYS_SET, "error saving timestamp: %s", error->message);
- g_error_free (error);
}
- g_key_file_free (timestamps_file);
}
static void
@@ -548,8 +498,14 @@ manager_device_state_changed (NMDevice *device,
nm_manager_update_state (manager);
- if (new_state == NM_DEVICE_STATE_ACTIVATED)
- update_active_connection_timestamp (manager, device);
+ if (new_state == NM_DEVICE_STATE_ACTIVATED) {
+ NMActRequest *req;
+
+ req = nm_device_get_act_request (device);
+ if (req)
+ nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)),
+ (guint64) time (NULL));
+ }
}
/* Removes a device from a device list; returns the start of the new device list */
@@ -578,7 +534,7 @@ remove_one_device (NMManager *manager,
g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager);
- nm_sysconfig_settings_device_removed (priv->sys_settings, device);
+ nm_settings_device_removed (priv->settings, device);
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device);
g_object_unref (device);
@@ -668,24 +624,44 @@ nm_manager_get_state (NMManager *manager)
return NM_MANAGER_GET_PRIVATE (manager)->state;
}
-static void
-emit_removed (gpointer key, gpointer value, gpointer user_data)
+static gboolean
+might_be_vpn (NMConnection *connection)
{
- NMManager *manager = NM_MANAGER (user_data);
- NMConnection *connection = NM_CONNECTION (value);
+ NMSettingConnection *s_con;
+ const char *ctype = NULL;
+
+ if (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN))
+ return TRUE;
- g_signal_emit (manager, signals[CONNECTION_REMOVED], 0,
- connection,
- nm_connection_get_scope (connection));
+ /* Make sure it's not a VPN, which we can't autocomplete yet */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if (s_con)
+ ctype = nm_setting_connection_get_connection_type (s_con);
+
+ return (g_strcmp0 (ctype, NM_SETTING_VPN_SETTING_NAME) == 0);
}
-static void
-nm_manager_pending_activation_remove (NMManager *self,
- PendingActivation *pending)
+static gboolean
+try_complete_vpn (NMConnection *connection, GSList *existing, GError **error)
{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ g_assert (might_be_vpn (connection) == TRUE);
+
+ if (!nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN)) {
+ g_set_error_literal (error,
+ NM_MANAGER_ERROR,
+ NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE,
+ "VPN connections require a 'vpn' setting");
+ return FALSE;
+ }
- priv->pending_activations = g_slist_remove (priv->pending_activations, pending);
+ nm_utils_complete_generic (connection,
+ NM_SETTING_VPN_SETTING_NAME,
+ existing,
+ _("VPN connection %d"),
+ NULL,
+ FALSE); /* No IPv6 by default for now */
+
+ return TRUE;
}
static PendingActivation *
@@ -693,18 +669,65 @@ pending_activation_new (NMManager *manager,
PolkitAuthority *authority,
DBusGMethodInvocation *context,
const char *device_path,
- NMConnectionScope scope,
const char *connection_path,
+ GHashTable *settings,
const char *specific_object_path,
- PendingActivationFunc callback)
+ PendingActivationFunc callback,
+ GError **error)
{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
PendingActivation *pending;
+ NMDevice *device = NULL;
+ NMConnection *connection = NULL;
+ GSList *all_connections = NULL;
+ gboolean success;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (authority != NULL, NULL);
g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (device_path != NULL, NULL);
- g_return_val_if_fail (connection_path != NULL, NULL);
+
+ /* A object path of "/" means NULL */
+ if (g_strcmp0 (specific_object_path, "/") == 0)
+ specific_object_path = NULL;
+ if (g_strcmp0 (device_path, "/") == 0)
+ device_path = NULL;
+
+ /* Create the partial connection from the given settings */
+ if (settings) {
+ if (device_path)
+ device = nm_manager_get_device_by_path (manager, device_path);
+ if (!device) {
+ g_set_error_literal (error,
+ NM_MANAGER_ERROR,
+ NM_MANAGER_ERROR_UNKNOWN_DEVICE,
+ "Device not found");
+ return NULL;
+ }
+
+ connection = nm_connection_new ();
+ nm_connection_replace_settings (connection, settings, NULL);
+
+ all_connections = nm_settings_get_connections (priv->settings);
+
+ if (might_be_vpn (connection)) {
+ /* Try to fill the VPN's connection setting and name at least */
+ success = try_complete_vpn (connection, all_connections, error);
+ } else {
+ /* Let each device subclass complete the connection */
+ success = nm_device_complete_connection (device,
+ connection,
+ specific_object_path,
+ all_connections,
+ error);
+ }
+ g_slist_free (all_connections);
+
+ if (success == FALSE) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ }
pending = g_slice_new0 (PendingActivation);
pending->manager = manager;
@@ -713,8 +736,8 @@ pending_activation_new (NMManager *manager,
pending->callback = callback;
pending->device_path = g_strdup (device_path);
- pending->scope = scope;
pending->connection_path = g_strdup (connection_path);
+ pending->connection = connection;
/* "/" is special-cased to NULL to get through D-Bus */
if (specific_object_path && strcmp (specific_object_path, "/"))
@@ -724,39 +747,6 @@ pending_activation_new (NMManager *manager,
}
static void
-pending_auth_user_done (NMAuthChain *chain,
- GError *error,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- PendingActivation *pending = user_data;
- NMAuthCallResult result;
-
- pending->chain = NULL;
-
- if (error) {
- pending->callback (pending, error);
- goto out;
- }
-
- /* Caller has had a chance to obtain authorization, so we only need to
- * check for 'yes' here.
- */
- result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS));
- if (result != NM_AUTH_CALL_RESULT_YES) {
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_PERMISSION_DENIED,
- "Not authorized to use user connections.");
- pending->callback (pending, error);
- g_error_free (error);
- } else
- pending->callback (pending, NULL);
-
-out:
- nm_auth_chain_unref (chain);
-}
-
-static void
pending_auth_net_done (NMAuthChain *chain,
GError *error,
DBusGMethodInvocation *context,
@@ -785,86 +775,33 @@ pending_auth_net_done (NMAuthChain *chain,
goto out;
}
- if (pending->scope == NM_CONNECTION_SCOPE_SYSTEM) {
- /* System connection and the user is authorized for that if they have
- * the network-control permission.
- */
- pending->callback (pending, NULL);
- } else {
- g_assert (pending->scope == NM_CONNECTION_SCOPE_USER);
-
- /* User connection, check the 'use-user-connections' permission */
- pending->chain = nm_auth_chain_new (pending->authority,
- pending->context,
- NULL,
- pending_auth_user_done,
- pending);
- nm_auth_chain_add_call (pending->chain,
- NM_AUTH_PERMISSION_USE_USER_CONNECTIONS,
- TRUE);
- }
+ pending->callback (pending, NULL);
out:
nm_auth_chain_unref (chain);
}
-static gboolean
-check_user_authorized (NMDBusManager *dbus_mgr,
- DBusGProxy *user_proxy,
- DBusGMethodInvocation *context,
- NMConnectionScope scope,
- gulong *out_sender_uid,
- const char **out_error_desc)
-{
- g_return_val_if_fail (dbus_mgr != NULL, FALSE);
- g_return_val_if_fail (context != NULL, FALSE);
- g_return_val_if_fail (out_sender_uid != NULL, FALSE);
- g_return_val_if_fail (out_error_desc != NULL, FALSE);
-
- *out_sender_uid = G_MAXULONG;
-
- /* Get the UID */
- if (!nm_auth_get_caller_uid (context, dbus_mgr, out_sender_uid, out_error_desc))
- return FALSE;
-
- /* root gets to do anything */
- if (0 == *out_sender_uid)
- return TRUE;
-
- /* Check whether the UID is authorized for user connections */
- if ( scope == NM_CONNECTION_SCOPE_USER
- && !nm_auth_uid_authorized (*out_sender_uid,
- dbus_mgr,
- user_proxy,
- out_error_desc))
- return FALSE;
-
- return TRUE;
-}
-
static void
pending_activation_check_authorized (PendingActivation *pending,
- NMDBusManager *dbus_mgr,
- DBusGProxy *user_proxy)
+ NMDBusManager *dbus_mgr)
{
- const char *error_desc = NULL;
+ char *error_desc = NULL;
gulong sender_uid = G_MAXULONG;
GError *error;
g_return_if_fail (pending != NULL);
g_return_if_fail (dbus_mgr != NULL);
- if (!check_user_authorized (dbus_mgr,
- user_proxy,
- pending->context,
- pending->scope,
- &sender_uid,
- &error_desc)) {
+ if (!nm_auth_get_caller_uid (pending->context,
+ dbus_mgr,
+ &sender_uid,
+ &error_desc)) {
error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
error_desc);
pending->callback (pending, error);
g_error_free (error);
+ g_free (error_desc);
return;
}
@@ -895,16 +832,22 @@ pending_activation_destroy (PendingActivation *pending,
{
g_return_if_fail (pending != NULL);
- if (pending->timeout_id)
- g_source_remove (pending->timeout_id);
+ if (error)
+ dbus_g_method_return_error (pending->context, error);
+ else if (ac_path) {
+ if (pending->connection) {
+ dbus_g_method_return (pending->context,
+ pending->connection_path,
+ ac_path);
+ } else
+ dbus_g_method_return (pending->context, ac_path);
+ }
+
g_free (pending->connection_path);
g_free (pending->specific_object_path);
g_free (pending->device_path);
-
- if (error)
- dbus_g_method_return_error (pending->context, error);
- else if (ac_path)
- dbus_g_method_return (pending->context, ac_path);
+ if (pending->connection)
+ g_object_unref (pending->connection);
if (pending->chain)
nm_auth_chain_unref (pending->chain);
@@ -946,577 +889,28 @@ get_active_connections (NMManager *manager, NMConnection *filter)
return active;
}
-static void
-remove_connection (NMManager *manager,
- NMConnection *connection,
- GHashTable *hash)
-{
- /* Destroys the connection, then associated DBusGProxy due to the
- * weak reference notify function placed on the connection when it
- * was created.
- */
- g_object_ref (connection);
- g_hash_table_remove (hash, nm_connection_get_path (connection));
- g_signal_emit (manager, signals[CONNECTION_REMOVED], 0,
- connection,
- nm_connection_get_scope (connection));
- g_object_unref (connection);
-
- bluez_manager_resync_devices (manager);
-}
-
-/*******************************************************************/
-/* User settings stuff via D-Bus */
-/*******************************************************************/
-
-static void
-user_proxy_cleanup (NMManager *self, gboolean resync_bt)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-
- if (priv->user_connections) {
- g_hash_table_foreach (priv->user_connections, emit_removed, self);
- g_hash_table_remove_all (priv->user_connections);
- }
-
- priv->user_net_perm = NM_AUTH_CALL_RESULT_UNKNOWN;
- priv->user_con_perm = NM_AUTH_CALL_RESULT_UNKNOWN;
-
- if (priv->user_proxy) {
- g_object_unref (priv->user_proxy);
- priv->user_proxy = NULL;
- }
-
- if (resync_bt) {
- /* Resync BT devices since they are generated from connections */
- bluez_manager_resync_devices (self);
- }
-}
-
-typedef struct GetSettingsInfo {
- NMManager *manager;
- NMConnection *connection;
- DBusGProxy *proxy;
- guint32 *calls;
-} GetSettingsInfo;
-
-static void
-free_get_settings_info (gpointer data)
-{
- GetSettingsInfo *info = (GetSettingsInfo *) data;
-
- /* If this was the last pending call for a batch of GetSettings calls,
- * send out the connections-added signal.
- */
- if (info->calls) {
- (*info->calls)--;
- if (*info->calls == 0) {
- g_slice_free (guint32, (gpointer) info->calls);
- g_signal_emit (info->manager, signals[CONNECTIONS_ADDED], 0, NM_CONNECTION_SCOPE_USER);
-
- /* Update the Bluetooth connections for all the new connections */
- bluez_manager_resync_devices (info->manager);
- }
- }
-
- if (info->manager) {
- g_object_unref (info->manager);
- info->manager = NULL;
- }
- if (info->connection) {
- g_object_unref (info->connection);
- info->connection = NULL;
- }
- if (info->proxy) {
- g_object_unref (info->proxy);
- info->proxy = NULL;
- }
-
- g_slice_free (GetSettingsInfo, data);
-}
-
-static void
-user_connection_get_settings_cb (DBusGProxy *proxy,
- DBusGProxyCall *call_id,
- gpointer user_data)
-{
- GetSettingsInfo *info = (GetSettingsInfo *) user_data;
- GError *err = NULL;
- GHashTable *settings = NULL;
- NMConnection *connection;
- NMManager *manager;
-
- g_return_if_fail (info != NULL);
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
- G_TYPE_INVALID)) {
- nm_log_info (LOGD_USER_SET, "couldn't retrieve connection settings: %s.",
- err && err->message ? err->message : "(unknown)");
- g_error_free (err);
- goto out;
- }
-
- manager = info->manager;
- connection = info->connection;
- if (connection == NULL) {
- const char *path = dbus_g_proxy_get_path (proxy);
- NMManagerPrivate *priv;
- GError *error = NULL;
- NMConnection *existing = NULL;
-
- connection = nm_connection_new_from_hash (settings, &error);
- if (connection == NULL) {
- nm_log_warn (LOGD_USER_SET, "invalid connection: '%s' / '%s' invalid: %d",
- g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
- error->message, error->code);
- g_error_free (error);
- goto out;
- }
-
- nm_connection_set_path (connection, path);
- nm_connection_set_scope (connection, NM_CONNECTION_SCOPE_USER);
-
- /* Add the new connection to the internal hashes only if the same
- * connection isn't already there.
- */
- priv = NM_MANAGER_GET_PRIVATE (manager);
-
- existing = g_hash_table_lookup (priv->user_connections, path);
- if (!existing || !nm_connection_compare (existing, connection, NM_SETTING_COMPARE_FLAG_EXACT)) {
- g_hash_table_insert (priv->user_connections,
- g_strdup (path),
- connection);
- existing = NULL;
-
- /* Attach the D-Bus proxy representing the remote NMConnection
- * to the local NMConnection object to ensure it stays alive to
- * continue delivering signals. It'll be destroyed once the
- * NMConnection is destroyed.
- */
- g_object_set_data_full (G_OBJECT (connection),
- "proxy",
- g_object_ref (info->proxy),
- g_object_unref);
- } else
- g_object_unref (connection);
-
- /* If the connection-added signal is supposed to be batched, don't
- * emit the single connection-added here. Also, don't emit the signal
- * if the connection wasn't actually added to the system or user hashes.
- */
- if (!info->calls && !existing) {
- g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, NM_CONNECTION_SCOPE_USER);
- /* Update the Bluetooth connections for that single new connection */
- bluez_manager_resync_devices (manager);
- }
- } else {
- // FIXME: merge settings? or just replace?
- nm_log_dbg (LOGD_USER_SET, "implement merge settings");
- }
-
-out:
- if (settings)
- g_hash_table_destroy (settings);
-
- return;
-}
-
-static void
-user_connection_removed_cb (DBusGProxy *proxy, gpointer user_data)
-{
- NMManager *manager = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- NMConnection *connection = NULL;
- const char *path;
-
- path = dbus_g_proxy_get_path (proxy);
- if (path) {
- connection = g_hash_table_lookup (priv->user_connections, path);
- if (connection)
- remove_connection (manager, connection, priv->user_connections);
- }
-}
-
-static void
-user_connection_updated_cb (DBusGProxy *proxy,
- GHashTable *settings,
- gpointer user_data)
-{
- NMManager *manager = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- NMConnection *new_connection;
- NMConnection *old_connection = NULL;
- gboolean valid = FALSE;
- GError *error = NULL;
- const char *path;
-
- path = dbus_g_proxy_get_path (proxy);
- if (path)
- old_connection = g_hash_table_lookup (priv->user_connections, path);
-
- g_return_if_fail (old_connection != NULL);
-
- new_connection = nm_connection_new_from_hash (settings, &error);
- if (!new_connection) {
- /* New connection invalid, remove existing connection */
- nm_log_warn (LOGD_USER_SET, "invalid connection: '%s' / '%s' invalid: %d",
- g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
- error->message, error->code);
- g_error_free (error);
- remove_connection (manager, old_connection, priv->user_connections);
- return;
- }
- g_object_unref (new_connection);
-
- valid = nm_connection_replace_settings (old_connection, settings, NULL);
- if (valid) {
- g_signal_emit (manager, signals[CONNECTION_UPDATED], 0,
- old_connection,
- nm_connection_get_scope (old_connection));
-
- bluez_manager_resync_devices (manager);
- } else {
- remove_connection (manager, old_connection, priv->user_connections);
- }
-}
-
-static void
-user_internal_new_connection_cb (NMManager *manager,
- const char *path,
- guint32 *counter)
-{
- GetSettingsInfo *info;
- DBusGProxy *con_proxy;
- DBusGConnection *g_connection;
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- con_proxy = dbus_g_proxy_new_for_name (g_connection,
- NM_DBUS_SERVICE_USER_SETTINGS,
- path,
- NM_DBUS_IFACE_SETTINGS_CONNECTION);
- if (!con_proxy) {
- nm_log_err (LOGD_USER_SET, "could not init user connection proxy");
- return;
- }
-
- dbus_g_proxy_add_signal (con_proxy, "Updated",
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (con_proxy, "Updated",
- G_CALLBACK (user_connection_updated_cb),
- manager,
- NULL);
-
- dbus_g_proxy_add_signal (con_proxy, "Removed", G_TYPE_INVALID, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (con_proxy, "Removed",
- G_CALLBACK (user_connection_removed_cb),
- manager,
- NULL);
-
- info = g_slice_new0 (GetSettingsInfo);
- info->manager = g_object_ref (manager);
- info->proxy = con_proxy;
- if (counter) {
- info->calls = counter;
- (*info->calls)++;
- }
- dbus_g_proxy_begin_call (con_proxy, "GetSettings",
- user_connection_get_settings_cb,
- info,
- free_get_settings_info,
- G_TYPE_INVALID);
-}
-
-static void
-user_list_connections_cb (DBusGProxy *proxy,
- DBusGProxyCall *call_id,
- gpointer user_data)
-{
- NMManager *manager = NM_MANAGER (user_data);
- GError *err = NULL;
- GPtrArray *ops;
- guint32 *counter = NULL;
- int i;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &ops,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_USER_SET, "couldn't retrieve connections: %s",
- err && err->message ? err->message : "(unknown)");
- g_clear_error (&err);
- return;
- }
-
- /* Keep track of all calls made here; don't want to emit connection-added for
- * each one, but emit connections-added when they are all done.
- */
- counter = g_slice_new0 (guint32);
- for (i = 0; i < ops->len; i++) {
- char *op = g_ptr_array_index (ops, i);
-
- user_internal_new_connection_cb (manager, op, counter);
- g_free (op);
- }
- g_ptr_array_free (ops, TRUE);
-}
-
-static void
-user_proxy_destroyed_cb (DBusGProxy *proxy, NMManager *self)
-{
- nm_log_dbg (LOGD_USER_SET, "Removing user connections...");
-
- /* At this point the user proxy is already being disposed */
- NM_MANAGER_GET_PRIVATE (self)->user_proxy = NULL;
-
- /* User Settings service disappeared; throw away user connections */
- user_proxy_cleanup (self, TRUE);
-}
-
-static void
-user_new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data)
-{
- user_internal_new_connection_cb (NM_MANAGER (user_data), path, NULL);
-}
-
-static gboolean
-user_settings_authorized (NMManager *self, NMAuthChain *chain)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- NMAuthCallResult old_net_perm = priv->user_net_perm;
- NMAuthCallResult old_con_perm = priv->user_con_perm;
-
- /* If the user could potentially get authorization to use networking and/or
- * to use user connections, the user settings service is authorized.
- */
- priv->user_net_perm = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL));
- priv->user_con_perm = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS));
-
- nm_log_dbg (LOGD_USER_SET, "User connections permissions: net %d, con %d",
- priv->user_net_perm, priv->user_con_perm);
-
- if (old_net_perm != priv->user_net_perm || old_con_perm != priv->user_con_perm)
- g_signal_emit (self, signals[USER_PERMISSIONS_CHANGED], 0);
-
- /* If the user can't control the network they certainly aren't allowed
- * to provide user connections.
- */
- if ( priv->user_net_perm == NM_AUTH_CALL_RESULT_UNKNOWN
- || priv->user_net_perm == NM_AUTH_CALL_RESULT_NO)
- return FALSE;
-
- /* And of course if they aren't allowed to use user connections, they can't
- * provide them either.
- */
- if ( priv->user_con_perm == NM_AUTH_CALL_RESULT_UNKNOWN
- || priv->user_con_perm == NM_AUTH_CALL_RESULT_NO)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-user_proxy_auth_done (NMAuthChain *chain,
- GError *error,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- gboolean authorized = FALSE;
-
- priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
-
- if (error) {
- nm_log_warn (LOGD_USER_SET, "User connections unavailable: (%d) %s",
- error->code, error->message ? error->message : "(unknown)");
- } else
- authorized = user_settings_authorized (self, chain);
-
- if (authorized) {
- /* If authorized, finish setting up the user settings service proxy */
- nm_log_dbg (LOGD_USER_SET, "Requesting user connections...");
-
- authorized = TRUE;
-
- dbus_g_proxy_add_signal (priv->user_proxy,
- "NewConnection",
- DBUS_TYPE_G_OBJECT_PATH,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->user_proxy, "NewConnection",
- G_CALLBACK (user_new_connection_cb),
- self,
- NULL);
-
- /* Clean up when the user settings proxy goes away */
- g_signal_connect (priv->user_proxy, "destroy",
- G_CALLBACK (user_proxy_destroyed_cb),
- self);
-
- /* Request user connections */
- dbus_g_proxy_begin_call (priv->user_proxy, "ListConnections",
- user_list_connections_cb,
- self,
- NULL,
- G_TYPE_INVALID);
- } else {
- /* Otherwise, we ignore the user settings service completely */
- user_proxy_cleanup (self, TRUE);
- }
-
- nm_auth_chain_unref (chain);
-}
-
-static void
-user_proxy_init (NMManager *self)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- DBusGConnection *bus;
- NMAuthChain *chain;
- GError *error = NULL;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (priv->user_proxy == NULL);
-
- /* Don't try to initialize the user settings proxy if the user
- * settings service doesn't actually exist.
- */
- if (!nm_dbus_manager_name_has_owner (priv->dbus_mgr, NM_DBUS_SERVICE_USER_SETTINGS))
- return;
-
- bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
- priv->user_proxy = dbus_g_proxy_new_for_name_owner (bus,
- NM_DBUS_SERVICE_USER_SETTINGS,
- NM_DBUS_PATH_SETTINGS,
- NM_DBUS_IFACE_SETTINGS,
- &error);
- if (!priv->user_proxy) {
- nm_log_err (LOGD_USER_SET, "could not init user settings proxy: (%d) %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- return;
- }
-
- /* Kick off some PolicyKit authorization requests to figure out what
- * permissions this user settings service has.
- */
- chain = nm_auth_chain_new (priv->authority,
- NULL,
- priv->user_proxy,
- user_proxy_auth_done,
- self);
- priv->auth_chains = g_slist_prepend (priv->auth_chains, chain);
-
- nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE);
- nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
-}
-
/*******************************************************************/
-/* System settings stuff via NMSysconfigSettings */
+/* Settings stuff via NMSettings */
/*******************************************************************/
static void
-system_connection_updated_cb (NMSettingsConnectionInterface *connection,
- gpointer unused,
- NMManager *manager)
+connections_changed (NMSettings *settings,
+ NMSettingsConnection *connection,
+ NMManager *manager)
{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- const char *path;
- NMSettingsConnectionInterface *existing;
- GError *error = NULL;
-
- path = nm_connection_get_path (NM_CONNECTION (connection));
-
- existing = g_hash_table_lookup (priv->system_connections, path);
- if (!existing)
- return;
- if (existing != connection) {
- nm_log_warn (LOGD_SYS_SET, "existing connection didn't matched updated.");
- return;
- }
-
- if (!nm_connection_verify (NM_CONNECTION (existing), &error)) {
- /* Updated connection invalid, remove existing connection */
- nm_log_warn (LOGD_SYS_SET, "invalid connection: '%s' / '%s' invalid: %d",
- g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
- error->message, error->code);
- g_error_free (error);
- remove_connection (manager, NM_CONNECTION (existing), priv->system_connections);
- return;
- }
-
- g_signal_emit (manager, signals[CONNECTION_UPDATED], 0,
- existing, NM_CONNECTION_SCOPE_SYSTEM);
-
bluez_manager_resync_devices (manager);
}
static void
-system_connection_removed_cb (NMSettingsConnectionInterface *connection,
- NMManager *manager)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- const char *path;
-
- path = nm_connection_get_path (NM_CONNECTION (connection));
-
- connection = g_hash_table_lookup (priv->system_connections, path);
- if (connection)
- remove_connection (manager, NM_CONNECTION (connection), priv->system_connections);
-}
-
-static void
-system_internal_new_connection (NMManager *manager,
- NMSettingsConnectionInterface *connection)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- const char *path;
-
- g_return_if_fail (connection != NULL);
-
- g_signal_connect (connection, NM_SETTINGS_CONNECTION_INTERFACE_UPDATED,
- G_CALLBACK (system_connection_updated_cb), manager);
- g_signal_connect (connection, NM_SETTINGS_CONNECTION_INTERFACE_REMOVED,
- G_CALLBACK (system_connection_removed_cb), manager);
-
- path = nm_connection_get_path (NM_CONNECTION (connection));
- g_hash_table_insert (priv->system_connections, g_strdup (path),
- g_object_ref (connection));
- g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, NM_CONNECTION_SCOPE_SYSTEM);
-}
-
-static void
-system_new_connection_cb (NMSysconfigSettings *settings,
- NMSettingsConnectionInterface *connection,
- NMManager *manager)
-{
- system_internal_new_connection (manager, connection);
-}
-
-static void
-system_query_connections (NMManager *manager)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- GSList *system_connections, *iter;
-
- system_connections = nm_settings_interface_list_connections (NM_SETTINGS_INTERFACE (priv->sys_settings));
- for (iter = system_connections; iter; iter = g_slist_next (iter))
- system_internal_new_connection (manager, NM_SETTINGS_CONNECTION_INTERFACE (iter->data));
- g_slist_free (system_connections);
-}
-
-static void
-system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings,
+system_unmanaged_devices_changed_cb (NMSettings *settings,
GParamSpec *pspec,
gpointer user_data)
{
- NMManager *manager = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
+ NMManager *self = NM_MANAGER (user_data);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
const GSList *unmanaged_specs, *iter;
- unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (sys_settings);
+ unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
NMDevice *device = NM_DEVICE (iter->data);
gboolean managed;
@@ -1525,30 +919,28 @@ system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings,
nm_device_set_managed (device,
managed,
managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED :
- NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
+ NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
}
}
static void
-system_hostname_changed_cb (NMSysconfigSettings *sys_settings,
+system_hostname_changed_cb (NMSettings *settings,
GParamSpec *pspec,
gpointer user_data)
{
- NMManager *manager = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
+ NMManager *self = NM_MANAGER (user_data);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
char *hostname;
- hostname = nm_sysconfig_settings_get_hostname (sys_settings);
-
+ hostname = nm_settings_get_hostname (priv->settings);
if (!hostname && !priv->hostname)
return;
-
if (hostname && priv->hostname && !strcmp (hostname, priv->hostname))
return;
g_free (priv->hostname);
priv->hostname = (hostname && strlen (hostname)) ? g_strdup (hostname) : NULL;
- g_object_notify (G_OBJECT (manager), NM_MANAGER_HOSTNAME);
+ g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME);
g_free (hostname);
}
@@ -1557,49 +949,6 @@ system_hostname_changed_cb (NMSysconfigSettings *sys_settings,
/* General NMManager stuff */
/*******************************************************************/
-static NMDevice *
-nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
-{
- GSList *iter;
-
- for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
- if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi))
- return NM_DEVICE (iter->data);
- }
- return NULL;
-}
-
-static NMDevice *
-nm_manager_get_device_by_path (NMManager *manager, const char *path)
-{
- GSList *iter;
-
- for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
- if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path))
- return NM_DEVICE (iter->data);
- }
- return NULL;
-}
-
-static void
-nm_manager_name_owner_changed (NMDBusManager *mgr,
- const char *name,
- const char *old,
- const char *new,
- gpointer user_data)
-{
- NMManager *manager = NM_MANAGER (user_data);
- gboolean old_owner_good = (old && (strlen (old) > 0));
- gboolean new_owner_good = (new && (strlen (new) > 0));
-
- if (strcmp (name, NM_DBUS_SERVICE_USER_SETTINGS) == 0) {
- if (!old_owner_good && new_owner_good)
- user_proxy_init (manager);
- else
- user_proxy_cleanup (manager, TRUE);
- }
-}
-
/* Store value into key-file; supported types: boolean, int, string */
static gboolean
write_value_to_state_file (const char *filename,
@@ -1701,6 +1050,7 @@ manager_hidden_ap_found (NMDeviceInterface *device,
gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
const struct ether_addr *ap_addr;
const GByteArray *ap_ssid;
GSList *iter;
@@ -1716,8 +1066,7 @@ manager_hidden_ap_found (NMDeviceInterface *device,
/* Look for this AP's BSSID in the seen-bssids list of a connection,
* and if a match is found, copy over the SSID */
- connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM);
- connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER));
+ connections = nm_settings_get_connections (priv->settings);
for (iter = connections; iter && !done; iter = g_slist_next (iter)) {
NMConnection *connection = NM_CONNECTION (iter->data);
@@ -1728,32 +1077,27 @@ manager_hidden_ap_found (NMDeviceInterface *device,
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
if (!s_wireless)
- goto next;
+ continue;
num_bssids = nm_setting_wireless_get_num_seen_bssids (s_wireless);
if (num_bssids < 1)
- goto next;
+ continue;
ssid = nm_setting_wireless_get_ssid (s_wireless);
g_assert (ssid);
- for (i = 0; i < num_bssids; i++) {
+ for (i = 0; i < num_bssids && !done; i++) {
const char *seen_bssid = nm_setting_wireless_get_seen_bssid (s_wireless, i);
struct ether_addr seen_addr;
- if (!ether_aton_r (seen_bssid, &seen_addr))
- continue;
-
- if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr)))
- continue;
-
- /* Copy the SSID from the connection to the AP */
- nm_ap_set_ssid (ap, ssid);
- done = TRUE;
+ if (ether_aton_r (seen_bssid, &seen_addr)) {
+ if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr))) {
+ /* Copy the SSID from the connection to the AP */
+ nm_ap_set_ssid (ap, ssid);
+ done = TRUE;
+ }
+ }
}
-
-next:
- g_object_unref (connection);
}
g_slist_free (connections);
}
@@ -1920,90 +1264,40 @@ deactivate_disconnect_check_error (GError *auth_error,
} else if (result != NM_AUTH_CALL_RESULT_YES) {
return g_error_new (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
- "Not authorized to %s user connections",
+ "Not authorized to %s connections",
detail);
}
return NULL;
}
static void
-disconnect_user_auth_done_cb (NMAuthChain *chain,
- GError *error,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GError *ret_error = NULL;
- NMAuthCallResult result;
- NMDevice *device;
-
- priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
-
- result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS));
- ret_error = deactivate_disconnect_check_error (error, result, "Disconnect");
- if (!ret_error) {
- /* Everything authorized, deactivate the connection */
- device = nm_auth_chain_get_data (chain, "device");
- if (nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error))
- dbus_g_method_return (context);
- }
-
- if (ret_error)
- dbus_g_method_return_error (context, ret_error);
- g_clear_error (&ret_error);
-
- nm_auth_chain_unref (chain);
-}
-
-static void
disconnect_net_auth_done_cb (NMAuthChain *chain,
- GError *error,
+ GError *auth_error,
DBusGMethodInvocation *context,
gpointer user_data)
{
NMManager *self = NM_MANAGER (user_data);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GError *ret_error = NULL;
+ GError *error = NULL;
NMAuthCallResult result;
- NMConnectionScope scope;
NMDevice *device;
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL));
- ret_error = deactivate_disconnect_check_error (error, result, "Disconnect");
- if (ret_error) {
- dbus_g_method_return_error (context, ret_error);
- g_error_free (ret_error);
- goto done;
+ error = deactivate_disconnect_check_error (auth_error, result, "Disconnect");
+ if (!error) {
+ device = nm_auth_chain_get_data (chain, "device");
+ if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &error))
+ g_assert (error);
}
- /* If it's a system connection, we're done */
- device = nm_auth_chain_get_data (chain, "device");
- scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope"));
- if (scope == NM_CONNECTION_SCOPE_USER) {
- NMAuthChain *user_chain;
-
- /* It's a user connection, so we need to ensure the caller is
- * authorized to manipulate user connections.
- */
- user_chain = nm_auth_chain_new (priv->authority, context, NULL, disconnect_user_auth_done_cb, self);
- g_assert (user_chain);
- priv->auth_chains = g_slist_append (priv->auth_chains, user_chain);
-
- nm_auth_chain_set_data (user_chain, "device", g_object_ref (device), g_object_unref);
- nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL);
- nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE);
- } else {
- if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) {
- dbus_g_method_return_error (context, ret_error);
- g_clear_error (&ret_error);
- } else
- dbus_g_method_return (context);
- }
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
-done:
+ g_clear_error (&error);
nm_auth_chain_unref (chain);
}
@@ -2014,11 +1308,9 @@ manager_device_disconnect_request (NMDevice *device,
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActRequest *req;
- NMConnection *connection;
GError *error = NULL;
- NMConnectionScope scope;
gulong sender_uid = G_MAXULONG;
- const char *error_desc = NULL;
+ char *error_desc = NULL;
req = nm_device_get_act_request (device);
if (!req) {
@@ -2030,24 +1322,19 @@ manager_device_disconnect_request (NMDevice *device,
return;
}
- connection = nm_act_request_get_connection (req);
- g_assert (connection);
-
/* Need to check the caller's permissions and stuff before we can
* deactivate the connection.
*/
- scope = nm_connection_get_scope (connection);
- if (!check_user_authorized (priv->dbus_mgr,
- priv->user_proxy,
- context,
- scope,
- &sender_uid,
- &error_desc)) {
+ if (!nm_auth_get_caller_uid (context,
+ priv->dbus_mgr,
+ &sender_uid,
+ &error_desc)) {
error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
error_desc);
dbus_g_method_return_error (context, error);
g_error_free (error);
+ g_free (error_desc);
return;
}
@@ -2067,7 +1354,6 @@ manager_device_disconnect_request (NMDevice *device,
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
- nm_auth_chain_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
}
}
@@ -2081,8 +1367,6 @@ add_device (NMManager *self, NMDevice *device)
static guint32 devcount = 0;
const GSList *unmanaged_specs;
NMConnection *existing = NULL;
- GHashTableIter iter;
- gpointer value;
gboolean managed = FALSE, enabled = FALSE;
iface = nm_device_get_ip_iface (device);
@@ -2137,6 +1421,12 @@ add_device (NMManager *self, NMDevice *device)
nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device),
priv->radio_states[RFKILL_TYPE_WWAN].enabled);
*/
+#if WITH_WIMAX
+ } else if (NM_IS_DEVICE_WIMAX (device)) {
+ nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX);
+ enabled = radio_enabled_for_type (self, RFKILL_TYPE_WIMAX);
+ nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled);
+#endif
}
type_desc = nm_device_get_type_desc (device);
@@ -2161,25 +1451,19 @@ add_device (NMManager *self, NMDevice *device)
if (nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device))) {
GSList *connections = NULL;
- g_hash_table_iter_init (&iter, priv->system_connections);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- connections = g_slist_append (connections, value);
+ connections = nm_settings_get_connections (priv->settings);
existing = nm_device_interface_connection_match_config (NM_DEVICE_INTERFACE (device),
(const GSList *) connections);
g_slist_free (connections);
- if (existing) {
- NMSettingConnection *s_con;
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (existing, NM_TYPE_SETTING_CONNECTION);
+ if (existing)
nm_log_dbg (LOGD_DEVICE, "(%s): found existing device connection '%s'",
nm_device_get_iface (device),
- nm_setting_connection_get_id (s_con));
- }
+ nm_connection_get_id (existing));
}
/* Start the device if it's supposed to be managed */
- unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings);
+ unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
if ( !manager_sleeping (self)
&& !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) {
nm_device_set_managed (device,
@@ -2189,7 +1473,7 @@ add_device (NMManager *self, NMDevice *device)
managed = TRUE;
}
- nm_sysconfig_settings_device_added (priv->sys_settings, device);
+ nm_settings_device_added (priv->settings, device);
g_signal_emit (self, signals[DEVICE_ADDED], 0, device);
/* If the device has a connection it can assume, do that now */
@@ -2200,12 +1484,11 @@ add_device (NMManager *self, NMDevice *device)
nm_log_dbg (LOGD_DEVICE, "(%s): will attempt to assume existing connection",
nm_device_get_iface (device));
- ac_path = internal_activate_device (self, device, existing, NULL, FALSE, TRUE, &error);
+ ac_path = internal_activate_device (self, device, existing, NULL, FALSE, 0, TRUE, &error);
if (ac_path)
g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS);
else {
- nm_log_warn (LOGD_DEVICE, "assumed connection (%d) %s failed to activate: (%d) %s",
- nm_connection_get_scope (existing),
+ nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s",
nm_connection_get_path (existing),
error ? error->code : -1,
error && error->message ? error->message : "(unknown)");
@@ -2245,11 +1528,11 @@ bluez_manager_find_connection (NMManager *manager,
const char *bdaddr,
guint32 capabilities)
{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
NMConnection *found = NULL;
GSList *connections, *l;
- connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM);
- connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER));
+ connections = nm_settings_get_connections (priv->settings);
for (l = connections; l != NULL; l = l->next) {
NMConnection *candidate = NM_CONNECTION (l->data);
@@ -2529,302 +1812,13 @@ nm_manager_get_act_request_by_path (NMManager *manager,
return NULL;
}
-typedef struct GetSecretsInfo {
- NMManager *manager;
- NMSecretsProviderInterface *provider;
-
- char *setting_name;
- RequestSecretsCaller caller;
- gboolean request_new;
-
- /* User connection bits */
- DBusGProxy *proxy;
- DBusGProxyCall *call;
-
- /* System connection bits */
- guint32 idle_id;
- char *hint1;
- char *hint2;
- char *connection_path;
-} GetSecretsInfo;
-
-static void
-free_get_secrets_info (gpointer data)
-{
- GetSecretsInfo *info = data;
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
-
- g_object_weak_unref (G_OBJECT (info->provider), (GWeakNotify) free_get_secrets_info, info);
-
- priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
-
- if (info->proxy) {
- if (info->call)
- dbus_g_proxy_cancel_call (info->proxy, info->call);
- g_object_unref (info->proxy);
- }
-
- if (info->idle_id)
- g_source_remove (info->idle_id);
-
- g_free (info->hint1);
- g_free (info->hint2);
- g_free (info->setting_name);
- g_free (info->connection_path);
- memset (info, 0, sizeof (GetSecretsInfo));
- g_free (info);
-}
-
-static void
-provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_data)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data);
- GSList *iter;
-
- for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
- GetSecretsInfo *candidate = iter->data;
-
- if (candidate->provider == provider) {
- free_get_secrets_info (candidate);
- break;
- }
- }
-}
-
-static void
-user_get_secrets_cb (DBusGProxy *proxy,
- DBusGProxyCall *call,
- gpointer user_data)
-{
- GetSecretsInfo *info = (GetSecretsInfo *) user_data;
- GHashTable *settings = NULL;
- GError *error = NULL;
- GObject *provider;
-
- g_return_if_fail (info != NULL);
- g_return_if_fail (info->provider);
- g_return_if_fail (info->setting_name);
-
- provider = g_object_ref (info->provider);
-
- if (dbus_g_proxy_end_call (proxy, call, &error,
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings,
- G_TYPE_INVALID)) {
- nm_secrets_provider_interface_get_secrets_result (info->provider,
- info->setting_name,
- info->caller,
- settings,
- NULL);
- g_hash_table_destroy (settings);
- } else {
- nm_secrets_provider_interface_get_secrets_result (info->provider,
- info->setting_name,
- info->caller,
- NULL,
- error);
- g_clear_error (&error);
- }
-
- info->call = NULL;
- free_get_secrets_info (info);
-
- g_object_unref (provider);
-}
-
-static GetSecretsInfo *
-user_get_secrets (NMManager *self,
- NMSecretsProviderInterface *provider,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller_id,
- const char *hint1,
- const char *hint2)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- DBusGConnection *g_connection;
- GetSecretsInfo *info = NULL;
- GPtrArray *hints = NULL;
-
- info = g_malloc0 (sizeof (GetSecretsInfo));
-
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- info->proxy = dbus_g_proxy_new_for_name (g_connection,
- NM_DBUS_SERVICE_USER_SETTINGS,
- nm_connection_get_path (connection),
- NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS);
- if (!info->proxy) {
- nm_log_warn (LOGD_USER_SET, "could not create user connection secrets proxy");
- g_free (info);
- return NULL;
- }
-
- info->manager = self;
- info->provider = provider;
- info->caller = caller_id;
- info->setting_name = g_strdup (setting_name);
-
- g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info);
-
- hints = g_ptr_array_sized_new (2);
- if (hint1)
- g_ptr_array_add (hints, (char *) hint1);
- if (hint2)
- g_ptr_array_add (hints, (char *) hint2);
-
- info->call = dbus_g_proxy_begin_call_with_timeout (info->proxy, "GetSecrets",
- user_get_secrets_cb,
- info,
- NULL,
- G_MAXINT32,
- G_TYPE_STRING, setting_name,
- DBUS_TYPE_G_ARRAY_OF_STRING, hints,
- G_TYPE_BOOLEAN, request_new,
- G_TYPE_INVALID);
- g_ptr_array_free (hints, TRUE);
- return info;
-}
-
-static void
-system_get_secrets_reply_cb (NMSettingsConnectionInterface *connection,
- GHashTable *secrets,
- GError *error,
- gpointer user_data)
-{
- GetSecretsInfo *info = user_data;
- GObject *provider;
-
- provider = g_object_ref (info->provider);
-
- nm_secrets_provider_interface_get_secrets_result (info->provider,
- info->setting_name,
- info->caller,
- error ? NULL : secrets,
- error);
- free_get_secrets_info (info);
- g_object_unref (provider);
-}
-
-static gboolean
-system_get_secrets_idle_cb (gpointer user_data)
-{
- GetSecretsInfo *info = user_data;
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
- NMSettingsConnectionInterface *connection;
- GError *error = NULL;
- const char *hints[3] = { NULL, NULL, NULL };
-
- info->idle_id = 0;
-
- connection = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (priv->sys_settings),
- info->connection_path);
- if (!connection) {
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
- "unknown connection (not exported by system settings)");
- nm_secrets_provider_interface_get_secrets_result (info->provider,
- info->setting_name,
- info->caller,
- NULL,
- error);
- g_error_free (error);
- free_get_secrets_info (info);
- return FALSE;
- }
-
- hints[0] = info->hint1;
- hints[1] = info->hint2;
- nm_settings_connection_interface_get_secrets (connection,
- info->setting_name,
- hints,
- info->request_new,
- system_get_secrets_reply_cb,
- info);
- return FALSE;
-}
-
-static GetSecretsInfo *
-system_get_secrets (NMManager *self,
- NMSecretsProviderInterface *provider,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller_id,
- const char *hint1,
- const char *hint2)
-{
- GetSecretsInfo *info;
-
- info = g_malloc0 (sizeof (GetSecretsInfo));
- info->manager = self;
- info->provider = provider;
- info->caller = caller_id;
- info->setting_name = g_strdup (setting_name);
- info->hint1 = hint1 ? g_strdup (hint1) : NULL;
- info->hint2 = hint2 ? g_strdup (hint2) : NULL;
- info->connection_path = g_strdup (nm_connection_get_path (connection));
- info->request_new = request_new;
-
- g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info);
-
- info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- system_get_secrets_idle_cb,
- info,
- NULL);
- return info;
-}
-
-static gboolean
-provider_get_secrets (NMSecretsProviderInterface *provider,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller_id,
- const char *hint1,
- const char *hint2,
- gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GetSecretsInfo *info = NULL;
- NMConnectionScope scope;
- GSList *iter;
-
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (setting_name != NULL, FALSE);
-
- /* Tear down any pending secrets requests for this secrets provider */
- for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
- GetSecretsInfo *candidate = iter->data;
-
- if (provider == candidate->provider) {
- free_get_secrets_info (candidate);
- break;
- }
- }
-
- /* Build up the new secrets request */
- scope = nm_connection_get_scope (connection);
- if (scope == NM_CONNECTION_SCOPE_SYSTEM) {
- info = system_get_secrets (self, provider, connection, setting_name,
- request_new, caller_id, hint1, hint2);
- } else if (scope == NM_CONNECTION_SCOPE_USER) {
- info = user_get_secrets (self, provider, connection, setting_name,
- request_new, caller_id, hint1, hint2);
- }
-
- if (info)
- priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
-
- return !!info;
-}
-
static const char *
internal_activate_device (NMManager *manager,
NMDevice *device,
NMConnection *connection,
const char *specific_object,
gboolean user_requested,
+ gulong sender_uid,
gboolean assumed,
GError **error)
{
@@ -2849,42 +1843,24 @@ internal_activate_device (NMManager *manager,
NM_DEVICE_STATE_REASON_NONE);
}
- req = nm_act_request_new (connection, specific_object, user_requested, assumed, (gpointer) device);
- g_signal_connect (req, "manager-get-secrets", G_CALLBACK (provider_get_secrets), manager);
- g_signal_connect (req, "manager-cancel-secrets", G_CALLBACK (provider_cancel_secrets), manager);
+ req = nm_act_request_new (connection,
+ specific_object,
+ user_requested,
+ sender_uid,
+ assumed,
+ (gpointer) device);
success = nm_device_interface_activate (dev_iface, req, error);
g_object_unref (req);
return success ? nm_act_request_get_active_connection_path (req) : NULL;
}
-static gboolean
-wait_for_connection_expired (gpointer data)
-{
- PendingActivation *pending = data;
- GError *error = NULL;
-
- g_return_val_if_fail (pending != NULL, FALSE);
-
- nm_log_warn (LOGD_CORE, "connection %s (scope %d) failed to activate (timeout)",
- pending->connection_path, pending->scope);
-
- nm_manager_pending_activation_remove (pending->manager, pending);
-
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
- "Connection was not provided by any settings service");
- pending_activation_destroy (pending, error, NULL);
- g_error_free (error);
- return FALSE;
-}
-
const char *
nm_manager_activate_connection (NMManager *manager,
NMConnection *connection,
const char *specific_object,
const char *device_path,
- gboolean user_requested,
+ const char *dbus_sender,
GError **error)
{
NMManagerPrivate *priv;
@@ -2892,6 +1868,8 @@ nm_manager_activate_connection (NMManager *manager,
NMSettingConnection *s_con;
NMVPNConnection *vpn_connection;
const char *path = NULL;
+ gulong sender_uid = 0;
+ DBusError dbus_error;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
@@ -2900,19 +1878,34 @@ nm_manager_activate_connection (NMManager *manager,
priv = NM_MANAGER_GET_PRIVATE (manager);
+ /* Get the UID of the user that originated the request, if any */
+ if (dbus_sender) {
+ dbus_error_init (&dbus_error);
+ sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr),
+ dbus_sender,
+ &dbus_error);
+ if (dbus_error_is_set (&dbus_error)) {
+ g_set_error_literal (error,
+ NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED,
+ "Failed to get unix user for dbus sender");
+ dbus_error_free (&dbus_error);
+ return NULL;
+ }
+ }
+
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
- NMActRequest *req = NULL;
+ NMActRequest *parent_req = NULL;
NMVPNManager *vpn_manager;
/* VPN connection */
if (specific_object) {
/* Find the specifc connection the client requested we use */
- req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
- if (!req) {
+ parent_req = nm_manager_get_act_request_by_path (manager, specific_object, &device);
+ if (!parent_req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
"%s", "Base connection for VPN connection not active.");
@@ -2929,13 +1922,13 @@ nm_manager_activate_connection (NMManager *manager,
candidate_req = nm_device_get_act_request (candidate);
if (candidate_req && nm_act_request_get_default (candidate_req)) {
device = candidate;
- req = candidate_req;
+ parent_req = candidate_req;
break;
}
}
}
- if (!device || !req) {
+ if (!device || !parent_req) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"%s", "Could not find source connection, or the source connection had no active device.");
@@ -2945,16 +1938,13 @@ nm_manager_activate_connection (NMManager *manager,
vpn_manager = nm_vpn_manager_get ();
vpn_connection = nm_vpn_manager_activate_connection (vpn_manager,
connection,
- req,
+ parent_req,
device,
+ TRUE,
+ sender_uid,
error);
- if (vpn_connection) {
- g_signal_connect (vpn_connection, "manager-get-secrets",
- G_CALLBACK (provider_get_secrets), manager);
- g_signal_connect (vpn_connection, "manager-cancel-secrets",
- G_CALLBACK (provider_cancel_secrets), manager);
+ if (vpn_connection)
path = nm_vpn_connection_get_active_connection_path (vpn_connection);
- }
g_object_unref (vpn_manager);
} else {
NMDeviceState state;
@@ -2980,7 +1970,8 @@ nm_manager_activate_connection (NMManager *manager,
device,
connection,
specific_object,
- user_requested,
+ dbus_sender ? TRUE : FALSE,
+ dbus_sender ? sender_uid : 0,
FALSE,
error);
}
@@ -2988,40 +1979,24 @@ nm_manager_activate_connection (NMManager *manager,
return path;
}
-static PendingActivation *
-nm_manager_pending_activation_find (NMManager *self,
- const char *path,
- NMConnectionScope scope)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GSList *iter;
-
- for (iter = priv->pending_activations; iter; iter = g_slist_next (iter)) {
- PendingActivation *pending = iter->data;
-
- if (!strcmp (pending->connection_path, path) && (pending->scope == scope))
- return pending;
- }
- return NULL;
-}
-
+/*
+ * TODO this function was created and named in the era of user settings, where
+ * we could get activation requests for a connection before we got the settings
+ * data of that connection. Now that user settings are gone, flatten or rename
+ * it.
+ */
static void
-check_pending_ready (NMManager *self, PendingActivation *pending)
+pending_activate (NMManager *self, PendingActivation *pending)
{
- NMConnection *connection;
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ NMSettingsConnection *connection;
const char *path = NULL;
GError *error = NULL;
+ char *sender;
- if (!pending->have_connection || !pending->authorized)
- return;
-
- /* Ok, we're authorized and the connection is available */
-
- nm_manager_pending_activation_remove (self, pending);
+ /* Ok, we're authorized */
- connection = nm_manager_get_connection_by_object_path (self,
- pending->scope,
- pending->connection_path);
+ connection = nm_settings_get_connection_by_path (priv->settings, pending->connection_path);
if (!connection) {
error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
@@ -3029,15 +2004,19 @@ check_pending_ready (NMManager *self, PendingActivation *pending)
goto out;
}
+ sender = dbus_g_method_get_sender (pending->context);
+ g_assert (sender);
path = nm_manager_activate_connection (self,
- connection,
+ NM_CONNECTION (connection),
pending->specific_object_path,
pending->device_path,
- TRUE,
+ sender,
&error);
+ g_free (sender);
+
if (!path) {
- nm_log_warn (LOGD_CORE, "connection (%d) %s failed to activate: (%d) %s",
- pending->scope, pending->connection_path, error->code, error->message);
+ nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s",
+ pending->connection_path, error->code, error->message);
} else
g_object_notify (G_OBJECT (pending->manager), NM_MANAGER_ACTIVE_CONNECTIONS);
@@ -3047,68 +2026,93 @@ out:
}
static void
-connection_added_default_handler (NMManager *self,
- NMConnection *connection,
- NMConnectionScope scope)
-{
- PendingActivation *pending;
-
- pending = nm_manager_pending_activation_find (self,
- nm_connection_get_path (connection),
- scope);
- if (pending) {
- pending->have_connection = TRUE;
- check_pending_ready (self, pending);
- }
-}
-
-static void
activation_auth_done (PendingActivation *pending, GError *error)
{
- if (error) {
- nm_manager_pending_activation_remove (pending->manager, pending);
+ if (error)
pending_activation_destroy (pending, error, NULL);
- return;
- } else {
- pending->authorized = TRUE;
-
- /* Now that we're authorized, if the connection hasn't shown up yet,
- * start a timer and wait for it.
- */
- if (!pending->have_connection && !pending->timeout_id)
- pending->timeout_id = g_timeout_add_seconds (5, wait_for_connection_expired, pending);
-
- check_pending_ready (pending->manager, pending);
- }
+ else
+ pending_activate (pending->manager, pending);
}
static void
impl_manager_activate_connection (NMManager *self,
- const char *service_name,
const char *connection_path,
const char *device_path,
const char *specific_object_path,
DBusGMethodInvocation *context)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- NMConnectionScope scope = NM_CONNECTION_SCOPE_UNKNOWN;
PendingActivation *pending;
GError *error = NULL;
- if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS))
- scope = NM_CONNECTION_SCOPE_USER;
- else if (!strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS))
- scope = NM_CONNECTION_SCOPE_SYSTEM;
+ /* Need to check the caller's permissions and stuff before we can
+ * activate the connection.
+ */
+ pending = pending_activation_new (self,
+ priv->authority,
+ context,
+ device_path,
+ connection_path,
+ NULL,
+ specific_object_path,
+ activation_auth_done,
+ &error);
+ if (pending)
+ pending_activation_check_authorized (pending, priv->dbus_mgr);
else {
- error = g_error_new_literal (NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_INVALID_SERVICE,
- "Invalid settings service name");
+ g_assert (error);
dbus_g_method_return_error (context, error);
- nm_log_warn (LOGD_CORE, "connection (%d) %s failed to activate: (%d) %s",
- scope, connection_path, error->code, error->message);
g_error_free (error);
- return;
}
+}
+
+static void
+activation_add_done (NMSettings *self,
+ NMSettingsConnection *connection,
+ GError *error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ PendingActivation *pending = user_data;
+
+ if (error)
+ pending_activation_destroy (pending, error, NULL);
+ else {
+ /* Save the new connection's D-Bus path */
+ pending->connection_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection)));
+
+ /* And activate it */
+ pending_activate (pending->manager, pending);
+ }
+}
+
+static void
+add_and_activate_auth_done (PendingActivation *pending, GError *error)
+{
+ if (error)
+ pending_activation_destroy (pending, error, NULL);
+ else {
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pending->manager);
+
+ /* Basic sender auth checks performed; try to add the connection */
+ nm_settings_add_connection (priv->settings,
+ pending->connection,
+ pending->context,
+ activation_add_done,
+ pending);
+ }
+}
+
+static void
+impl_manager_add_and_activate_connection (NMManager *self,
+ GHashTable *settings,
+ const char *device_path,
+ const char *specific_object_path,
+ DBusGMethodInvocation *context)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ PendingActivation *pending;
+ GError *error = NULL;
/* Need to check the caller's permissions and stuff before we can
* activate the connection.
@@ -3117,16 +2121,18 @@ impl_manager_activate_connection (NMManager *self,
priv->authority,
context,
device_path,
- scope,
- connection_path,
+ NULL,
+ settings,
specific_object_path,
- activation_auth_done);
- priv->pending_activations = g_slist_prepend (priv->pending_activations, pending);
-
- if (nm_manager_get_connection_by_object_path (self, scope, connection_path))
- pending->have_connection = TRUE;
-
- pending_activation_check_authorized (pending, priv->dbus_mgr, priv->user_proxy);
+ add_and_activate_auth_done,
+ &error);
+ if (pending)
+ pending_activation_check_authorized (pending, priv->dbus_mgr);
+ else {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
}
gboolean
@@ -3178,37 +2184,6 @@ done:
}
static void
-deactivate_user_auth_done_cb (NMAuthChain *chain,
- GError *error,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GError *ret_error = NULL;
- NMAuthCallResult result;
-
- priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
-
- result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS));
- ret_error = deactivate_disconnect_check_error (error, result, "Deactivate");
- if (!ret_error) {
- /* Everything authorized, deactivate the connection */
- if (nm_manager_deactivate_connection (self,
- nm_auth_chain_get_data (chain, "path"),
- NM_DEVICE_STATE_REASON_USER_REQUESTED,
- &ret_error))
- dbus_g_method_return (context);
- }
-
- if (ret_error)
- dbus_g_method_return_error (context, ret_error);
- g_clear_error (&ret_error);
-
- nm_auth_chain_unref (chain);
-}
-
-static void
deactivate_net_auth_done_cb (NMAuthChain *chain,
GError *error,
DBusGMethodInvocation *context,
@@ -3219,7 +2194,6 @@ deactivate_net_auth_done_cb (NMAuthChain *chain,
GError *ret_error = NULL;
NMAuthCallResult result;
const char *active_path;
- NMConnectionScope scope;
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
@@ -3231,32 +2205,15 @@ deactivate_net_auth_done_cb (NMAuthChain *chain,
goto done;
}
- /* If it's a system connection, we're done */
active_path = nm_auth_chain_get_data (chain, "path");
- scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope"));
- if (scope == NM_CONNECTION_SCOPE_USER) {
- NMAuthChain *user_chain;
-
- /* It's a user connection, so we need to ensure the caller is
- * authorized to manipulate user connections.
- */
- user_chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_user_auth_done_cb, self);
- g_assert (user_chain);
- priv->auth_chains = g_slist_append (priv->auth_chains, user_chain);
-
- nm_auth_chain_set_data (user_chain, "path", g_strdup (active_path), g_free);
- nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL);
- nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE);
- } else {
- if (!nm_manager_deactivate_connection (self,
- active_path,
- NM_DEVICE_STATE_REASON_USER_REQUESTED,
- &ret_error)) {
- dbus_g_method_return_error (context, ret_error);
- g_clear_error (&ret_error);
- } else
- dbus_g_method_return (context);
- }
+ if (!nm_manager_deactivate_connection (self,
+ active_path,
+ NM_DEVICE_STATE_REASON_USER_REQUESTED,
+ &ret_error)) {
+ dbus_g_method_return_error (context, ret_error);
+ g_clear_error (&ret_error);
+ } else
+ dbus_g_method_return (context);
done:
nm_auth_chain_unref (chain);
@@ -3273,8 +2230,7 @@ impl_manager_deactivate_connection (NMManager *self,
GSList *iter;
NMAuthChain *chain;
gulong sender_uid = G_MAXULONG;
- NMConnectionScope scope;
- const char *error_desc = NULL;
+ char *error_desc = NULL;
/* Check for device connections first */
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
@@ -3307,18 +2263,16 @@ impl_manager_deactivate_connection (NMManager *self,
/* Need to check the caller's permissions and stuff before we can
* deactivate the connection.
*/
- scope = nm_connection_get_scope (connection);
- if (!check_user_authorized (priv->dbus_mgr,
- priv->user_proxy,
- context,
- scope,
- &sender_uid,
- &error_desc)) {
+ if (!nm_auth_get_caller_uid (context,
+ priv->dbus_mgr,
+ &sender_uid,
+ &error_desc)) {
error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
error_desc);
dbus_g_method_return_error (context, error);
g_error_free (error);
+ g_free (error_desc);
return;
}
@@ -3342,7 +2296,6 @@ impl_manager_deactivate_connection (NMManager *self,
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
- nm_auth_chain_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
}
@@ -3366,7 +2319,7 @@ do_sleep_wake (NMManager *self)
} else {
nm_log_info (LOGD_SUSPEND, "waking up and re-enabling...");
- unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings);
+ unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings);
/* Ensure rfkill state is up-to-date since we don't respond to state
* changes during sleep.
@@ -3652,7 +2605,7 @@ impl_manager_enable (NMManager *self,
NMAuthChain *chain;
GError *error = NULL;
gulong sender_uid = G_MAXULONG;
- const char *error_desc = NULL;
+ char *error_desc = NULL;
g_return_if_fail (NM_IS_MANAGER (self));
@@ -3673,6 +2626,7 @@ impl_manager_enable (NMManager *self,
error_desc);
dbus_g_method_return_error (context, error);
g_error_free (error);
+ g_free (error_desc);
return;
}
@@ -3697,60 +2651,8 @@ impl_manager_enable (NMManager *self,
/* Permissions */
static void
-user_proxy_permissions_changed_done (NMAuthChain *chain,
- GError *error,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- gboolean authorized = FALSE;
-
- priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
-
- if (error) {
- nm_log_warn (LOGD_USER_SET, "User connections unavailable: (%d) %s",
- error->code, error->message ? error->message : "(unknown)");
- } else
- authorized = user_settings_authorized (self, chain);
-
- if (authorized) {
- /* User connections are authorized */
- if (!priv->user_proxy)
- user_proxy_init (self);
- } else
- user_proxy_cleanup (self, TRUE);
-
- nm_auth_chain_unref (chain);
-}
-
-static void
pk_authority_changed_cb (GObject *object, gpointer user_data)
{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- NMAuthChain *chain;
-
- /* If the user settings service wasn't previously authorized, we wouldn't
- * care about it. But it might be authorized now, so lets check.
- */
- if (!priv->user_proxy)
- user_proxy_init (self);
- else {
- /* Otherwise the user settings permissions could have changed so we
- * need to recheck them.
- */
- chain = nm_auth_chain_new (priv->authority,
- NULL,
- priv->user_proxy,
- user_proxy_permissions_changed_done,
- self);
- priv->auth_chains = g_slist_prepend (priv->auth_chains, chain);
-
- nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE);
- nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
- }
-
/* Let clients know they should re-check their authorization */
g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0);
}
@@ -3798,8 +2700,13 @@ get_permissions_done_cb (NMAuthChain *chain,
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SLEEP_WAKE);
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI);
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN);
- get_perm_add_result (chain, results, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX);
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN);
+ get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
dbus_g_method_return (context, results);
g_hash_table_destroy (results);
}
@@ -3825,31 +2732,20 @@ impl_manager_get_permissions (NMManager *self,
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
- nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE);
-}
-
-/* Legacy 0.6 compatibility interface */
-
-static void
-impl_manager_legacy_sleep (NMManager *manager, DBusGMethodInvocation *context)
-{
- return impl_manager_sleep (manager, TRUE, context);
-}
-
-static void
-impl_manager_legacy_wake (NMManager *manager, DBusGMethodInvocation *context)
-{
- return impl_manager_sleep (manager, FALSE, context);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE);
}
static gboolean
-impl_manager_legacy_state (NMManager *manager, guint32 *state, GError **err)
+impl_manager_get_state (NMManager *manager, guint32 *state, GError **error)
{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-
nm_manager_update_state (manager);
- *state = priv->state;
+ *state = NM_MANAGER_GET_PRIVATE (manager)->state;
return TRUE;
}
@@ -3871,115 +2767,6 @@ impl_manager_set_logging (NMManager *manager,
return FALSE;
}
-/* Connections */
-
-gboolean
-nm_manager_auto_user_connections_allowed (NMManager *self)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-
- return priv->user_net_perm == NM_AUTH_CALL_RESULT_YES
- && priv->user_con_perm == NM_AUTH_CALL_RESULT_YES;
-}
-
-static guint64
-get_connection_timestamp (NMConnection *connection)
-{
- if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
- guint64 *ts_p;
-
- ts_p = (guint64 *) g_object_get_data (G_OBJECT (connection), NM_SYSCONFIG_SETTINGS_TIMESTAMP_TAG);
- return ts_p != NULL ? *ts_p : 0;
- } else {
- NMSettingConnection *s_con;
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- return nm_setting_connection_get_timestamp (s_con);
- }
-}
-
-static int
-connection_sort (gconstpointer pa, gconstpointer pb)
-{
- NMConnection *a = NM_CONNECTION (pa);
- NMSettingConnection *con_a;
- NMConnection *b = NM_CONNECTION (pb);
- NMSettingConnection *con_b;
- guint64 ts_a, ts_b;
-
- con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION);
- g_assert (con_a);
- con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
- g_assert (con_b);
-
- if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) {
- if (nm_setting_connection_get_autoconnect (con_a))
- return -1;
- return 1;
- }
-
- ts_a = get_connection_timestamp (a);
- ts_b = get_connection_timestamp (b);
- if (ts_a > ts_b)
- return -1;
- else if (ts_a == ts_b)
- return 0;
-
- return 1;
-}
-
-static void
-connections_to_slist (gpointer key, gpointer value, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_insert_sorted (*list, g_object_ref (value), connection_sort);
-}
-
-/* Returns a GSList of referenced NMConnection objects, caller must
- * unref the connections in the list and destroy the list.
- */
-GSList *
-nm_manager_get_connections (NMManager *manager,
- NMConnectionScope scope)
-{
- NMManagerPrivate *priv;
- GSList *list = NULL;
-
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- priv = NM_MANAGER_GET_PRIVATE (manager);
- if (scope == NM_CONNECTION_SCOPE_USER)
- g_hash_table_foreach (priv->user_connections, connections_to_slist, &list);
- else if (scope == NM_CONNECTION_SCOPE_SYSTEM)
- g_hash_table_foreach (priv->system_connections, connections_to_slist, &list);
- else
- nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope);
- return list;
-}
-
-NMConnection *
-nm_manager_get_connection_by_object_path (NMManager *manager,
- NMConnectionScope scope,
- const char *path)
-{
- NMManagerPrivate *priv;
- NMConnection *connection = NULL;
-
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
- g_return_val_if_fail (path != NULL, NULL);
-
- priv = NM_MANAGER_GET_PRIVATE (manager);
- if (scope == NM_CONNECTION_SCOPE_USER)
- connection = (NMConnection *) g_hash_table_lookup (priv->user_connections, path);
- else if (scope == NM_CONNECTION_SCOPE_SYSTEM)
- connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path);
- else
- nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope);
- return connection;
-}
-
GPtrArray *
nm_manager_get_active_connections_by_connection (NMManager *manager,
NMConnection *connection)
@@ -4017,15 +2804,8 @@ nm_manager_start (NMManager *self)
nm_log_info (LOGD_CORE, "Networking is %s by state file",
priv->net_enabled ? "enabled" : "disabled");
- system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self);
- system_hostname_changed_cb (priv->sys_settings, NULL, self);
- system_query_connections (self);
-
- /* Get user connections if the user settings service is around, otherwise
- * they will be queried when the user settings service shows up on the
- * bus in nm_manager_name_owner_changed().
- */
- user_proxy_init (self);
+ system_unmanaged_devices_changed_cb (priv->settings, NULL, self);
+ system_hostname_changed_cb (priv->settings, NULL, self);
nm_udev_manager_query_devices (priv->udev_mgr);
bluez_manager_resync_devices (self);
@@ -4194,6 +2974,9 @@ prop_filter (DBusConnection *connection,
} else if (!strcmp (propname, "WwanEnabled")) {
glib_propname = NM_MANAGER_WWAN_ENABLED;
permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN;
+ } else if (!strcmp (propname, "WimaxEnabled")) {
+ glib_propname = NM_MANAGER_WIMAX_ENABLED;
+ permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX;
} else
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -4246,12 +3029,14 @@ out:
}
NMManager *
-nm_manager_get (const char *config_file,
+nm_manager_get (NMSettings *settings,
+ const char *config_file,
const char *plugins,
const char *state_file,
gboolean initial_net_enabled,
gboolean initial_wifi_enabled,
gboolean initial_wwan_enabled,
+ gboolean initial_wimax_enabled,
GError **error)
{
static NMManager *singleton = NULL;
@@ -4262,6 +3047,8 @@ nm_manager_get (const char *config_file,
if (singleton)
return g_object_ref (singleton);
+ g_assert (settings);
+
singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL);
g_assert (singleton);
@@ -4278,37 +3065,31 @@ nm_manager_get (const char *config_file,
return NULL;
}
- priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, bus, error);
- if (!priv->sys_settings) {
- g_object_unref (singleton);
- return NULL;
- }
- nm_settings_service_export (NM_SETTINGS_SERVICE (priv->sys_settings));
+ priv->settings = g_object_ref (settings);
priv->config_file = g_strdup (config_file);
-
priv->state_file = g_strdup (state_file);
priv->net_enabled = initial_net_enabled;
priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled;
priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled;
+ priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = initial_wimax_enabled;
- g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
+ g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
- g_signal_connect (priv->sys_settings, "notify::" NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME,
+ g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
G_CALLBACK (system_hostname_changed_cb), singleton);
- g_signal_connect (priv->sys_settings, "new-connection",
- G_CALLBACK (system_new_connection_cb), singleton);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
+ G_CALLBACK (connections_changed), singleton);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
+ G_CALLBACK (connections_changed), singleton);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
+ G_CALLBACK (connections_changed), singleton);
+ g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
+ G_CALLBACK (connections_changed), singleton);
- dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr),
- NM_DBUS_PATH,
- G_OBJECT (singleton));
-
- g_signal_connect (priv->dbus_mgr,
- "name-owner-changed",
- G_CALLBACK (nm_manager_name_owner_changed),
- singleton);
+ dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton));
priv->udev_mgr = nm_udev_manager_new ();
g_signal_connect (priv->udev_mgr,
@@ -4344,7 +3125,6 @@ dispose (GObject *object)
{
NMManager *manager = NM_MANAGER (object);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- GSList *iter;
DBusGConnection *bus;
DBusConnection *dbus_connection;
@@ -4354,18 +3134,10 @@ dispose (GObject *object)
}
priv->disposed = TRUE;
- for (iter = priv->pending_activations; iter; iter = g_slist_next (iter))
- pending_activation_destroy ((PendingActivation *) iter->data, NULL, NULL);
- g_slist_free (priv->pending_activations);
- priv->pending_activations = NULL;
-
g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL);
g_slist_free (priv->auth_chains);
g_object_unref (priv->authority);
- while (g_slist_length (priv->secrets_calls))
- free_get_secrets_info ((GetSecretsInfo *) priv->secrets_calls->data);
-
while (g_slist_length (priv->devices)) {
priv->devices = remove_one_device (manager,
priv->devices,
@@ -4373,22 +3145,10 @@ dispose (GObject *object)
TRUE);
}
- user_proxy_cleanup (manager, FALSE);
- g_hash_table_destroy (priv->user_connections);
- priv->user_connections = NULL;
-
- g_hash_table_foreach (priv->system_connections, emit_removed, manager);
- g_hash_table_remove_all (priv->system_connections);
- g_hash_table_destroy (priv->system_connections);
- priv->system_connections = NULL;
-
g_free (priv->hostname);
g_free (priv->config_file);
- if (priv->sys_settings) {
- g_object_unref (priv->sys_settings);
- priv->sys_settings = NULL;
- }
+ g_object_unref (priv->settings);
if (priv->vpn_manager_id) {
g_source_remove (priv->vpn_manager_id);
@@ -4501,6 +3261,11 @@ set_property (GObject *object, guint prop_id,
&priv->radio_states[RFKILL_TYPE_WWAN],
g_value_get_boolean (value));
break;
+ case PROP_WIMAX_ENABLED:
+ manager_radio_user_toggled (NM_MANAGER (object),
+ &priv->radio_states[RFKILL_TYPE_WIMAX],
+ g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4537,6 +3302,12 @@ get_property (GObject *object, guint prop_id,
case PROP_WWAN_HARDWARE_ENABLED:
g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled);
break;
+ case PROP_WIMAX_ENABLED:
+ g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WIMAX));
+ break;
+ case PROP_WIMAX_HARDWARE_ENABLED:
+ g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled);
+ break;
case PROP_ACTIVE_CONNECTIONS:
g_value_take_boxed (value, get_active_connections (self, NULL));
break;
@@ -4568,7 +3339,8 @@ periodic_update_active_connection_timestamps (gpointer user_data)
req = nm_manager_get_act_request_by_path (manager, active_path, &device);
if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
- update_active_connection_timestamp (manager, device);
+ nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (nm_act_request_get_connection (req)),
+ (guint64) time (NULL));
}
return TRUE;
@@ -4604,8 +3376,8 @@ nm_manager_init (NMManager *manager)
priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE;
priv->radio_states[RFKILL_TYPE_WIMAX].key = "WiMAXEnabled";
- priv->radio_states[RFKILL_TYPE_WIMAX].prop = NULL;
- priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NULL;
+ priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED;
+ priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED;
priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX";
priv->radio_states[RFKILL_TYPE_WIMAX].other_enabled_func = NULL;
priv->radio_states[RFKILL_TYPE_WIMAX].rtype = RFKILL_TYPE_WIMAX;
@@ -4618,16 +3390,6 @@ nm_manager_init (NMManager *manager)
priv->dbus_mgr = nm_dbus_manager_get ();
- priv->user_connections = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_object_unref);
-
- priv->system_connections = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_object_unref);
-
priv->modem_manager = nm_modem_manager_get ();
priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added",
G_CALLBACK (modem_added), manager);
@@ -4725,8 +3487,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
/* virtual methods */
- manager_class->connection_added = connection_added_default_handler;
-
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->dispose = dispose;
@@ -4789,6 +3549,22 @@ nm_manager_class_init (NMManagerClass *manager_class)
G_PARAM_READABLE));
g_object_class_install_property
+ (object_class, PROP_WIMAX_ENABLED,
+ g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED,
+ "WimaxEnabled",
+ "Is WiMAX enabled",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_WIMAX_HARDWARE_ENABLED,
+ g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED,
+ "WimaxHardwareEnabled",
+ "Whether WiMAX is disabled by a hardware switch or not",
+ TRUE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
(object_class, PROP_ACTIVE_CONNECTIONS,
g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS,
"Active connections",
@@ -4846,42 +3622,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMManagerClass, properties_changed));
- signals[CONNECTIONS_ADDED] =
- g_signal_new ("connections-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, connections_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
- signals[CONNECTION_ADDED] =
- g_signal_new ("connection-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, connection_added),
- NULL, NULL,
- _nm_marshal_VOID__OBJECT_UINT,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT);
-
- signals[CONNECTION_UPDATED] =
- g_signal_new ("connection-updated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, connection_updated),
- NULL, NULL,
- _nm_marshal_VOID__OBJECT_UINT,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT);
-
- signals[CONNECTION_REMOVED] =
- g_signal_new ("connection-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, connection_removed),
- NULL, NULL,
- _nm_marshal_VOID__OBJECT_UINT,
- G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT);
-
signals[CHECK_PERMISSIONS] =
g_signal_new ("check-permissions",
G_OBJECT_CLASS_TYPE (object_class),
@@ -4898,15 +3638,6 @@ nm_manager_class_init (NMManagerClass *manager_class)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- /* StateChange is DEPRECATED */
- signals[STATE_CHANGE] =
- g_signal_new ("state-change",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
&dbus_glib_nm_manager_object_info);
diff --git a/src/nm-manager.h b/src/nm-manager.h
index 280d554b2..22bfca9e8 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -20,13 +20,14 @@
*/
#ifndef NM_MANAGER_H
-#define NM_MANAGER_H 1
+#define NM_MANAGER_H
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "nm-device.h"
#include "nm-device-interface.h"
+#include "nm-settings.h"
#define NM_TYPE_MANAGER (nm_manager_get_type ())
#define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager))
@@ -42,6 +43,8 @@
#define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
#define NM_MANAGER_WWAN_ENABLED "wwan-enabled"
#define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled"
+#define NM_MANAGER_WIMAX_ENABLED "wimax-enabled"
+#define NM_MANAGER_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled"
#define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections"
/* Not exported */
@@ -60,30 +63,18 @@ typedef struct {
void (*device_removed) (NMManager *manager, NMDevice *device);
void (*state_changed) (NMManager *manager, guint state);
void (*properties_changed) (NMManager *manager, GHashTable *properties);
-
- void (*connections_added) (NMManager *manager, NMConnectionScope scope);
-
- void (*connection_added) (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope);
-
- void (*connection_updated) (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope);
-
- void (*connection_removed) (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope);
} NMManagerClass;
GType nm_manager_get_type (void);
-NMManager *nm_manager_get (const char *config_file,
+NMManager *nm_manager_get (NMSettings *settings,
+ const char *config_file,
const char *plugins,
const char *state_file,
gboolean initial_net_enabled,
gboolean initial_wifi_enabled,
gboolean initial_wwan_enabled,
+ gboolean initial_wimax_enabled,
GError **error);
void nm_manager_start (NMManager *manager);
@@ -96,7 +87,7 @@ const char * nm_manager_activate_connection (NMManager *manager,
NMConnection *connection,
const char *specific_object,
const char *device_path,
- gboolean user_requested,
+ const char *dbus_sender, /* NULL if automatic */
GError **error);
gboolean nm_manager_deactivate_connection (NMManager *manager,
@@ -108,16 +99,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager,
NMState nm_manager_get_state (NMManager *manager);
-/* Connections */
-
-GSList *nm_manager_get_connections (NMManager *manager, NMConnectionScope scope);
-
-gboolean nm_manager_auto_user_connections_allowed (NMManager *manager);
-
-NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager,
- NMConnectionScope scope,
- const char *path);
-
GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager,
NMConnection *connection);
diff --git a/src/nm-policy.c b/src/nm-policy.c
index aed2f897b..fcada5454 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -36,6 +36,9 @@
#include "nm-device-wifi.h"
#include "nm-device-ethernet.h"
#include "nm-device-modem.h"
+#if WITH_WIMAX
+#include "nm-device-wimax.h"
+#endif
#include "nm-dbus-manager.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-connection.h"
@@ -48,13 +51,16 @@ struct NMPolicy {
NMManager *manager;
guint update_state_id;
GSList *pending_activation_checks;
- GSList *signal_ids;
- GSList *dev_signal_ids;
+ GSList *manager_ids;
+ GSList *settings_ids;
+ GSList *dev_ids;
NMVPNManager *vpn_manager;
gulong vpn_activated_id;
gulong vpn_deactivated_id;
+ NMSettings *settings;
+
NMDevice *default_device4;
NMDevice *default_device6;
@@ -64,20 +70,8 @@ struct NMPolicy {
char *cur_hostname; /* hostname we want to assign */
};
-#define INVALID_TAG "invalid"
-
-static const char *
-get_connection_id (NMConnection *connection)
-{
- NMSettingConnection *s_con;
-
- g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
- g_return_val_if_fail (s_con != NULL, NULL);
-
- return nm_setting_connection_get_id (s_con);
-}
+#define RETRIES_TAG "autoconnect-retries"
+#define RETRIES_DEFAULT 4
static NMDevice *
get_best_ip4_device (NMManager *manager, NMActRequest **out_req)
@@ -287,7 +281,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6)
/* Hostname precedence order:
*
- * 1) a configured hostname (from system-settings)
+ * 1) a configured hostname (from settings)
* 2) automatic hostname from the default device's config (DHCP, VPN, etc)
* 3) the original hostname when NM started
* 4) reverse-DNS of the best device's IPv4 address
@@ -476,7 +470,6 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
}
- g_object_unref (candidate);
}
g_slist_free (vpns);
@@ -601,7 +594,6 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
dns_type = NM_DNS_IP_CONFIG_TYPE_VPN;
}
- g_object_unref (candidate);
}
g_slist_free (vpns);
#endif
@@ -674,6 +666,20 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
update_system_hostname (policy, policy->default_device4, policy->default_device6);
}
+static void
+set_connection_auto_retries (NMConnection *connection, guint retries)
+{
+ /* add +1 so that the tag still exists if the # retries is 0 */
+ g_object_set_data (G_OBJECT (connection), RETRIES_TAG, GUINT_TO_POINTER (retries + 1));
+}
+
+static guint32
+get_connection_auto_retries (NMConnection *connection)
+{
+ /* subtract 1 to handle the +1 from set_connection_auto_retries() */
+ return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), RETRIES_TAG)) - 1;
+}
+
typedef struct {
NMPolicy *policy;
NMDevice *device;
@@ -699,23 +705,21 @@ auto_activate_device (gpointer user_data)
if (nm_device_get_act_request (data->device))
goto out;
- /* System connections first, then user connections */
- connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_SYSTEM);
- if (nm_manager_auto_user_connections_allowed (policy->manager))
- connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_USER));
+ iter = connections = nm_settings_get_connections (policy->settings);
- /* Remove connections that are in the invalid list. */
- iter = connections;
+ /* Remove connections that shouldn't be auto-activated */
while (iter) {
- NMConnection *iter_connection = NM_CONNECTION (iter->data);
- GSList *next = g_slist_next (iter);
+ NMConnection *candidate = NM_CONNECTION (iter->data);
- if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) {
- connections = g_slist_remove_link (connections, iter);
- g_object_unref (iter_connection);
- g_slist_free (iter);
- }
- iter = next;
+ /* Grab next item before we possibly delete the current item */
+ iter = g_slist_next (iter);
+
+ /* Ignore connections that were tried too many times or are not visible
+ * to any logged-in users.
+ */
+ if ( get_connection_auto_retries (candidate) == 0
+ || nm_settings_connection_is_visible (NM_SETTINGS_CONNECTION (candidate)) == FALSE)
+ connections = g_slist_remove (connections, candidate);
}
best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object);
@@ -726,20 +730,14 @@ auto_activate_device (gpointer user_data)
best_connection,
specific_object,
nm_device_get_path (data->device),
- FALSE,
+ NULL,
&error)) {
- NMSettingConnection *s_con;
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (best_connection, NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
-
nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation failed: (%d) %s",
- nm_setting_connection_get_id (s_con), error->code, error->message);
+ nm_connection_get_id (best_connection), error->code, error->message);
g_error_free (error);
}
}
- g_slist_foreach (connections, (GFunc) g_object_unref, NULL);
g_slist_free (connections);
out:
@@ -785,18 +783,18 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
static void
sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
{
+ NMPolicy *policy = user_data;
gboolean sleeping = FALSE, enabled = FALSE;
GSList *connections, *iter;
g_object_get (G_OBJECT (manager), NM_MANAGER_SLEEPING, &sleeping, NULL);
g_object_get (G_OBJECT (manager), NM_MANAGER_NETWORKING_ENABLED, &enabled, NULL);
- /* Clear the invalid flag on all connections so they'll get retried on wakeup */
+ /* Reset retries on all connections so they'll checked on wakeup */
if (sleeping || !enabled) {
- connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM);
- connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER));
+ connections = nm_settings_get_connections (policy->settings);
for (iter = connections; iter; iter = g_slist_next (iter))
- g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL);
+ set_connection_auto_retries (NM_CONNECTION (iter->data), RETRIES_DEFAULT);
g_slist_free (connections);
}
}
@@ -861,16 +859,32 @@ device_state_changed (NMDevice *device,
* it doesn't get automatically chosen over and over and over again.
*/
if (connection && IS_ACTIVATING_STATE (old_state)) {
- g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
- nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
+ guint32 tries = get_connection_auto_retries (connection);
+
+ if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) {
+ /* If the connection couldn't get the secrets it needed (ex because
+ * the user canceled, or no secrets exist), there's no point in
+ * automatically retrying because it's just going to fail anyway.
+ */
+ set_connection_auto_retries (connection, 0);
+ } else if (tries > 0) {
+ /* Otherwise if it's a random failure, just decrease the number
+ * of automatic retries so that the connection gets tried again
+ * if it still has a retry count.
+ */
+ set_connection_auto_retries (connection, tries - 1);
+ }
+
+ if (get_connection_auto_retries (connection) == 0)
+ nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", nm_connection_get_id (connection));
nm_connection_clear_secrets (connection);
}
schedule_activate_check (policy, device, 3);
break;
case NM_DEVICE_STATE_ACTIVATED:
if (connection) {
- /* Clear the invalid tag on the connection */
- g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
+ /* Reset auto retries back to default since connection was successful */
+ set_connection_auto_retries (connection, RETRIES_DEFAULT);
/* And clear secrets so they will always be requested from the
* settings service when the next connection is made.
@@ -905,56 +919,48 @@ wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer use
schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0);
}
+#if WITH_WIMAX
+static void
+nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data)
+{
+ schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0);
+}
+#endif
+
typedef struct {
gulong id;
NMDevice *device;
-} DeviceSignalID;
+} DeviceSignalId;
-static GSList *
-add_device_signal_id (GSList *list, gulong id, NMDevice *device)
+static void
+_connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback)
{
- DeviceSignalID *data;
-
- data = g_malloc0 (sizeof (DeviceSignalID));
- if (!data)
- return list;
+ DeviceSignalId *data;
- data->id = id;
+ data = g_slice_new0 (DeviceSignalId);
+ g_assert (data);
+ data->id = g_signal_connect (device, name, callback, policy);
data->device = device;
- return g_slist_append (list, data);
+ policy->dev_ids = g_slist_prepend (policy->dev_ids, data);
}
static void
device_added (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
- gulong id;
-
- id = g_signal_connect (device, "state-changed",
- G_CALLBACK (device_state_changed),
- policy);
- policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
- id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
- G_CALLBACK (device_ip_config_changed),
- policy);
- policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
-
- id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG,
- G_CALLBACK (device_ip_config_changed),
- policy);
- policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
+ _connect_device_signal (policy, device, "state-changed", device_state_changed);
+ _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, device_ip_config_changed);
+ _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG, device_ip_config_changed);
if (NM_IS_DEVICE_WIFI (device)) {
- id = g_signal_connect (device, "access-point-added",
- G_CALLBACK (wireless_networks_changed),
- policy);
- policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
-
- id = g_signal_connect (device, "access-point-removed",
- G_CALLBACK (wireless_networks_changed),
- policy);
- policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
+ _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed);
+ _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed);
+#if WITH_WIMAX
+ } else if (NM_IS_DEVICE_WIMAX (device)) {
+ _connect_device_signal (policy, device, "nsp-added", nsps_changed);
+ _connect_device_signal (policy, device, "nsp-removed", nsps_changed);
+#endif
}
}
@@ -980,15 +986,15 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
}
/* Clear any signal handlers for this device */
- iter = policy->dev_signal_ids;
+ iter = policy->dev_ids;
while (iter) {
- DeviceSignalID *data = (DeviceSignalID *) iter->data;
+ DeviceSignalId *data = iter->data;
GSList *next = g_slist_next (iter);
if (data->device == device) {
g_signal_handler_disconnect (data->device, data->id);
- g_free (data);
- policy->dev_signal_ids = g_slist_delete_link (policy->dev_signal_ids, iter);
+ g_slice_free (DeviceSignalId, data);
+ policy->dev_ids = g_slist_delete_link (policy->dev_ids, iter);
}
iter = next;
}
@@ -1007,48 +1013,38 @@ schedule_activate_all (NMPolicy *policy)
}
static void
-connections_added (NMManager *manager,
- NMConnectionScope scope,
- gpointer user_data)
+connection_added (NMSettings *settings,
+ NMConnection *connection,
+ gpointer user_data)
{
+ set_connection_auto_retries (connection, RETRIES_DEFAULT);
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-connection_added (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope,
- gpointer user_data)
+connections_loaded (NMSettings *settings,
+ gpointer user_data)
{
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-connection_updated (NMManager *manager,
+connection_updated (NMSettings *settings,
NMConnection *connection,
- NMConnectionScope scope,
gpointer user_data)
{
- /* Clear the invalid tag on the connection if it got updated. */
- g_object_set_data (G_OBJECT (connection), INVALID_TAG, NULL);
+ /* Reset auto retries back to default since connection was updated */
+ set_connection_auto_retries (connection, RETRIES_DEFAULT);
schedule_activate_all ((NMPolicy *) user_data);
}
static void
-connection_removed (NMManager *manager,
- NMConnection *connection,
- NMConnectionScope scope,
- gpointer user_data)
+_deactivate_if_active (NMManager *manager, NMConnection *connection)
{
- NMSettingConnection *s_con;
GPtrArray *list;
int i;
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- if (!s_con)
- return;
-
list = nm_manager_get_active_connections_by_connection (manager, connection);
if (!list)
return;
@@ -1059,7 +1055,7 @@ connection_removed (NMManager *manager,
if (!nm_manager_deactivate_connection (manager, path, NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, &error)) {
nm_log_warn (LOGD_DEVICE, "Connection '%s' disappeared, but error deactivating it: (%d) %s",
- nm_setting_connection_get_id (s_con), error->code, error->message);
+ nm_connection_get_id (connection), error->code, error->message);
g_error_free (error);
}
g_free (path);
@@ -1068,13 +1064,50 @@ connection_removed (NMManager *manager,
}
static void
-manager_user_permissions_changed (NMManager *manager, NMPolicy *policy)
+connection_removed (NMSettings *settings,
+ NMConnection *connection,
+ gpointer user_data)
+{
+ NMPolicy *policy = user_data;
+
+ _deactivate_if_active (policy->manager, connection);
+}
+
+static void
+connection_visibility_changed (NMSettings *settings,
+ NMSettingsConnection *connection,
+ gpointer user_data)
+{
+ NMPolicy *policy = user_data;
+
+ if (nm_settings_connection_is_visible (connection))
+ schedule_activate_all (policy);
+ else
+ _deactivate_if_active (policy->manager, NM_CONNECTION (connection));
+}
+
+static void
+_connect_manager_signal (NMPolicy *policy, const char *name, gpointer callback)
+{
+ guint id;
+
+ id = g_signal_connect (policy->manager, name, callback, policy);
+ policy->manager_ids = g_slist_prepend (policy->manager_ids, GUINT_TO_POINTER (id));
+}
+
+static void
+_connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback)
{
- schedule_activate_all (policy);
+ guint id;
+
+ id = g_signal_connect (policy->settings, name, callback, policy);
+ policy->settings_ids = g_slist_prepend (policy->settings_ids, GUINT_TO_POINTER (id));
}
NMPolicy *
-nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager)
+nm_policy_new (NMManager *manager,
+ NMVPNManager *vpn_manager,
+ NMSettings *settings)
{
NMPolicy *policy;
static gboolean initialized = FALSE;
@@ -1086,6 +1119,7 @@ nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager)
policy = g_malloc0 (sizeof (NMPolicy));
policy->manager = g_object_ref (manager);
+ policy->settings = g_object_ref (settings);
policy->update_state_id = 0;
/* Grab hostname on startup and use that if nothing provides one */
@@ -1104,54 +1138,21 @@ nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager)
G_CALLBACK (vpn_connection_deactivated), policy);
policy->vpn_deactivated_id = id;
- id = g_signal_connect (manager, "state-changed",
- G_CALLBACK (global_state_changed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "notify::" NM_MANAGER_HOSTNAME,
- G_CALLBACK (hostname_changed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "notify::" NM_MANAGER_SLEEPING,
- G_CALLBACK (sleeping_changed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "notify::" NM_MANAGER_NETWORKING_ENABLED,
- G_CALLBACK (sleeping_changed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "device-added",
- G_CALLBACK (device_added), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "device-removed",
- G_CALLBACK (device_removed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- /* Large batch of connections added, manager doesn't want us to
- * process each one individually.
- */
- id = g_signal_connect (manager, "connections-added",
- G_CALLBACK (connections_added), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- /* Single connection added */
- id = g_signal_connect (manager, "connection-added",
- G_CALLBACK (connection_added), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "connection-updated",
- G_CALLBACK (connection_updated), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "connection-removed",
- G_CALLBACK (connection_removed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
- id = g_signal_connect (manager, "user-permissions-changed",
- G_CALLBACK (manager_user_permissions_changed), policy);
- policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id);
-
+ _connect_manager_signal (policy, "state-changed", global_state_changed);
+ _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed);
+ _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed);
+ _connect_manager_signal (policy, "notify::" NM_MANAGER_NETWORKING_ENABLED, sleeping_changed);
+ _connect_manager_signal (policy, "device-added", device_added);
+ _connect_manager_signal (policy, "device-removed", device_removed);
+
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded);
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added);
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated);
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed);
+ _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
+ connection_visibility_changed);
+
+ initialized = TRUE;
return policy;
}
@@ -1183,21 +1184,26 @@ nm_policy_destroy (NMPolicy *policy)
g_signal_handler_disconnect (policy->vpn_manager, policy->vpn_deactivated_id);
g_object_unref (policy->vpn_manager);
- for (iter = policy->signal_ids; iter; iter = g_slist_next (iter))
- g_signal_handler_disconnect (policy->manager, (gulong) iter->data);
- g_slist_free (policy->signal_ids);
+ for (iter = policy->manager_ids; iter; iter = g_slist_next (iter))
+ g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data));
+ g_slist_free (policy->manager_ids);
- for (iter = policy->dev_signal_ids; iter; iter = g_slist_next (iter)) {
- DeviceSignalID *data = (DeviceSignalID *) iter->data;
+ for (iter = policy->settings_ids; iter; iter = g_slist_next (iter))
+ g_signal_handler_disconnect (policy->settings, GPOINTER_TO_UINT (iter->data));
+ g_slist_free (policy->settings_ids);
+
+ for (iter = policy->dev_ids; iter; iter = g_slist_next (iter)) {
+ DeviceSignalId *data = iter->data;
g_signal_handler_disconnect (data->device, data->id);
- g_free (data);
+ g_slice_free (DeviceSignalId, data);
}
- g_slist_free (policy->dev_signal_ids);
+ g_slist_free (policy->dev_ids);
g_free (policy->orig_hostname);
g_free (policy->cur_hostname);
+ g_object_unref (policy->settings);
g_object_unref (policy->manager);
g_free (policy);
}
diff --git a/src/nm-policy.h b/src/nm-policy.h
index 7d99613cc..33796bcaa 100644
--- a/src/nm-policy.h
+++ b/src/nm-policy.h
@@ -15,22 +15,22 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2004 - 2008 Red Hat, Inc.
+ * Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2007 - 2008 Novell, Inc.
*/
-#ifndef NETWORK_MANAGER_POLICY_H
-#define NETWORK_MANAGER_POLICY_H
+#ifndef NM_POLICY_H
+#define NM_POLICY_H
-#include "NetworkManager.h"
#include "nm-manager.h"
#include "nm-vpn-manager.h"
-#include "nm-device.h"
-#include "nm-activation-request.h"
+#include "nm-settings.h"
typedef struct NMPolicy NMPolicy;
-NMPolicy *nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager);
+NMPolicy *nm_policy_new (NMManager *manager,
+ NMVPNManager *vpn_manager,
+ NMSettings *settings);
void nm_policy_destroy (NMPolicy *policy);
-#endif /* NETWORK_MANAGER_POLICY_H */
+#endif /* NM_POLICY_H */
diff --git a/src/nm-secrets-provider-interface.c b/src/nm-secrets-provider-interface.c
deleted file mode 100644
index 47b8e57ef..000000000
--- a/src/nm-secrets-provider-interface.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#include <string.h>
-
-#include "nm-marshal.h"
-#include "nm-secrets-provider-interface.h"
-
-#include <nm-setting-8021x.h>
-#include <nm-setting-wireless-security.h>
-#include "nm-logging.h"
-
-static void
-nm_secrets_provider_interface_init (gpointer g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
- initialized = TRUE;
-
- /* Signals */
- g_signal_new ("manager-get-secrets",
- iface_type,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_get_secrets),
- NULL, NULL,
- _nm_marshal_BOOLEAN__POINTER_STRING_BOOLEAN_UINT_STRING_STRING,
- G_TYPE_BOOLEAN, 6,
- G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
-
- g_signal_new ("manager-cancel-secrets",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_cancel_secrets),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-
-GType
-nm_secrets_provider_interface_get_type (void)
-{
- static GType interface_type = 0;
-
- if (!interface_type) {
- const GTypeInfo interface_info = {
- sizeof (NMSecretsProviderInterface), /* class_size */
- nm_secrets_provider_interface_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- interface_type = g_type_register_static (G_TYPE_INTERFACE,
- "NMSecretsProviderInterface",
- &interface_info, 0);
-
- g_type_interface_add_prerequisite (interface_type, G_TYPE_OBJECT);
- }
-
- return interface_type;
-}
-
-gboolean
-nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2)
-{
- guint success = FALSE;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self), FALSE);
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
- g_return_val_if_fail (setting_name != NULL, FALSE);
-
- nm_secrets_provider_interface_cancel_get_secrets (self);
-
- g_signal_emit_by_name (self, "manager-get-secrets",
- connection, setting_name, request_new, caller, hint1, hint2,
- &success);
- if (!success) {
- nm_log_warn (LOGD_CORE, "failed to get connection secrets.");
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self)
-{
- g_return_if_fail (self != NULL);
- g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
-
- g_signal_emit_by_name (self, "manager-cancel-secrets");
-}
-
-
-static void
-add_one_key_to_list (gpointer key, gpointer data, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_append (*list, key);
-}
-
-static gint
-settings_order_func (gconstpointer a, gconstpointer b)
-{
- /* Just ensure the 802.1x setting gets processed _before_ the
- * wireless-security one.
- */
-
- if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME)
- && !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
- return -1;
-
- if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)
- && !strcmp (b, NM_SETTING_802_1X_SETTING_NAME))
- return 1;
-
- return 0;
-}
-
-void
-nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
- const char *setting_name,
- RequestSecretsCaller caller,
- GHashTable *settings,
- GError *error)
-{
- GSList *keys = NULL, *iter;
- GSList *updated = NULL;
- GError *tmp_error = NULL;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self));
-
- if (error) {
- NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
- setting_name,
- caller,
- NULL,
- error);
- return;
- }
-
- if (g_hash_table_size (settings) == 0) {
- g_set_error (&tmp_error, 0, 0, "%s", "no secrets were received!");
- NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
- setting_name,
- caller,
- NULL,
- tmp_error);
- g_clear_error (&tmp_error);
- return;
- }
-
- g_hash_table_foreach (settings, add_one_key_to_list, &keys);
- keys = g_slist_sort (keys, settings_order_func);
- for (iter = keys; iter; iter = g_slist_next (iter)) {
- GHashTable *hash;
- const char *name = (const char *) iter->data;
-
- hash = g_hash_table_lookup (settings, name);
- if (!hash) {
- nm_log_warn (LOGD_CORE, "couldn't get setting secrets for '%s'", name);
- continue;
- }
-
- if (NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->update_setting (self, name, hash))
- updated = g_slist_append (updated, (gpointer) setting_name);
- }
- g_slist_free (keys);
-
- if (g_slist_length (updated)) {
- NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
- setting_name,
- caller,
- updated,
- NULL);
- } else {
- g_set_error (&tmp_error, 0, 0, "%s", "no secrets updated because no valid "
- "settings were received!");
- NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self,
- setting_name,
- caller,
- NULL,
- tmp_error);
- g_clear_error (&tmp_error);
- }
-
- g_slist_free (updated);
-}
-
diff --git a/src/nm-secrets-provider-interface.h b/src/nm-secrets-provider-interface.h
deleted file mode 100644
index 3d9e08b18..000000000
--- a/src/nm-secrets-provider-interface.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager -- Network link manager
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef NM_SECRETS_PROVIDER_INTERFACE_H
-#define NM_SECRETS_PROVIDER_INTERFACE_H
-
-#include <glib-object.h>
-#include <nm-connection.h>
-
-typedef enum {
- SECRETS_CALLER_NONE = 0,
- SECRETS_CALLER_ETHERNET,
- SECRETS_CALLER_WIFI,
- SECRETS_CALLER_MOBILE_BROADBAND,
- SECRETS_CALLER_PPP,
- SECRETS_CALLER_VPN
-} RequestSecretsCaller;
-
-#define NM_TYPE_SECRETS_PROVIDER_INTERFACE (nm_secrets_provider_interface_get_type ())
-#define NM_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
-#define NM_IS_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE))
-#define NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface))
-
-typedef struct _NMSecretsProviderInterface NMSecretsProviderInterface;
-
-struct _NMSecretsProviderInterface {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*result) (NMSecretsProviderInterface *self,
- const char *setting_name,
- RequestSecretsCaller caller,
- const GSList *updated,
- GError *error);
-
- gboolean (*update_setting) (NMSecretsProviderInterface *self,
- const char *setting_name,
- GHashTable *new);
-
- /* Signals */
- void (*manager_get_secrets) (NMSecretsProviderInterface *self,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2);
-
- void (*manager_cancel_secrets) (NMSecretsProviderInterface *self);
-};
-
-GType nm_secrets_provider_interface_get_type (void);
-
-/* For callers */
-gboolean nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self,
- NMConnection *connection,
- const char *setting_name,
- gboolean request_new,
- RequestSecretsCaller caller,
- const char *hint1,
- const char *hint2);
-
-void nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self);
-
-/* For NMManager */
-void nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self,
- const char *setting_name,
- RequestSecretsCaller caller,
- GHashTable *settings,
- GError *error);
-
-#endif /* NM_SECRETS_PROVIDER_INTERFACE_H */
-
diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c
new file mode 100644
index 000000000..4877b7703
--- /dev/null
+++ b/src/nm-session-monitor.c
@@ -0,0 +1,602 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ * Author: David Zeuthen <davidz@redhat.com>
+ * Author: Dan Williams <dcbw@redhat.com>
+ */
+
+#include "config.h"
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <gio/gio.h>
+#include "nm-logging.h"
+
+#include "nm-session-monitor.h"
+
+#define CKDB_PATH "/var/run/ConsoleKit/database"
+
+/* <internal>
+ * SECTION:nm-session-monitor
+ * @title: NMSessionMonitor
+ * @short_description: Monitor sessions
+ *
+ * The #NMSessionMonitor class is a utility class to track and monitor sessions.
+ */
+
+struct _NMSessionMonitor {
+ GObject parent_instance;
+
+ GKeyFile *database;
+ GFileMonitor *database_monitor;
+ time_t database_mtime;
+ GHashTable *sessions_by_uid;
+ GHashTable *sessions_by_user;
+};
+
+struct _NMSessionMonitorClass {
+ GObjectClass parent_class;
+
+ void (*changed) (NMSessionMonitor *monitor);
+};
+
+
+enum {
+ CHANGED,
+ LAST_SIGNAL,
+};
+static guint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT);
+
+/********************************************************************/
+
+#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ())
+GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST;
+GType nm_session_monitor_error_get_type (void) G_GNUC_CONST;
+
+typedef enum {
+ NM_SESSION_MONITOR_ERROR_IO_ERROR = 0,
+ NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+} NMSessionMonitorError;
+
+GQuark
+nm_session_monitor_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (G_UNLIKELY (ret == 0))
+ ret = g_quark_from_static_string ("nm-session-monitor-error");
+ return ret;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_session_monitor_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* Some I/O operation on the CK database failed */
+ ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_IO_ERROR, "IOError"),
+ /* Error parsing the CK database */
+ ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "MalformedDatabase"),
+ /* Username or UID could could not be found */
+ ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("NMSessionMonitorError", values);
+ }
+ return etype;
+}
+/********************************************************************/
+
+typedef struct {
+ char *user;
+ uid_t uid;
+ gboolean local;
+ gboolean active;
+} Session;
+
+static void
+session_free (Session *s)
+{
+ g_free (s->user);
+ memset (s, 0, sizeof (Session));
+ g_free (s);
+}
+
+static gboolean
+check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error)
+{
+ if (g_key_file_has_key (keyfile, group, key, error))
+ return TRUE;
+
+ if (!error) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE,
+ "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key",
+ group, key);
+ }
+ return FALSE;
+}
+
+static Session *
+session_new (GKeyFile *keyfile, const char *group, GError **error)
+{
+ GError *local = NULL;
+ Session *s;
+ struct passwd *pw;
+
+ s = g_new0 (Session, 1);
+ g_assert (s);
+
+ s->uid = G_MAXUINT; /* paranoia */
+ if (!check_key (keyfile, group, "uid", &local))
+ goto error;
+ s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local);
+ if (local)
+ goto error;
+
+ if (!check_key (keyfile, group, "is_active", &local))
+ goto error;
+ s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local);
+ if (local)
+ goto error;
+
+ if (!check_key (keyfile, group, "is_local", &local))
+ goto error;
+ s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local);
+ if (local)
+ goto error;
+
+ pw = getpwuid (s->uid);
+ if (!pw) {
+ g_set_error (&local,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "Could not get username for UID %d",
+ s->uid);
+ goto error;
+ }
+ s->user = g_strdup (pw->pw_name);
+
+ return s;
+
+error:
+ session_free (s);
+ g_propagate_error (error, local);
+ return NULL;
+}
+
+/********************************************************************/
+
+static void
+free_database (NMSessionMonitor *self)
+{
+ if (self->database != NULL) {
+ g_key_file_free (self->database);
+ self->database = NULL;
+ }
+
+ g_hash_table_remove_all (self->sessions_by_uid);
+ g_hash_table_remove_all (self->sessions_by_user);
+}
+
+static gboolean
+reload_database (NMSessionMonitor *self, GError **error)
+{
+ struct stat statbuf;
+ char **groups = NULL;
+ gsize len = 0, i;
+ Session *s;
+
+ free_database (self);
+
+ if (stat (CKDB_PATH, &statbuf) != 0) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_IO_ERROR,
+ "Error statting file " CKDB_PATH ": %s",
+ strerror (errno));
+ goto error;
+ }
+ self->database_mtime = statbuf.st_mtime;
+
+ self->database = g_key_file_new ();
+ if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error))
+ goto error;
+
+ groups = g_key_file_get_groups (self->database, &len);
+ if (!groups) {
+ g_set_error_literal (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_IO_ERROR,
+ "Could not load groups from " CKDB_PATH "");
+ goto error;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (!g_str_has_prefix (groups[i], "Session "))
+ continue;
+
+ s = session_new (self->database, groups[i], error);
+ if (!s)
+ goto error;
+ g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s);
+ g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s);
+ }
+
+ g_strfreev (groups);
+ return TRUE;
+
+error:
+ if (groups)
+ g_strfreev (groups);
+ free_database (self);
+ return FALSE;
+}
+
+static gboolean
+ensure_database (NMSessionMonitor *self, GError **error)
+{
+ gboolean ret = FALSE;
+
+#if NO_CONSOLEKIT
+ return TRUE;
+#endif
+
+ if (self->database != NULL) {
+ struct stat statbuf;
+
+ if (stat (CKDB_PATH, &statbuf) != 0) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_IO_ERROR,
+ "Error statting file " CKDB_PATH " to check timestamp: %s",
+ strerror (errno));
+ goto out;
+ }
+
+ if (statbuf.st_mtime == self->database_mtime) {
+ ret = TRUE;
+ goto out;
+ }
+ }
+
+ ret = reload_database (self, error);
+
+out:
+ return ret;
+}
+
+static void
+on_file_monitor_changed (GFileMonitor * file_monitor,
+ GFile * file,
+ GFile * other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ NMSessionMonitor *self = NM_SESSION_MONITOR (user_data);
+
+ /* throw away cache */
+ free_database (self);
+
+ g_signal_emit (self, signals[CHANGED], 0);
+}
+
+static void
+nm_session_monitor_init (NMSessionMonitor *self)
+{
+ GError *error = NULL;
+ GFile *file;
+
+#if NO_CONSOLEKIT
+ return;
+#endif
+
+ /* Sessions-by-user is responsible for destroying the Session objects */
+ self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, (GDestroyNotify) session_free);
+ self->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+
+ error = NULL;
+ if (!ensure_database (self, &error)) {
+ nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message);
+ g_error_free (error);
+ }
+
+ error = NULL;
+ file = g_file_new_for_path (CKDB_PATH);
+ self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
+ g_object_unref (file);
+ if (self->database_monitor == NULL) {
+ nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message);
+ g_error_free (error);
+ } else {
+ g_signal_connect (self->database_monitor,
+ "changed",
+ G_CALLBACK (on_file_monitor_changed),
+ self);
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ NMSessionMonitor *self = NM_SESSION_MONITOR (object);
+
+ if (self->database_monitor != NULL)
+ g_object_unref (self->database_monitor);
+
+ free_database (self);
+
+ if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL)
+ G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object);
+}
+
+static void
+nm_session_monitor_class_init (NMSessionMonitorClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = finalize;
+
+ /**
+ * NMSessionMonitor::changed:
+ * @monitor: A #NMSessionMonitor
+ *
+ * Emitted when something changes.
+ */
+ signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED,
+ NM_TYPE_SESSION_MONITOR,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSessionMonitorClass, changed),
+ NULL, /* accumulator */
+ NULL, /* accumulator data */
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+NMSessionMonitor *
+nm_session_monitor_get (void)
+{
+ static NMSessionMonitor *singleton = NULL;
+
+ if (singleton)
+ return NM_SESSION_MONITOR (g_object_ref (singleton));
+
+ return NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+#if NO_CONSOLEKIT
+static gboolean
+uid_to_user (uid_t uid, const char **out_user, GError **error)
+{
+ struct passwd *pw;
+
+ pw = getpwuid (uid);
+ if (!pw) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "Could not get username for UID %d",
+ uid);
+ return FALSE;
+ }
+
+ /* Ugly, but hey, use ConsoleKit */
+ if (out_user)
+ *out_user = pw->pw_name;
+ return TRUE;
+}
+
+static gboolean
+user_to_uid (const char *user, uid_t *out_uid, GError **error)
+{
+ struct passwd *pw;
+
+ pw = getpwnam (user);
+ if (!pw) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "Could not get UID for username '%s'",
+ user);
+ return FALSE;
+ }
+
+ /* Ugly, but hey, use ConsoleKit */
+ if (out_uid)
+ *out_uid = pw->pw_uid;
+ return TRUE;
+}
+#endif
+
+/**
+ * nm_session_monitor_user_has_session:
+ * @monitor: A #NMSessionMonitor.
+ * @username: A username.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @username is logged into a session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is
+ * currently logged into a session.
+ */
+gboolean
+nm_session_monitor_user_has_session (NMSessionMonitor *monitor,
+ const char *username,
+ uid_t *out_uid,
+ GError **error)
+{
+ Session *s;
+
+#if NO_CONSOLEKIT
+ if (!user_to_uid (username, out_uid, error))
+ return FALSE;
+ return TRUE;
+#endif
+
+ if (!ensure_database (monitor, error))
+ return FALSE;
+
+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
+ if (!s) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "No session found for user '%s'",
+ username);
+ return FALSE;
+ }
+
+ if (out_uid)
+ *out_uid = s->uid;
+ return TRUE;
+}
+
+/**
+ * nm_session_monitor_uid_has_session:
+ * @monitor: A #NMSessionMonitor.
+ * @uid: A user ID.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @uid is logged into a session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
+ * currently logged into a session.
+ */
+gboolean
+nm_session_monitor_uid_has_session (NMSessionMonitor *monitor,
+ uid_t uid,
+ const char **out_user,
+ GError **error)
+{
+ Session *s;
+
+#if NO_CONSOLEKIT
+ if (!uid_to_user (uid, out_user, error))
+ return FALSE;
+ return TRUE;
+#endif
+
+ if (!ensure_database (monitor, error))
+ return FALSE;
+
+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
+ if (!s) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "No session found for uid %d",
+ uid);
+ return FALSE;
+ }
+
+ if (out_user)
+ *out_user = s->user;
+ return TRUE;
+}
+
+/**
+ * nm_session_monitor_user_active:
+ * @monitor: A #NMSessionMonitor.
+ * @username: A username.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @username is logged into a active session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is
+ * logged into an active session.
+ */
+gboolean
+nm_session_monitor_user_active (NMSessionMonitor *monitor,
+ const char *username,
+ GError **error)
+{
+ Session *s;
+
+#if NO_CONSOLEKIT
+ return TRUE;
+#endif
+
+ if (!ensure_database (monitor, error))
+ return FALSE;
+
+ s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username);
+ if (!s) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "No session found for user '%s'",
+ username);
+ return FALSE;
+ }
+
+ return s->active;
+}
+
+/**
+ * nm_session_monitor_uid_active:
+ * @monitor: A #NMSessionMonitor.
+ * @uid: A user ID.
+ * @error: Return location for error.
+ *
+ * Checks whether the given @uid is logged into a active session or not.
+ *
+ * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is
+ * logged into an active session.
+ */
+gboolean
+nm_session_monitor_uid_active (NMSessionMonitor *monitor,
+ uid_t uid,
+ GError **error)
+{
+ Session *s;
+
+#if NO_CONSOLEKIT
+ return TRUE;
+#endif
+
+ if (!ensure_database (monitor, error))
+ return FALSE;
+
+ s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid));
+ if (!s) {
+ g_set_error (error,
+ NM_SESSION_MONITOR_ERROR,
+ NM_SESSION_MONITOR_ERROR_UNKNOWN_USER,
+ "No session found for uid '%d'",
+ uid);
+ return FALSE;
+ }
+
+ return s->active;
+}
+
diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h
new file mode 100644
index 000000000..77ea9a036
--- /dev/null
+++ b/src/nm-session-monitor.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ * Author: David Zeuthen <davidz@redhat.com>
+ * Author: Dan Williams <dcbw@redhat.com>
+ */
+
+#ifndef NM_SESSION_MONITOR_H
+#define NM_SESSION_MONITOR_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SESSION_MONITOR (nm_session_monitor_get_type ())
+#define NM_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_SESSION_MONITOR, NMSessionMonitor))
+#define NM_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), NM_TYPE_SESSION_MONITOR, NMSessionMonitorClass))
+#define NM_SESSION_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_SESSION_MONITOR, NMSessionMonitorClass))
+#define NM_IS_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_SESSION_MONITOR))
+#define NM_IS_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_SESSION_MONITOR))
+
+#define NM_SESSION_MONITOR_CHANGED "changed"
+
+typedef struct _NMSessionMonitor NMSessionMonitor;
+typedef struct _NMSessionMonitorClass NMSessionMonitorClass;
+
+GType nm_session_monitor_get_type (void) G_GNUC_CONST;
+NMSessionMonitor *nm_session_monitor_get (void);
+
+gboolean nm_session_monitor_user_has_session (NMSessionMonitor *monitor,
+ const char *username,
+ uid_t *out_uid,
+ GError **error);
+
+gboolean nm_session_monitor_uid_has_session (NMSessionMonitor *monitor,
+ uid_t uid,
+ const char **out_user,
+ GError **error);
+
+gboolean nm_session_monitor_user_active (NMSessionMonitor *monitor,
+ const char *username,
+ GError **error);
+
+gboolean nm_session_monitor_uid_active (NMSessionMonitor *monitor,
+ uid_t uid,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* NM_SESSION_MONITOR_H */
+
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index ff0ef68c8..3563a5741 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -15,9 +15,10 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
*/
+#include <config.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
@@ -28,7 +29,6 @@
#include "wireless-helper.h"
-#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include "nm-udev-manager.h"
@@ -38,6 +38,9 @@
#include "nm-device-wifi.h"
#include "nm-device-olpc-mesh.h"
#include "nm-device-ethernet.h"
+#if WITH_WIMAX
+#include "nm-device-wimax.h"
+#endif
typedef struct {
GUdevClient *client;
@@ -335,6 +338,15 @@ is_olpc_mesh (GUdevDevice *device)
return (prop != NULL);
}
+static gboolean
+is_wimax (const char *driver)
+{
+ /* FIXME: check 'DEVTYPE' instead; but since we only support Intel
+ * WiMAX devices for now this is appropriate.
+ */
+ return g_strcmp0 (driver, "i2400m_usb") == 0;
+}
+
static GObject *
device_creator (NMUdevManager *manager,
GUdevDevice *udev_device,
@@ -387,7 +399,11 @@ device_creator (NMUdevManager *manager,
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver);
else if (is_wireless (udev_device))
device = (GObject *) nm_device_wifi_new (path, ifname, driver);
- else
+ else if (is_wimax (driver)) {
+#if WITH_WIMAX
+ device = (GObject *) nm_device_wimax_new (path, ifname, driver);
+#endif
+ } else
device = (GObject *) nm_device_ethernet_new (path, ifname, driver);
out:
@@ -403,7 +419,7 @@ net_add (NMUdevManager *self, GUdevDevice *device)
{
gint etype;
const char *iface;
- const char *devtype;
+ const char *tmp;
g_return_if_fail (device != NULL);
@@ -420,12 +436,24 @@ net_add (NMUdevManager *self, GUdevDevice *device)
* subclass. ModemManager will pick it up though and so we'll handle it
* through the mobile broadband stuff.
*/
- devtype = g_udev_device_get_property (device, "DEVTYPE");
- if (devtype && !strcmp (devtype, "wwan")) {
- nm_log_dbg (LOGD_HW, "ignoring interface with devtype '%s'", devtype);
+ tmp = g_udev_device_get_property (device, "DEVTYPE");
+ if (g_strcmp0 (tmp, "wwan") == 0) {
+ nm_log_dbg (LOGD_HW, "ignoring interface with devtype '%s'", tmp);
return;
}
+ /* Ignore Nokia cdc-ether interfaces in PC-Suite mode since we need to
+ * talk phonet to use them, which ModemManager doesn't do yet.
+ */
+ tmp = g_udev_device_get_property (device, "ID_VENDOR_ID");
+ if (g_strcmp0 (tmp, "0421") == 0) { /* Nokia vendor ID */
+ tmp = g_udev_device_get_property (device, "ID_MODEL");
+ if (tmp && (strstr (tmp, "PC-Suite") || strstr (tmp, "PC Suite"))) {
+ nm_log_dbg (LOGD_HW, "ignoring Nokia PC-Suite ethernet interface");
+ return;
+ }
+ }
+
iface = g_udev_device_get_name (device);
if (!iface) {
nm_log_dbg (LOGD_HW, "failed to get device's interface");
diff --git a/src/nm-udev-manager.h b/src/nm-udev-manager.h
index 06a2d35ce..e7866f96e 100644
--- a/src/nm-udev-manager.h
+++ b/src/nm-udev-manager.h
@@ -25,7 +25,6 @@
#include <glib.h>
#include <glib-object.h>
-#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
#include <gudev/gudev.h>
#include "nm-rfkill.h"
diff --git a/src/nm-wifi-ap-utils.c b/src/nm-wifi-ap-utils.c
new file mode 100644
index 000000000..1efcc9d8c
--- /dev/null
+++ b/src/nm-wifi-ap-utils.c
@@ -0,0 +1,731 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "nm-wifi-ap-utils.h"
+
+static gboolean
+verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error)
+{
+ if ( nm_setting_wireless_security_get_wep_key (s_wsec, 0)
+ || nm_setting_wireless_security_get_wep_key (s_wsec, 1)
+ || nm_setting_wireless_security_get_wep_key (s_wsec, 2)
+ || nm_setting_wireless_security_get_wep_key (s_wsec, 3)
+ || nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec)
+ || nm_setting_wireless_security_get_wep_key_type (s_wsec)) {
+ /* Dynamic WEP cannot have any WEP keys set */
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s is incompatible with static WEP keys", tag);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_leap (NMSettingWirelessSecurity *s_wsec,
+ NMSetting8021x *s_8021x,
+ gboolean adhoc,
+ GError **error)
+{
+ const char *key_mgmt, *auth_alg, *leap_username;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
+
+ /* One (or both) of two things indicates we want LEAP:
+ * 1) auth_alg == 'leap'
+ * 2) valid leap_username
+ *
+ * LEAP always requires a LEAP username.
+ */
+
+ if (auth_alg) {
+ if (!strcmp (auth_alg, "leap")) {
+ /* LEAP authentication requires at least a LEAP username */
+ if (!leap_username) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME,
+ "LEAP requires a LEAP username");
+ return FALSE;
+ }
+ } else if (leap_username) {
+ /* Leap username requires 'leap' auth */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "LEAP requires 'leap' authentication");
+ return FALSE;
+ }
+ }
+
+ if (leap_username) {
+ if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) {
+ /* LEAP requires ieee8021x key management */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X,
+ "LEAP requires IEEE 802.1x key management");
+ return FALSE;
+ }
+ }
+
+ /* At this point if auth_alg is set it must be 'leap', and if key_mgmt
+ * is set it must be 'ieee8021x'.
+ */
+ if (leap_username) {
+ if (auth_alg)
+ g_assert (strcmp (auth_alg, "leap") == 0);
+ if (key_mgmt)
+ g_assert (strcmp (key_mgmt, "ieee8021x") == 0);
+
+ if (adhoc) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "LEAP incompatible with Ad-Hoc mode");
+ return FALSE;
+ }
+
+ if (!verify_no_wep (s_wsec, "LEAP", error))
+ return FALSE;
+
+ if (s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME,
+ "LEAP incompatible with 802.1x setting");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_no_wpa (NMSettingWirelessSecurity *s_wsec,
+ const char *tag,
+ GError **error)
+{
+ const char *key_mgmt;
+ int n, i;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s incompatible with any WPA key management", tag);
+ return FALSE;
+ }
+
+ if (nm_setting_wireless_security_get_num_protos (s_wsec)) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s incompatible with any 'proto' setting", tag);
+ return FALSE;
+ }
+
+ n = nm_setting_wireless_security_get_num_pairwise (s_wsec);
+ for (i = 0; i < n; i++) {
+ const char *pw;
+
+ pw = nm_setting_wireless_security_get_pairwise (s_wsec, i);
+ if (strcmp (pw, "wep40") && strcmp (pw, "wep104")) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s is incompatible with WPA pairwise ciphers", tag);
+ return FALSE;
+ }
+ }
+
+ n = nm_setting_wireless_security_get_num_groups (s_wsec);
+ for (i = 0; i < n; i++) {
+ const char *gr;
+
+ gr = nm_setting_wireless_security_get_group (s_wsec, i);
+ if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s is incompatible with WPA group ciphers", tag);
+ return FALSE;
+ }
+ }
+
+ if (nm_setting_wireless_security_get_psk (s_wsec)) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "%s is incompatible with a WPA Pre-Shared Key", tag);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec,
+ NMSetting8021x *s_8021x,
+ gboolean adhoc,
+ GError **error)
+{
+ const char *key_mgmt, *auth_alg, *leap_username;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
+
+ g_return_val_if_fail (leap_username == NULL, TRUE);
+
+ if (key_mgmt) {
+ if (!strcmp (key_mgmt, "ieee8021x")) {
+ if (!s_8021x) {
+ /* 802.1x key management requires an 802.1x setting */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Dynamic WEP requires an 802.1x setting");
+ return FALSE;
+ }
+
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ /* 802.1x key management must use "open" authentication */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Dynamic WEP requires 'open' authentication");
+ return FALSE;
+ }
+
+ /* Dynamic WEP incompatible with anything static WEP related */
+ if (!verify_no_wep (s_wsec, "Dynamic WEP", error))
+ return FALSE;
+ } else if (!strcmp (key_mgmt, "none")) {
+ if (s_8021x) {
+ /* 802.1x setting requires 802.1x key management */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Dynamic WEP requires 'ieee8021x' key management");
+ return FALSE;
+ }
+ }
+ } else if (s_8021x) {
+ /* 802.1x setting incompatible with anything but 'open' auth */
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ /* 802.1x key management must use "open" authentication */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Dynamic WEP requires 'open' authentication");
+ return FALSE;
+ }
+
+ /* Dynamic WEP incompatible with anything static WEP related */
+ if (!verify_no_wep (s_wsec, "Dynamic WEP", error))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_wpa_psk (NMSettingWirelessSecurity *s_wsec,
+ NMSetting8021x *s_8021x,
+ gboolean adhoc,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ GError **error)
+{
+ const char *key_mgmt, *auth_alg, *tmp;
+ int n;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+
+ if (key_mgmt) {
+ if (!strcmp (key_mgmt, "wpa-psk") || !strcmp (key_mgmt, "wpa-none")) {
+ if (s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA-PSK incompatible with 802.1x");
+ return FALSE;
+ }
+
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ /* WPA must use "open" authentication */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA-PSK requires 'open' authentication");
+ return FALSE;
+ }
+ }
+
+ if (!strcmp (key_mgmt, "wpa-none")) {
+ if (!adhoc) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA Ad-Hoc requires an Ad-Hoc mode AP");
+ return FALSE;
+ }
+
+ /* Ad-Hoc WPA requires 'wpa' proto, 'none' pairwise, and 'tkip' group */
+ n = nm_setting_wireless_security_get_num_protos (s_wsec);
+ tmp = (n > 0) ? nm_setting_wireless_security_get_proto (s_wsec, 0) : NULL;
+ if (n > 1 || strcmp (tmp, "wpa")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA Ad-Hoc requires 'wpa' proto");
+ return FALSE;
+ }
+
+ n = nm_setting_wireless_security_get_num_pairwise (s_wsec);
+ tmp = (n > 0) ? nm_setting_wireless_security_get_pairwise (s_wsec, 0) : NULL;
+ if (n > 1 || strcmp (tmp, "none")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA Ad-Hoc requires 'none' pairwise cipher");
+ return FALSE;
+ }
+
+ n = nm_setting_wireless_security_get_num_groups (s_wsec);
+ tmp = (n > 0) ? nm_setting_wireless_security_get_group (s_wsec, 0) : NULL;
+ if (n > 1 || strcmp (tmp, "tkip")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA Ad-Hoc requires 'tkip' group cipher");
+ return FALSE;
+ }
+ }
+
+ if (!strcmp (key_mgmt, "wpa-psk")) {
+ /* Make sure the AP's capabilities support WPA-PSK */
+ if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
+ && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "AP does not support PSK but setting requires it");
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_wpa_eap (NMSettingWirelessSecurity *s_wsec,
+ NMSetting8021x *s_8021x,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ GError **error)
+{
+ const char *key_mgmt, *auth_alg;
+ gboolean is_wpa_eap = FALSE;
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+
+ if (key_mgmt) {
+ if (!strcmp (key_mgmt, "wpa-eap")) {
+ if (!s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA-EAP requires an 802.1x setting");
+ return FALSE;
+ }
+
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ /* WPA must use "open" authentication */
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA-EAP requires 'open' authentication");
+ return FALSE;
+ }
+
+ is_wpa_eap = TRUE;
+ } else if (s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Setting requires 802.1x but does not use 'wpa-eap' key management");
+ return FALSE;
+ }
+ }
+
+ if (is_wpa_eap || s_8021x) {
+ /* Make sure the AP's capabilities support WPA-EAP */
+ if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+ && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "AP does not support 802.1x but setting requires it");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+verify_adhoc (NMSettingWirelessSecurity *s_wsec,
+ NMSetting8021x *s_8021x,
+ gboolean adhoc,
+ GError **error)
+{
+ const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL;
+
+ if (s_wsec) {
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
+ }
+
+ if (adhoc) {
+ if (key_mgmt && strcmp (key_mgmt, "wpa-none") && strcmp (key_mgmt, "none")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "AP mode is Ad-Hoc but setting requires Infrastructure security");
+ return FALSE;
+ }
+
+ if (s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Ad-Hoc mode incompatible with 802.1x security");
+ return FALSE;
+ }
+
+ if (leap_username) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Ad-Hoc mode incompatible with LEAP security");
+ return FALSE;
+ }
+
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Ad-Hoc mode requires 'open' authentication");
+ return FALSE;
+ }
+ } else {
+ if (key_mgmt && !strcmp (key_mgmt, "wpa-none")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "AP mode is Infrastructure but setting requires Ad-Hoc security");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+nm_ap_utils_complete_connection (const GByteArray *ap_ssid,
+ const guint8 ap_bssid[ETH_ALEN],
+ NM80211Mode ap_mode,
+ guint32 ap_flags,
+ guint32 ap_wpa_flags,
+ guint32 ap_rsn_flags,
+ NMConnection *connection,
+ gboolean lock_bssid,
+ GError **error)
+{
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ const GByteArray *ssid;
+ const char *mode, *key_mgmt, *auth_alg, *leap_username;
+ gboolean adhoc = FALSE;
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+
+ if (!s_wifi) {
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+ }
+
+ /* Fill in missing SSID */
+ ssid = nm_setting_wireless_get_ssid (s_wifi);
+ if (!ssid)
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL);
+ else if ( ssid->len != ap_ssid->len
+ || memcmp (ssid->data, ap_ssid->data, ssid->len)) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_ERROR,
+ NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+ "Setting SSID did not match AP SSID");
+ return FALSE;
+ }
+
+ if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) {
+ GByteArray *bssid;
+
+ bssid = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bssid, ap_bssid, ETH_ALEN);
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL);
+ g_byte_array_free (bssid, TRUE);
+ }
+
+ /* And mode */
+ mode = nm_setting_wireless_get_mode (s_wifi);
+ if (mode) {
+ gboolean valid = FALSE;
+
+ /* Make sure the supplied mode matches the AP's */
+ if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_INFRA)) {
+ if (ap_mode == NM_802_11_MODE_INFRA)
+ valid = TRUE;
+ } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) {
+ if (ap_mode == NM_802_11_MODE_ADHOC)
+ valid = TRUE;
+ adhoc = TRUE;
+ }
+
+ if (valid == FALSE) {
+ g_set_error (error,
+ NM_SETTING_WIRELESS_ERROR,
+ NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIRELESS_MODE);
+ return FALSE;
+ }
+ } else {
+ mode = NM_SETTING_WIRELESS_MODE_INFRA;
+ if (ap_mode == NM_802_11_MODE_ADHOC) {
+ mode = NM_SETTING_WIRELESS_MODE_ADHOC;
+ adhoc = TRUE;
+ }
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL);
+ }
+
+ /* Security */
+
+ /* Open */
+ if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
+ && (ap_wpa_flags == NM_802_11_AP_SEC_NONE)
+ && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) {
+ /* Make sure the connection doesn't specify security */
+ if (nm_setting_wireless_get_security (s_wifi) || s_wsec || s_8021x) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "AP is unencrypted but setting specifies security");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ /* Everything else requires security */
+ g_object_set (G_OBJECT (s_wifi),
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+ if (!s_wsec) {
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+ }
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ leap_username = nm_setting_wireless_security_get_leap_username (s_wsec);
+
+ /* Ad-Hoc checks */
+ if (!verify_adhoc (s_wsec, s_8021x, adhoc, error))
+ return FALSE;
+
+ /* Static WEP, Dynamic WEP, or LEAP */
+ if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
+ && (ap_wpa_flags == NM_802_11_AP_SEC_NONE)
+ && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) {
+ const char *tag = "WEP";
+ gboolean is_dynamic_wep = FALSE;
+
+ if (!verify_leap (s_wsec, s_8021x, adhoc, error))
+ return FALSE;
+
+ if (leap_username) {
+ tag = "LEAP";
+ } else {
+ /* Static or Dynamic WEP */
+ if (!verify_dynamic_wep (s_wsec, s_8021x, adhoc, error))
+ return FALSE;
+
+ if (s_8021x || (key_mgmt && !strcmp (key_mgmt, "ieee8021x"))) {
+ is_dynamic_wep = TRUE;
+ tag = "Dynamic WEP";
+ }
+ }
+
+ /* Nothing WPA-related can be set */
+ if (!verify_no_wpa (s_wsec, tag, error))
+ return FALSE;
+
+ if (leap_username) {
+ /* LEAP */
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
+ NULL);
+ } else if (is_dynamic_wep) {
+ /* Dynamic WEP */
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
+ NULL);
+ nm_setting_wireless_security_add_pairwise (s_wsec, "wep40");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "wep104");
+ nm_setting_wireless_security_add_group (s_wsec, "wep40");
+ nm_setting_wireless_security_add_group (s_wsec, "wep104");
+
+ if (s_8021x) {
+ /* Dynamic WEP requires a valid 802.1x setting since we can't
+ * autocomplete 802.1x.
+ */
+ if (!nm_setting_verify (NM_SETTING (s_8021x), NULL, error))
+ return FALSE;
+ }
+ } else {
+ /* Static WEP */
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NULL);
+ }
+
+ return TRUE;
+ }
+
+ /* WPA/RSN */
+ g_assert (ap_wpa_flags || ap_rsn_flags);
+
+ /* Ensure key management is valid for WPA */
+ if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA incompatible with non-EAP (original) LEAP or Dynamic WEP");
+ return FALSE;
+ }
+
+ /* 'shared' auth incompatible with any type of WPA */
+ if (auth_alg && strcmp (auth_alg, "open")) {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "WPA incompatible with Shared Key authentication");
+ return FALSE;
+ }
+
+ if (!verify_no_wep (s_wsec, "WPA", error))
+ return FALSE;
+
+ if (!verify_wpa_psk (s_wsec, s_8021x, adhoc, ap_wpa_flags, ap_rsn_flags, error))
+ return FALSE;
+
+ if (!adhoc && !verify_wpa_eap (s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error))
+ return FALSE;
+
+ if (adhoc) {
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
+ /* Ad-Hoc does not support RSN/WPA2 */
+ nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "none");
+ nm_setting_wireless_security_add_group (s_wsec, "tkip");
+ } else if (s_8021x) {
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
+ NULL);
+ /* Leave proto/pairwise/group as client set them; if they are unset the
+ * supplicant will figure out the best combination at connect time.
+ */
+
+ /* 802.1x also requires the client to completely fill in the 8021x
+ * setting. Since there's so much configuration required for it, there's
+ * no way it can be automatically completed.
+ */
+ } else if ( (key_mgmt && !strcmp (key_mgmt, "wpa-psk"))
+ || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
+ || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) {
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
+ NULL);
+ /* Leave proto/pairwise/group as client set them; if they are unset the
+ * supplicant will figure out the best combination at connect time.
+ */
+ } else {
+ g_set_error_literal (error,
+ NM_SETTING_WIRELESS_SECURITY_ERROR,
+ NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
+ "Failed to determine AP security information");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+guint32
+nm_ap_utils_level_to_quality (gint val)
+{
+ if (val < 0) {
+ /* Assume dBm already; rough conversion: best = -40, worst = -100 */
+ val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */
+ val = 100 - (int) ((100.0 * (double) val) / 60.0);
+ } else if (val > 110 && val < 256) {
+ /* assume old-style WEXT 8-bit unsigned signal level */
+ val -= 256; /* subtract 256 to convert to dBm */
+ val = abs (CLAMP (val, -100, -40) + 40); /* normalize to 0 */
+ val = 100 - (int) ((100.0 * (double) val) / 60.0);
+ } else {
+ /* Assume signal is a "quality" percentage */
+ val = CLAMP (val, 0, 100);
+ }
+ g_assert (val >= 0);
+
+ return (guint32) val;
+}
+
diff --git a/src/nm-wifi-ap-utils.h b/src/nm-wifi-ap-utils.h
new file mode 100644
index 000000000..992b839d5
--- /dev/null
+++ b/src/nm-wifi-ap-utils.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_WIFI_AP_UTILS_H
+#define NM_WIFI_AP_UTILS_H
+
+#include <net/ethernet.h>
+
+#include <NetworkManager.h>
+#include <nm-connection.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-8021x.h>
+
+gboolean nm_ap_utils_complete_connection (const GByteArray *ssid,
+ const guint8 bssid[ETH_ALEN],
+ NM80211Mode mode,
+ guint32 flags,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ NMConnection *connection,
+ gboolean lock_bssid,
+ GError **error);
+
+guint32 nm_ap_utils_level_to_quality (gint val);
+
+#endif /* NM_WIFI_AP_UTILS_H */
+
diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c
index 7770b8bc4..5fbdcea6a 100644
--- a/src/nm-wifi-ap.c
+++ b/src/nm-wifi-ap.c
@@ -22,8 +22,10 @@
#include "wireless-helper.h"
#include <string.h>
+#include <stdlib.h>
#include "nm-wifi-ap.h"
+#include "nm-wifi-ap-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-logging.h"
@@ -369,10 +371,69 @@ NMAccessPoint *nm_ap_new (void)
return (NMAccessPoint *) object;
}
+static guint32
+pair_to_flags (const char *str)
+{
+ g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
+
+ if (strcmp (str, "wep40") == 0)
+ return NM_802_11_AP_SEC_PAIR_WEP40;
+ if (strcmp (str, "wep104") == 0)
+ return NM_802_11_AP_SEC_PAIR_WEP104;
+ if (strcmp (str, "tkip") == 0)
+ return NM_802_11_AP_SEC_PAIR_TKIP;
+ if (strcmp (str, "ccmp") == 0)
+ return NM_802_11_AP_SEC_PAIR_CCMP;
+ return NM_802_11_AP_SEC_NONE;
+}
+
+static guint32
+group_to_flags (const char *str)
+{
+ g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE);
+
+ if (strcmp (str, "wep40") == 0)
+ return NM_802_11_AP_SEC_GROUP_WEP40;
+ if (strcmp (str, "wep104") == 0)
+ return NM_802_11_AP_SEC_GROUP_WEP104;
+ if (strcmp (str, "tkip") == 0)
+ return NM_802_11_AP_SEC_GROUP_TKIP;
+ if (strcmp (str, "ccmp") == 0)
+ return NM_802_11_AP_SEC_GROUP_CCMP;
+ return NM_802_11_AP_SEC_NONE;
+}
-#define IEEE80211_CAP_ESS 0x0001
-#define IEEE80211_CAP_IBSS 0x0002
-#define IEEE80211_CAP_PRIVACY 0x0010
+static guint32
+security_from_dict (GHashTable *security)
+{
+ GValue *value;
+ guint32 flags = NM_802_11_AP_SEC_NONE;
+ const char **items, **iter;
+
+ value = g_hash_table_lookup (security, "KeyMgmt");
+ if (value) {
+ items = g_value_get_boxed (value);
+ for (iter = items; iter && *iter; iter++) {
+ if (strcmp (*iter, "wpa-psk") == 0)
+ flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (strcmp (*iter, "wpa-eap") == 0)
+ flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
+ }
+ }
+
+ value = g_hash_table_lookup (security, "Pairwise");
+ if (value) {
+ items = g_value_get_boxed (value);
+ for (iter = items; iter && *iter; iter++)
+ flags |= pair_to_flags (*iter);
+ }
+
+ value = g_hash_table_lookup (security, "Group");
+ if (value)
+ flags |= group_to_flags (g_value_get_string (value));
+
+ return flags;
+}
static void
foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
@@ -383,9 +444,9 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
if (G_VALUE_HOLDS_BOXED (variant)) {
GArray *array = g_value_get_boxed (variant);
- if (!strcmp (key, "ssid")) {
+ if (!strcmp (key, "SSID")) {
guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len);
- GByteArray * ssid;
+ GByteArray *ssid;
/* Stupid ieee80211 layer uses <hidden> */
if (((len == 8) || (len == 9))
@@ -399,7 +460,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
g_byte_array_append (ssid, (const guint8 *) array->data, len);
nm_ap_set_ssid (ap, ssid);
g_byte_array_free (ssid, TRUE);
- } else if (!strcmp (key, "bssid")) {
+ } else if (!strcmp (key, "BSSID")) {
struct ether_addr addr;
if (array->len != ETH_ALEN)
@@ -407,43 +468,54 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
memset (&addr, 0, sizeof (struct ether_addr));
memcpy (&addr, array->data, ETH_ALEN);
nm_ap_set_address (ap, &addr);
- } else if (!strcmp (key, "wpaie")) {
- guint8 * ie = (guint8 *) array->data;
+ } else if (!strcmp (key, "Rates")) {
+ guint32 maxrate = 0;
+ int i;
+
+ /* Find the max AP rate */
+ for (i = 0; i < array->len; i++) {
+ guint32 r = g_array_index (array, guint32, i);
+
+ if (r > maxrate) {
+ maxrate = r;
+ nm_ap_set_max_bitrate (ap, r / 1000);
+ }
+ }
+ } else if (!strcmp (key, "WPA")) {
guint32 flags = nm_ap_get_wpa_flags (ap);
- if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
- return;
- flags = nm_ap_add_security_from_ie (flags, ie, array->len);
+ flags |= security_from_dict (g_value_get_boxed (variant));
nm_ap_set_wpa_flags (ap, flags);
- } else if (!strcmp (key, "rsnie")) {
- guint8 * ie = (guint8 *) array->data;
+ } else if (!strcmp (key, "RSN")) {
guint32 flags = nm_ap_get_rsn_flags (ap);
- if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
- return;
- flags = nm_ap_add_security_from_ie (flags, ie, array->len);
+ flags |= security_from_dict (g_value_get_boxed (variant));
nm_ap_set_rsn_flags (ap, flags);
}
- } else if (G_VALUE_HOLDS_INT (variant)) {
- gint32 int_val = g_value_get_int (variant);
-
- if (!strcmp (key, "frequency")) {
- nm_ap_set_freq (ap, (guint32) int_val);
- } else if (!strcmp (key, "maxrate")) {
- /* Supplicant reports as b/s, we use Kb/s internally */
- nm_ap_set_max_bitrate (ap, int_val / 1000);
- }
} else if (G_VALUE_HOLDS_UINT (variant)) {
guint32 val = g_value_get_uint (variant);
- if (!strcmp (key, "capabilities")) {
- if (val & IEEE80211_CAP_ESS) {
+ if (!strcmp (key, "Frequency"))
+ nm_ap_set_freq (ap, val);
+ } else if (G_VALUE_HOLDS_INT (variant)) {
+ gint val = g_value_get_int (variant);
+
+ if (!strcmp (key, "Signal"))
+ nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (val));
+ } else if (G_VALUE_HOLDS_STRING (variant)) {
+ const char *val = g_value_get_string (variant);
+
+ if (val && !strcmp (key, "Mode")) {
+ if (strcmp (val, "infrastructure") == 0)
nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
- } else if (val & IEEE80211_CAP_IBSS) {
+ else if (strcmp (val, "ad-hoc") == 0)
nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
- }
+ }
+ } else if (G_VALUE_HOLDS_BOOLEAN (variant)) {
+ gboolean val = g_value_get_boolean (variant);
- if (val & IEEE80211_CAP_PRIVACY) {
+ if (strcmp (key, "Privacy") == 0) {
+ if (val) {
guint32 flags = nm_ap_get_flags (ap);
nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
}
@@ -451,7 +523,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
}
}
-
NMAccessPoint *
nm_ap_new_from_properties (GHashTable *properties)
{
@@ -1170,45 +1241,6 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list)
}
-guint32
-nm_ap_add_security_from_ie (guint32 flags,
- const guint8 *wpa_ie,
- guint32 length)
-{
- wpa_ie_data * cap_data;
-
- if (!(cap_data = wpa_parse_wpa_ie (wpa_ie, length)))
- return NM_802_11_AP_SEC_NONE;
-
- /* Pairwise cipher flags */
- if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP40)
- flags |= NM_802_11_AP_SEC_PAIR_WEP40;
- if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP104)
- flags |= NM_802_11_AP_SEC_PAIR_WEP104;
- if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_TKIP)
- flags |= NM_802_11_AP_SEC_PAIR_TKIP;
- if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_CCMP)
- flags |= NM_802_11_AP_SEC_PAIR_CCMP;
-
- /* Group cipher flags */
- if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP40)
- flags |= NM_802_11_AP_SEC_GROUP_WEP40;
- if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP104)
- flags |= NM_802_11_AP_SEC_GROUP_WEP104;
- if (cap_data->group_cipher & IW_AUTH_CIPHER_TKIP)
- flags |= NM_802_11_AP_SEC_GROUP_TKIP;
- if (cap_data->group_cipher & IW_AUTH_CIPHER_CCMP)
- flags |= NM_802_11_AP_SEC_GROUP_CCMP;
-
- if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
- flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X;
- if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_PSK)
- flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;
-
- g_slice_free (wpa_ie_data, cap_data);
- return flags;
-}
-
gboolean
nm_ap_check_compatible (NMAccessPoint *self,
NMConnection *connection)
@@ -1275,6 +1307,27 @@ nm_ap_check_compatible (NMAccessPoint *self,
nm_ap_get_mode (self));
}
+gboolean
+nm_ap_complete_connection (NMAccessPoint *self,
+ NMConnection *connection,
+ gboolean lock_bssid,
+ GError **error)
+{
+ NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (self);
+
+ g_return_val_if_fail (connection != NULL, FALSE);
+
+ return nm_ap_utils_complete_connection (priv->ssid,
+ priv->address.ether_addr_octet,
+ priv->mode,
+ priv->flags,
+ priv->wpa_flags,
+ priv->rsn_flags,
+ connection,
+ lock_bssid,
+ error);
+}
+
static gboolean
capabilities_compatible (guint32 a_flags, guint32 b_flags)
{
diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h
index 86b785a31..2a10d3505 100644
--- a/src/nm-wifi-ap.h
+++ b/src/nm-wifi-ap.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2004 - 2010 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -110,13 +110,14 @@ void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created);
GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap);
void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
-guint32 nm_ap_add_security_from_ie (guint32 flags,
- const guint8 *wpa_ie,
- guint32 length);
-
gboolean nm_ap_check_compatible (NMAccessPoint *self,
NMConnection *connection);
+gboolean nm_ap_complete_connection (NMAccessPoint *self,
+ NMConnection *connection,
+ gboolean lock_bssid,
+ GError **error);
+
NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap,
GSList *ap_list,
gboolean strict_match);
diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in
index f8f55d2c8..897a50334 100644
--- a/src/ppp-manager/Makefile.in
+++ b/src/ppp-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/ppp-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -96,7 +101,7 @@ nm_pppd_plugin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
-o $@
@WITH_PPP_TRUE@am_nm_pppd_plugin_la_rpath = -rpath $(pppd_plugindir)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -128,7 +133,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -137,8 +141,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -155,6 +157,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -163,6 +166,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -171,8 +175,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -187,13 +191,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -201,6 +215,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -209,13 +225,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -241,12 +259,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -261,10 +276,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c
index 31a5e57a7..41b5ef1a7 100644
--- a/src/ppp-manager/nm-ppp-manager.c
+++ b/src/ppp-manager/nm-ppp-manager.c
@@ -78,6 +78,7 @@ typedef struct {
NMActRequest *act_req;
DBusGMethodInvocation *pending_secrets_context;
+ guint32 secrets_id;
guint32 ppp_watch_id;
guint32 ppp_timeout_handler;
@@ -191,8 +192,7 @@ set_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_PARENT_IFACE:
- if (priv->parent_iface)
- g_free (priv->parent_iface);
+ g_free (priv->parent_iface);
priv->parent_iface = g_value_dup_string (value);
break;
default:
@@ -335,19 +335,29 @@ remove_timeout_handler (NMPPPManager *manager)
}
static void
-impl_ppp_manager_need_secrets (NMPPPManager *manager,
- DBusGMethodInvocation *context)
+cancel_get_secrets (NMPPPManager *self)
+{
+ NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
+
+ if (priv->secrets_id) {
+ nm_act_request_cancel_secrets (priv->act_req, priv->secrets_id);
+ priv->secrets_id = 0;
+ }
+}
+
+static gboolean
+extract_details_from_connection (NMConnection *connection,
+ const char **username,
+ const char **password,
+ GError **error)
{
- NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
- NMConnection *connection;
NMSettingConnection *s_con;
+ NMSetting *setting;
const char *connection_type;
- const char *setting_name;
- guint32 tries;
- GPtrArray *hints = NULL;
- const char *hint1 = NULL, *hint2 = NULL;
- connection = nm_act_request_get_connection (priv->act_req);
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (username != NULL, FALSE);
+ g_return_val_if_fail (password != NULL, FALSE);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
@@ -355,67 +365,117 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
connection_type = nm_setting_connection_get_connection_type (s_con);
g_assert (connection_type);
+ setting = nm_connection_get_setting_by_name (connection, connection_type);
+ if (!setting) {
+ g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN,
+ "Missing type-specific setting; no secrets could be found.");
+ return FALSE;
+ }
+
+ /* FIXME: push this down to the settings and keep PPP manager generic */
+ if (NM_IS_SETTING_PPPOE (setting)) {
+ *username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting));
+ *password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting));
+ } else if (NM_IS_SETTING_GSM (setting)) {
+ *username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting));
+ *password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting));
+ } else if (NM_IS_SETTING_CDMA (setting)) {
+ *username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting));
+ *password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting));
+ }
+
+ return TRUE;
+}
+
+static void
+ppp_secrets_cb (NMActRequest *req,
+ guint32 call_id,
+ NMConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ NMPPPManager *self = NM_PPP_MANAGER (user_data);
+ NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
+ const char *username = NULL;
+ const char *password = NULL;
+ GError *local = NULL;
+
+ g_return_if_fail (priv->pending_secrets_context != NULL);
+ g_return_if_fail (req == priv->act_req);
+ g_return_if_fail (call_id == priv->secrets_id);
+
+ if (error) {
+ nm_log_warn (LOGD_PPP, "%s", error->message);
+ dbus_g_method_return_error (priv->pending_secrets_context, error);
+ goto out;
+ }
+
+ if (!extract_details_from_connection (connection, &username, &password, &local)) {
+ nm_log_warn (LOGD_PPP, "%s", local->message);
+ dbus_g_method_return_error (priv->pending_secrets_context, local);
+ g_clear_error (&local);
+ goto out;
+ }
+
+ /* This is sort of a hack but...
+ * pppd plugin only ever needs username and password. Passing the full
+ * connection there would mean some bloat: the plugin would need to link
+ * against libnm-util just to parse this. So instead, let's just send what
+ * it needs.
+ */
+ dbus_g_method_return (priv->pending_secrets_context, username, password);
+
+out:
+ priv->pending_secrets_context = NULL;
+ priv->secrets_id = 0;
+}
+
+static void
+impl_ppp_manager_need_secrets (NMPPPManager *manager,
+ DBusGMethodInvocation *context)
+{
+ NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
+ NMConnection *connection;
+ const char *setting_name;
+ const char *username = NULL;
+ const char *password = NULL;
+ guint32 tries;
+ GPtrArray *hints = NULL;
+ GError *error = NULL;
+ NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION;
+
+ connection = nm_act_request_get_connection (priv->act_req);
+
nm_connection_clear_secrets (connection);
setting_name = nm_connection_need_secrets (connection, &hints);
if (!setting_name) {
- NMSetting *setting;
-
- setting = nm_connection_get_setting_by_name (connection, connection_type);
- if (setting) {
- const char *username = NULL;
- const char *password = NULL;
-
- /* FIXME: push this down to the settings and keep PPP manager generic */
- if (NM_IS_SETTING_PPPOE (setting)) {
- username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting));
- password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting));
- } else if (NM_IS_SETTING_GSM (setting)) {
- username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting));
- password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting));
- } else if (NM_IS_SETTING_CDMA (setting)) {
- username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting));
- password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting));
- }
-
- /* If secrets are not required, send the existing username and password
- * back to the PPP plugin immediately.
- */
+ /* Use existing secrets from the connection */
+ if (extract_details_from_connection (connection, &username, &password, &error)) {
+ /* Send existing secrets to the PPP plugin */
priv->pending_secrets_context = context;
- nm_ppp_manager_update_secrets (manager,
- priv->parent_iface,
- username ? username : "",
- password ? password : "",
- NULL);
+ ppp_secrets_cb (priv->act_req, priv->secrets_id, connection, NULL, manager);
} else {
- GError *err = NULL;
-
- g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN,
- "Missing type-specific setting; no secrets could be found.");
- nm_log_warn (LOGD_PPP, "%s", err->message);
- dbus_g_method_return_error (context, err);
+ nm_log_warn (LOGD_PPP, "%s", error->message);
+ dbus_g_method_return_error (priv->pending_secrets_context, error);
+ g_clear_error (&error);
}
return;
}
- /* Extract hints */
- if (hints) {
- if (hints->len > 0)
- hint1 = g_ptr_array_index (hints, 0);
- if (hints->len > 1)
- hint2 = g_ptr_array_index (hints, 1);
- }
-
- tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES));
- /* Only ask for completely new secrets after retrying them once; some PPP
- * servers (T-Mobile USA) appear to ask a few times when they actually don't
- * even care what you pass back.
+ /* Only ask for completely new secrets after retrying them once; some devices
+ * appear to ask a few times when they actually don't even care what you
+ * pass back.
*/
- nm_act_request_get_secrets (priv->act_req,
- setting_name,
- tries > 1 ? TRUE : FALSE,
- SECRETS_CALLER_PPP,
- hint1,
- hint2);
+ tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES));
+ if (tries > 1)
+ flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW;
+
+ priv->secrets_id = nm_act_request_get_secrets (priv->act_req,
+ setting_name,
+ flags,
+ hints ? g_ptr_array_index (hints, 0) : NULL,
+ ppp_secrets_cb,
+ manager);
g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries));
priv->pending_secrets_context = context;
@@ -967,46 +1027,6 @@ nm_ppp_manager_start (NMPPPManager *manager,
return priv->pid > 0;
}
-void
-nm_ppp_manager_update_secrets (NMPPPManager *manager,
- const char *device,
- const char *username,
- const char *password,
- const char *error_message)
-{
- NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
-
- g_return_if_fail (NM_IS_PPP_MANAGER (manager));
- g_return_if_fail (device != NULL);
- g_return_if_fail (priv->pending_secrets_context != NULL);
-
- if (error_message) {
- g_return_if_fail (username == NULL);
- g_return_if_fail (password == NULL);
- } else {
- g_return_if_fail (username != NULL);
- g_return_if_fail (password != NULL);
- }
-
- if (error_message) {
- GError *err = NULL;
-
- g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, "%s", error_message);
- nm_log_warn (LOGD_PPP, "%s", error_message);
- dbus_g_method_return_error (priv->pending_secrets_context, err);
- g_error_free (err);
- } else {
- /* This is sort of a hack but...
- pppd plugin only ever needs username and password.
- Passing the full connection there would mean some bloat:
- the plugin would need to link against libnm-util just to parse this.
- So instead, let's just send what it needs */
-
- dbus_g_method_return (priv->pending_secrets_context, username, password);
- }
- priv->pending_secrets_context = NULL;
-}
-
static gboolean
ensure_killed (gpointer data)
{
@@ -1032,6 +1052,8 @@ nm_ppp_manager_stop (NMPPPManager *manager)
priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
+ cancel_get_secrets (manager);
+
if (priv->monitor_id) {
g_source_remove (priv->monitor_id);
priv->monitor_id = 0;
diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h
index a0200973f..5a8c73e4c 100644
--- a/src/ppp-manager/nm-ppp-manager.h
+++ b/src/ppp-manager/nm-ppp-manager.h
@@ -16,7 +16,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008 - 2010 Red Hat, Inc.
*/
#ifndef NM_PPP_MANAGER_H
@@ -63,12 +63,6 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager,
guint32 timeout_secs,
GError **err);
-void nm_ppp_manager_update_secrets (NMPPPManager *manager,
- const char *device,
- const char *username,
- const char *password,
- const char *error_message);
-
void nm_ppp_manager_stop (NMPPPManager *manager);
diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am
new file mode 100644
index 000000000..55b5b7ef0
--- /dev/null
+++ b/src/settings/Makefile.am
@@ -0,0 +1,89 @@
+SUBDIRS=plugins . tests
+
+INCLUDES = -I${top_srcdir} \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/src \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la
+
+libtest_settings_utils_la_SOURCES = \
+ nm-settings-utils.c \
+ nm-settings-utils.h
+
+libtest_settings_utils_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+libtest_settings_utils_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS)
+
+BUILT_SOURCES = \
+ nm-settings-glue.h \
+ nm-settings-connection-glue.h \
+ nm-agent-manager-glue.h
+
+libsettings_la_SOURCES = \
+ nm-settings.c \
+ nm-settings.h \
+ nm-inotify-helper.c \
+ nm-inotify-helper.h \
+ nm-polkit-helpers.h \
+ nm-settings-error.c \
+ nm-settings-error.h \
+ nm-system-config-interface.c \
+ nm-system-config-interface.h \
+ nm-settings-connection.c \
+ nm-settings-connection.h \
+ nm-default-wired-connection.c \
+ nm-default-wired-connection.h \
+ nm-agent-manager.c \
+ nm-agent-manager.h \
+ nm-secret-agent.c \
+ nm-secret-agent.h \
+ nm-settings-utils.h \
+ nm-settings-utils.c
+
+libsettings_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(POLKIT_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DBINDIR=\"$(bindir)\" \
+ -DSBINDIR=\"$(sbindir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLOCALSTATEDIR=\"$(localstatedir)\" \
+ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
+ -DPLUGINDIR=\"$(pkglibdir)\"
+
+libsettings_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ $(top_builddir)/src/logging/libnm-logging.la \
+ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(POLKIT_LIBS)
+
+libsettings_la_LDFLAGS = -rdynamic
+
+nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $<
+
+nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $<
+
+nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $<
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
diff --git a/src/settings/Makefile.in b/src/settings/Makefile.in
new file mode 100644
index 000000000..81970334b
--- /dev/null
+++ b/src/settings/Makefile.in
@@ -0,0 +1,945 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libsettings_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ $(top_builddir)/src/logging/libnm-logging.la \
+ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libsettings_la_OBJECTS = libsettings_la-nm-settings.lo \
+ libsettings_la-nm-inotify-helper.lo \
+ libsettings_la-nm-settings-error.lo \
+ libsettings_la-nm-system-config-interface.lo \
+ libsettings_la-nm-settings-connection.lo \
+ libsettings_la-nm-default-wired-connection.lo \
+ libsettings_la-nm-agent-manager.lo \
+ libsettings_la-nm-secret-agent.lo \
+ libsettings_la-nm-settings-utils.lo
+libsettings_la_OBJECTS = $(am_libsettings_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libsettings_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libsettings_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+libtest_settings_utils_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libtest_settings_utils_la_OBJECTS = \
+ libtest_settings_utils_la-nm-settings-utils.lo
+libtest_settings_utils_la_OBJECTS = \
+ $(am_libtest_settings_utils_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libsettings_la_SOURCES) \
+ $(libtest_settings_utils_la_SOURCES)
+DIST_SOURCES = $(libsettings_la_SOURCES) \
+ $(libtest_settings_utils_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = plugins . tests
+INCLUDES = -I${top_srcdir} \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/src \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libsettings.la libtest-settings-utils.la
+libtest_settings_utils_la_SOURCES = \
+ nm-settings-utils.c \
+ nm-settings-utils.h
+
+libtest_settings_utils_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+libtest_settings_utils_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS)
+
+BUILT_SOURCES = \
+ nm-settings-glue.h \
+ nm-settings-connection-glue.h \
+ nm-agent-manager-glue.h
+
+libsettings_la_SOURCES = \
+ nm-settings.c \
+ nm-settings.h \
+ nm-inotify-helper.c \
+ nm-inotify-helper.h \
+ nm-polkit-helpers.h \
+ nm-settings-error.c \
+ nm-settings-error.h \
+ nm-system-config-interface.c \
+ nm-system-config-interface.h \
+ nm-settings-connection.c \
+ nm-settings-connection.h \
+ nm-default-wired-connection.c \
+ nm-default-wired-connection.h \
+ nm-agent-manager.c \
+ nm-agent-manager.h \
+ nm-secret-agent.c \
+ nm-secret-agent.h \
+ nm-settings-utils.h \
+ nm-settings-utils.c
+
+libsettings_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(POLKIT_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DBINDIR=\"$(bindir)\" \
+ -DSBINDIR=\"$(sbindir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLOCALSTATEDIR=\"$(localstatedir)\" \
+ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
+ -DPLUGINDIR=\"$(pkglibdir)\"
+
+libsettings_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ $(top_builddir)/src/logging/libnm-logging.la \
+ $(builddir)/plugins/keyfile/libnm-settings-plugin-keyfile.la \
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(POLKIT_LIBS)
+
+libsettings_la_LDFLAGS = -rdynamic
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libsettings.la: $(libsettings_la_OBJECTS) $(libsettings_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libsettings_la_LINK) $(libsettings_la_OBJECTS) $(libsettings_la_LIBADD) $(LIBS)
+libtest-settings-utils.la: $(libtest_settings_utils_la_OBJECTS) $(libtest_settings_utils_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libtest_settings_utils_la_OBJECTS) $(libtest_settings_utils_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-agent-manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-default-wired-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-inotify-helper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-secret-agent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings-utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-settings.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsettings_la-nm-system-config-interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libsettings_la-nm-settings.lo: nm-settings.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings.Tpo -c -o libsettings_la-nm-settings.lo `test -f 'nm-settings.c' || echo '$(srcdir)/'`nm-settings.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings.Tpo $(DEPDIR)/libsettings_la-nm-settings.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings.c' object='libsettings_la-nm-settings.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings.lo `test -f 'nm-settings.c' || echo '$(srcdir)/'`nm-settings.c
+
+libsettings_la-nm-inotify-helper.lo: nm-inotify-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-inotify-helper.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-inotify-helper.Tpo -c -o libsettings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-inotify-helper.Tpo $(DEPDIR)/libsettings_la-nm-inotify-helper.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-inotify-helper.c' object='libsettings_la-nm-inotify-helper.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c
+
+libsettings_la-nm-settings-error.lo: nm-settings-error.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-error.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-error.Tpo -c -o libsettings_la-nm-settings-error.lo `test -f 'nm-settings-error.c' || echo '$(srcdir)/'`nm-settings-error.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-error.Tpo $(DEPDIR)/libsettings_la-nm-settings-error.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-error.c' object='libsettings_la-nm-settings-error.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-error.lo `test -f 'nm-settings-error.c' || echo '$(srcdir)/'`nm-settings-error.c
+
+libsettings_la-nm-system-config-interface.lo: nm-system-config-interface.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-system-config-interface.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-system-config-interface.Tpo -c -o libsettings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-system-config-interface.Tpo $(DEPDIR)/libsettings_la-nm-system-config-interface.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-system-config-interface.c' object='libsettings_la-nm-system-config-interface.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c
+
+libsettings_la-nm-settings-connection.lo: nm-settings-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-connection.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-connection.Tpo -c -o libsettings_la-nm-settings-connection.lo `test -f 'nm-settings-connection.c' || echo '$(srcdir)/'`nm-settings-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-connection.Tpo $(DEPDIR)/libsettings_la-nm-settings-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-connection.c' object='libsettings_la-nm-settings-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-connection.lo `test -f 'nm-settings-connection.c' || echo '$(srcdir)/'`nm-settings-connection.c
+
+libsettings_la-nm-default-wired-connection.lo: nm-default-wired-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-default-wired-connection.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-default-wired-connection.Tpo -c -o libsettings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-default-wired-connection.Tpo $(DEPDIR)/libsettings_la-nm-default-wired-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-default-wired-connection.c' object='libsettings_la-nm-default-wired-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c
+
+libsettings_la-nm-agent-manager.lo: nm-agent-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-agent-manager.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-agent-manager.Tpo -c -o libsettings_la-nm-agent-manager.lo `test -f 'nm-agent-manager.c' || echo '$(srcdir)/'`nm-agent-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-agent-manager.Tpo $(DEPDIR)/libsettings_la-nm-agent-manager.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-agent-manager.c' object='libsettings_la-nm-agent-manager.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-agent-manager.lo `test -f 'nm-agent-manager.c' || echo '$(srcdir)/'`nm-agent-manager.c
+
+libsettings_la-nm-secret-agent.lo: nm-secret-agent.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-secret-agent.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-secret-agent.Tpo -c -o libsettings_la-nm-secret-agent.lo `test -f 'nm-secret-agent.c' || echo '$(srcdir)/'`nm-secret-agent.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-secret-agent.Tpo $(DEPDIR)/libsettings_la-nm-secret-agent.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-secret-agent.c' object='libsettings_la-nm-secret-agent.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-secret-agent.lo `test -f 'nm-secret-agent.c' || echo '$(srcdir)/'`nm-secret-agent.c
+
+libsettings_la-nm-settings-utils.lo: nm-settings-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsettings_la-nm-settings-utils.lo -MD -MP -MF $(DEPDIR)/libsettings_la-nm-settings-utils.Tpo -c -o libsettings_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsettings_la-nm-settings-utils.Tpo $(DEPDIR)/libsettings_la-nm-settings-utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-utils.c' object='libsettings_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsettings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsettings_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c
+
+libtest_settings_utils_la-nm-settings-utils.lo: nm-settings-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_settings_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libtest_settings_utils_la-nm-settings-utils.lo -MD -MP -MF $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Tpo -c -o libtest_settings_utils_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Tpo $(DEPDIR)/libtest_settings_utils_la-nm-settings-utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-settings-utils.c' object='libtest_settings_utils_la-nm-settings-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtest_settings_utils_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libtest_settings_utils_la-nm-settings-utils.lo `test -f 'nm-settings-utils.c' || echo '$(srcdir)/'`nm-settings-utils.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ ctags-recursive install install-am install-strip \
+ tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+
+nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $<
+
+nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $<
+
+nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $<
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
new file mode 100644
index 000000000..dbc29cae4
--- /dev/null
+++ b/src/settings/nm-agent-manager.c
@@ -0,0 +1,1390 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <ctype.h>
+#include <pwd.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "NetworkManager.h"
+#include "nm-logging.h"
+#include "nm-agent-manager.h"
+#include "nm-secret-agent.h"
+#include "nm-manager-auth.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-polkit-helpers.h"
+#include "nm-manager-auth.h"
+#include "nm-setting-vpn.h"
+#include "nm-setting-connection.h"
+
+G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT)
+
+#define NM_AGENT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_AGENT_MANAGER, \
+ NMAgentManagerPrivate))
+
+typedef struct {
+ gboolean disposed;
+
+ NMDBusManager *dbus_mgr;
+ NMSessionMonitor *session_monitor;
+ PolkitAuthority *authority;
+
+ /* Hashed by owner name, not identifier, since two agents in different
+ * sessions can use the same identifier.
+ */
+ GHashTable *agents;
+
+ GHashTable *requests;
+} NMAgentManagerPrivate;
+
+typedef struct _Request Request;
+
+static void request_add_agent (Request *req,
+ NMSecretAgent *agent,
+ NMSessionMonitor *session_monitor);
+
+static void request_remove_agent (Request *req, NMSecretAgent *agent);
+
+static void impl_agent_manager_register (NMAgentManager *self,
+ const char *identifier,
+ DBusGMethodInvocation *context);
+
+static void impl_agent_manager_unregister (NMAgentManager *self,
+ DBusGMethodInvocation *context);
+
+#include "nm-agent-manager-glue.h"
+
+/********************************************************************/
+
+#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ())
+#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ())
+
+typedef enum {
+ NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0,
+ NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
+ NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ NM_AGENT_MANAGER_ERROR_NOT_REGISTERED,
+ NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR,
+ NM_AGENT_MANAGER_ERROR_NO_SECRETS
+} NMAgentManagerError;
+
+static GQuark
+nm_agent_manager_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (G_UNLIKELY (ret == 0))
+ ret = g_quark_from_static_string ("nm-agent-manager-error");
+ return ret;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+static GType
+nm_agent_manager_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* Unable to determine caller's sender or UID */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "SenderUnknown"),
+ /* Permission for some operation was denied */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"),
+ /* The caller's session could not be determined */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "SessionNotFound"),
+ /* The identifier was invalid */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "InvalidIdentifier"),
+ /* Request was not from a registered agent */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"),
+ /* Some internal error occurred */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"),
+ /* No secrets were available */
+ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NoSecrets"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("NMAgentManagerError", values);
+ }
+ return etype;
+}
+
+/*************************************************************/
+
+static gboolean
+remove_agent (NMAgentManager *self, const char *owner)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ NMSecretAgent *agent;
+ GHashTableIter iter;
+ gpointer data;
+
+ g_return_val_if_fail (owner != NULL, FALSE);
+
+ /* Make sure this agent has already registered */
+ agent = g_hash_table_lookup (priv->agents, owner);
+ if (!agent)
+ return FALSE;
+
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent unregistered",
+ nm_secret_agent_get_description (agent));
+
+ /* Remove this agent to any in-progress secrets requests */
+ g_hash_table_iter_init (&iter, priv->requests);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ request_remove_agent ((Request *) data, agent);
+
+ /* And dispose of the agent */
+ g_hash_table_remove (priv->agents, owner);
+ return TRUE;
+}
+
+/*************************************************************/
+
+static gboolean
+validate_identifier (const char *identifier, GError **error)
+{
+ const char *p = identifier;
+ size_t id_len;
+
+ if (!identifier) {
+ g_set_error_literal (error,
+ NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ "No identifier was given");
+ return FALSE;
+ }
+
+ /* Length between 3 and 255 characters inclusive */
+ id_len = strlen (identifier);
+ if (id_len < 3 || id_len > 255) {
+ g_set_error_literal (error,
+ NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ "Identifier length not between 3 and 255 characters (inclusive)");
+ return FALSE;
+ }
+
+ if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) {
+ g_set_error_literal (error,
+ NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ "Identifier must not start or end with '.'");
+ return FALSE;
+ }
+
+ /* FIXME: do complete validation here */
+ while (p && *p) {
+ if (!isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) {
+ g_set_error (error,
+ NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ "Identifier contains invalid character '%c'", *p);
+ return FALSE;
+ }
+
+ if ((*p == '.') && (*(p + 1) == '.')) {
+ g_set_error_literal (error,
+ NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER,
+ "Identifier contains two '.' characters in sequence");
+ return FALSE;
+ }
+ p++;
+ }
+
+ return TRUE;
+}
+
+static void
+impl_agent_manager_register (NMAgentManager *self,
+ const char *identifier,
+ DBusGMethodInvocation *context)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ char *error_desc = NULL, *sender = NULL;
+ gulong sender_uid = G_MAXULONG;
+ GError *error = NULL, *local = NULL;
+ NMSecretAgent *agent;
+ GHashTableIter iter;
+ gpointer data;
+
+ if (!nm_auth_get_caller_uid (context,
+ priv->dbus_mgr,
+ &sender_uid,
+ &error_desc)) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN,
+ error_desc);
+ g_free (error_desc);
+ goto done;
+ }
+
+ if (!nm_session_monitor_uid_has_session (priv->session_monitor,
+ sender_uid,
+ NULL,
+ &local)) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND,
+ local && local->message ? local->message : "Session not found");
+ goto done;
+ }
+
+ sender = dbus_g_method_get_sender (context);
+ if (!sender) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN,
+ "Failed to get D-Bus request sender");
+ goto done;
+ }
+
+ /* Validate the identifier */
+ if (!validate_identifier (identifier, &error))
+ goto done;
+
+ /* Success, add the new agent */
+ agent = nm_secret_agent_new (priv->dbus_mgr, sender, identifier, sender_uid);
+ if (!agent) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR,
+ "Failed to initialize the agent");
+ goto done;
+ }
+
+ g_hash_table_insert (priv->agents, g_strdup (sender), agent);
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent registered",
+ nm_secret_agent_get_description (agent));
+ dbus_g_method_return (context);
+
+ /* Add this agent to any in-progress secrets requests */
+ g_hash_table_iter_init (&iter, priv->requests);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ request_add_agent ((Request *) data, agent, priv->session_monitor);
+
+done:
+ if (error)
+ dbus_g_method_return_error (context, error);
+ g_clear_error (&error);
+ g_clear_error (&local);
+ g_free (sender);
+}
+
+static void
+impl_agent_manager_unregister (NMAgentManager *self,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+ char *sender = NULL;
+
+ sender = dbus_g_method_get_sender (context);
+ if (!sender) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN,
+ "Failed to get D-Bus request sender");
+ goto done;
+ }
+
+ /* Found the agent, unregister and remove it */
+ if (!remove_agent (self, sender)) {
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_NOT_REGISTERED,
+ "Caller is not registered as an Agent");
+ goto done;
+ }
+
+ dbus_g_method_return (context);
+
+done:
+ if (error)
+ dbus_g_method_return_error (context, error);
+ g_clear_error (&error);
+ g_free (sender);
+}
+
+/*************************************************************/
+
+typedef void (*RequestCompleteFunc) (Request *req,
+ GHashTable *secrets,
+ const char *agent_dbus_owner,
+ const char *agent_username,
+ gboolean agent_has_modify,
+ GError *error,
+ gpointer user_data);
+typedef void (*RequestNextFunc) (Request *req);
+typedef void (*RequestCancelFunc) (Request *req);
+
+struct _Request {
+ guint32 reqid;
+ PolkitAuthority *authority;
+ NMAuthChain *chain;
+
+ NMConnection *connection;
+ gboolean filter_by_uid;
+ gulong uid_filter;
+ char *setting_name;
+ NMSettingsGetSecretsFlags flags;
+ char *hint;
+
+ /* Current agent being asked for secrets */
+ NMSecretAgent *current;
+ gconstpointer current_call_id;
+ gboolean current_has_modify;
+
+ /* Stores the sorted list of NMSecretAgents which will be asked for secrets */
+ GSList *pending;
+
+ /* Stores the list of NMSecretAgent hashes that we've already
+ * asked for secrets, so that we don't ask the same agent twice
+ * if it quits and re-registers during this secrets request.
+ */
+ GSList *asked;
+
+ guint32 idle_id;
+
+ GHashTable *existing_secrets;
+
+ NMAgentSecretsResultFunc callback;
+ gpointer callback_data;
+ gpointer other_data2;
+ gpointer other_data3;
+
+ RequestCancelFunc cancel_callback;
+ RequestNextFunc next_callback;
+ RequestCompleteFunc complete_callback;
+ gpointer complete_callback_data;
+};
+
+static guint32 next_req_id = 1;
+
+static Request *
+request_new_get (NMConnection *connection,
+ PolkitAuthority *authority,
+ gboolean filter_by_uid,
+ gulong uid_filter,
+ GHashTable *existing_secrets,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMAgentSecretsResultFunc callback,
+ gpointer callback_data,
+ gpointer other_data2,
+ gpointer other_data3,
+ RequestCompleteFunc complete_callback,
+ gpointer complete_callback_data,
+ RequestNextFunc next_callback,
+ RequestCancelFunc cancel_callback)
+{
+ Request *req;
+
+ req = g_malloc0 (sizeof (Request));
+ req->reqid = next_req_id++;
+ req->connection = g_object_ref (connection);
+ req->authority = g_object_ref (authority);
+ req->filter_by_uid = filter_by_uid;
+ req->uid_filter = uid_filter;
+ if (existing_secrets)
+ req->existing_secrets = g_hash_table_ref (existing_secrets);
+ req->setting_name = g_strdup (setting_name);
+ req->flags = flags;
+ req->hint = g_strdup (hint);
+ req->callback = callback;
+ req->callback_data = callback_data;
+ req->other_data2 = other_data2;
+ req->other_data3 = other_data3;
+ req->complete_callback = complete_callback;
+ req->complete_callback_data = complete_callback_data;
+ req->next_callback = next_callback;
+ req->cancel_callback = cancel_callback;
+
+ return req;
+}
+
+static Request *
+request_new_other (NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter,
+ RequestCompleteFunc complete_callback,
+ gpointer complete_callback_data,
+ RequestNextFunc next_callback)
+{
+ Request *req;
+
+ req = g_malloc0 (sizeof (Request));
+ req->reqid = next_req_id++;
+ req->connection = g_object_ref (connection);
+ req->filter_by_uid = filter_by_uid;
+ req->uid_filter = uid_filter;
+ req->complete_callback = complete_callback;
+ req->complete_callback_data = complete_callback_data;
+ req->next_callback = next_callback;
+
+ return req;
+}
+
+static void
+request_free (Request *req)
+{
+ if (req->idle_id)
+ g_source_remove (req->idle_id);
+
+ if (req->cancel_callback)
+ req->cancel_callback (req);
+
+ g_slist_free (req->pending);
+ g_slist_free (req->asked);
+ g_object_unref (req->connection);
+ g_free (req->setting_name);
+ g_free (req->hint);
+ if (req->existing_secrets)
+ g_hash_table_unref (req->existing_secrets);
+ if (req->chain)
+ nm_auth_chain_unref (req->chain);
+ if (req->authority)
+ g_object_unref (req->authority);
+ memset (req, 0, sizeof (Request));
+ g_free (req);
+}
+
+static void
+req_complete_success (Request *req,
+ GHashTable *secrets,
+ const char *agent_dbus_owner,
+ const char *agent_uname,
+ gboolean agent_has_modify)
+{
+ req->complete_callback (req,
+ secrets,
+ agent_dbus_owner,
+ agent_uname,
+ agent_has_modify,
+ NULL,
+ req->complete_callback_data);
+}
+
+static void
+req_complete_error (Request *req, GError *error)
+{
+ req->complete_callback (req, NULL, NULL, NULL, FALSE, error, req->complete_callback_data);
+}
+
+static gint
+agent_compare_func (NMSecretAgent *a, NMSecretAgent *b, gpointer user_data)
+{
+ NMSessionMonitor *session_monitor = NM_SESSION_MONITOR (user_data);
+ gboolean a_active, b_active;
+
+ if (a && !b)
+ return -1;
+ else if (a == b)
+ return 0;
+ else if (!a && b)
+ return 1;
+
+ /* Prefer agents in active sessions */
+ a_active = nm_session_monitor_uid_active (session_monitor,
+ nm_secret_agent_get_owner_uid (a),
+ NULL);
+ b_active = nm_session_monitor_uid_active (session_monitor,
+ nm_secret_agent_get_owner_uid (b),
+ NULL);
+ if (a_active && !b_active)
+ return -1;
+ else if (a_active == b_active)
+ return 0;
+ else if (!a_active && b_active)
+ return 1;
+
+ return 0;
+}
+
+static void
+request_add_agent (Request *req,
+ NMSecretAgent *agent,
+ NMSessionMonitor *session_monitor)
+{
+ uid_t agent_uid;
+
+ g_return_if_fail (req != NULL);
+ g_return_if_fail (agent != NULL);
+
+ if (g_slist_find (req->asked, GUINT_TO_POINTER (nm_secret_agent_get_hash (agent))))
+ return;
+
+ /* Ensure the caller's username exists in the connection's permissions,
+ * or that the permissions is empty (ie, visible by everyone).
+ */
+ agent_uid = nm_secret_agent_get_owner_uid (agent);
+ if (0 != agent_uid) {
+ if (!nm_auth_uid_in_acl (req->connection, session_monitor, agent_uid, NULL)) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s (not in ACL)",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+ /* Connection not visible to this agent's user */
+ return;
+ }
+ /* Caller is allowed to manipulate this connection */
+ }
+
+ /* If the request should filter agents by UID, do that now */
+ if (req->filter_by_uid && (agent_uid != req->uid_filter)) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s "
+ "(uid %d not required %ld)",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name, agent_uid, req->uid_filter);
+ return;
+ }
+
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent allowed for secrets request %p/%s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+
+ /* Add this agent to the list, preferring active sessions */
+ req->pending = g_slist_insert_sorted_with_data (req->pending,
+ agent,
+ (GCompareDataFunc) agent_compare_func,
+ session_monitor);
+}
+
+static void
+request_add_agents (NMAgentManager *self, Request *req)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer data;
+
+ g_hash_table_iter_init (&iter, priv->agents);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ request_add_agent (req, NM_SECRET_AGENT (data), priv->session_monitor);
+}
+
+static void
+request_remove_agent (Request *req, NMSecretAgent *agent)
+{
+ gboolean try_next = FALSE;
+ const char *detail = "";
+
+ g_return_if_fail (req != NULL);
+ g_return_if_fail (agent != NULL);
+
+ /* If this agent is being asked right now, cancel the request */
+ if (agent == req->current) {
+ req->cancel_callback (req);
+ req->current_has_modify = FALSE;
+ req->current = NULL;
+ req->current_call_id = NULL;
+ try_next = TRUE;
+ detail = " current";
+ }
+
+ nm_log_dbg (LOGD_AGENTS, "(%s)%s agent removed from secrets request %p/%s",
+ nm_secret_agent_get_description (agent),
+ detail, req, req->setting_name);
+
+ req->pending = g_slist_remove (req->pending, agent);
+
+ if (try_next) {
+ /* If the agent serving the in-progress secrets request went away then
+ * we need to send the request to the next agent.
+ */
+ req->next_callback (req);
+ }
+}
+
+static gboolean
+next_generic (Request *req, const char *detail)
+{
+ GError *error = NULL;
+ gboolean success = FALSE;
+
+ if (req->pending == NULL) {
+ /* No more secret agents are available to fulfill this secrets request */
+ error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
+ NM_AGENT_MANAGER_ERROR_NO_SECRETS,
+ "No agents were available for this request.");
+ req_complete_error (req, error);
+ g_error_free (error);
+ } else {
+ /* Send a secrets request to the next agent */
+ req->current_has_modify = FALSE;
+ req->current = req->pending->data;
+ req->pending = g_slist_remove (req->pending, req->current);
+
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent %s secrets for request %p/%s",
+ nm_secret_agent_get_description (req->current),
+ detail, req, req->setting_name);
+ success = TRUE;
+ }
+
+ return success;
+}
+
+static gboolean
+start_generic (gpointer user_data)
+{
+ Request *req = user_data;
+
+ req->idle_id = 0;
+ req->next_callback (req);
+ return FALSE;
+}
+
+
+/*************************************************************/
+
+static void
+get_done_cb (NMSecretAgent *agent,
+ gconstpointer call_id,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ Request *req = user_data;
+ GHashTable *setting_secrets;
+ const char *agent_dbus_owner;
+ gboolean agent_has_modify;
+ struct passwd *pw;
+ char *agent_uname = NULL;
+
+ g_return_if_fail (call_id == req->current_call_id);
+
+ agent_has_modify = req->current_has_modify;
+ req->current_has_modify = FALSE;
+ req->current = NULL;
+ req->current_call_id = NULL;
+
+ if (error) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Try the next agent */
+ req->next_callback (req);
+ return;
+ }
+
+ /* Ensure the setting we wanted secrets for got returned and has something in it */
+ setting_secrets = g_hash_table_lookup (secrets, req->setting_name);
+ if (!setting_secrets || !g_hash_table_size (setting_secrets)) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+
+ /* Try the next agent */
+ req->next_callback (req);
+ return;
+ }
+
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+
+ /* Get the agent's username */
+ pw = getpwuid (nm_secret_agent_get_owner_uid (agent));
+ if (pw && strlen (pw->pw_name)) {
+ /* Needs to be UTF-8 valid since it may be pushed through D-Bus */
+ if (g_utf8_validate (pw->pw_name, -1, NULL))
+ agent_uname = g_strdup (pw->pw_name);
+ }
+
+ agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent);
+ req_complete_success (req, secrets, agent_dbus_owner, agent_uname, agent_has_modify);
+ g_free (agent_uname);
+}
+
+static void
+set_secrets_not_required (NMConnection *connection, GHashTable *hash)
+{
+ GHashTableIter iter, setting_iter;
+ const char *setting_name = NULL;
+ GHashTable *setting_hash = NULL;
+
+ /* Iterate through the settings hashes */
+ g_hash_table_iter_init (&iter, hash);
+ while (g_hash_table_iter_next (&iter,
+ (gpointer *) &setting_name,
+ (gpointer *) &setting_hash)) {
+ const char *key_name = NULL;
+ NMSetting *setting;
+ GValue *val;
+
+ setting = nm_connection_get_setting_by_name (connection, setting_name);
+ if (setting) {
+ /* Now through each secret in the setting and mark it as not required */
+ g_hash_table_iter_init (&setting_iter, setting_hash);
+ while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, (gpointer *) &val)) {
+ /* For each secret, set the flag that it's not required; VPN
+ * secrets need slightly different treatment here since the
+ * "secrets" property is actually a hash table of secrets.
+ */
+ if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0
+ && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0
+ && G_VALUE_HOLDS (val, DBUS_TYPE_G_MAP_OF_STRING)) {
+ GHashTableIter vpn_secret_iter;
+ const char *secret_name;
+
+ g_hash_table_iter_init (&vpn_secret_iter, g_value_get_boxed (val));
+ while (g_hash_table_iter_next (&vpn_secret_iter, (gpointer *) &secret_name, NULL))
+ nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL);
+ } else
+ nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL);
+ }
+ }
+ }
+}
+
+static void
+get_agent_request_secrets (Request *req, gboolean include_system_secrets)
+{
+ NMConnection *tmp;
+
+ tmp = nm_connection_duplicate (req->connection);
+ nm_connection_clear_secrets (tmp);
+ if (include_system_secrets) {
+ if (req->existing_secrets)
+ nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL);
+ } else {
+ /* Update secret flags in the temporary connection to indicate that
+ * the system secrets we're not sending to the agent aren't required,
+ * so the agent can properly validate UI controls and such.
+ */
+ if (req->existing_secrets)
+ set_secrets_not_required (tmp, req->existing_secrets);
+ }
+
+ req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current),
+ tmp,
+ req->setting_name,
+ req->hint,
+ req->flags,
+ get_done_cb,
+ req);
+ if (req->current_call_id == NULL) {
+ /* Shouldn't hit this, but handle it anyway */
+ g_warn_if_fail (req->current_call_id != NULL);
+ req->current_has_modify = FALSE;
+ req->current = NULL;
+ req->next_callback (req);
+ }
+
+ g_object_unref (tmp);
+}
+
+static void
+get_agent_modify_auth_cb (NMAuthChain *chain,
+ GError *error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ Request *req = user_data;
+ NMAuthCallResult result;
+ const char *perm;
+
+ req->chain = NULL;
+
+ if (error) {
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check error: (%d) %s",
+ req, req->setting_name,
+ error->code, error->message ? error->message : "(unknown)");
+
+ /* Try the next agent */
+ req->next_callback (req);
+ } else {
+ /* If the agent obtained the 'modify' permission, we send all system secrets
+ * to it. If it didn't, we still ask it for secrets, but we don't send
+ * any system secrets.
+ */
+ perm = nm_auth_chain_get_data (chain, "perm");
+ g_assert (perm);
+ result = nm_auth_chain_get_result (chain, perm);
+ if (result == NM_AUTH_CALL_RESULT_YES)
+ req->current_has_modify = TRUE;
+
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check result %d",
+ req, req->setting_name, result);
+
+ get_agent_request_secrets (req, req->current_has_modify);
+ }
+ nm_auth_chain_unref (chain);
+}
+
+static void
+check_system_secrets_cb (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
+{
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+ gboolean *has_system = user_data;
+
+ if (!(flags & NM_SETTING_PARAM_SECRET))
+ return;
+
+ /* Clear out system-owned or always-ask secrets */
+ if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
+ GHashTableIter iter;
+ const char *secret_name = NULL;
+
+ /* VPNs are special; need to handle each secret separately */
+ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
+ while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
+ if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
+ if (secret_flags == NM_SETTING_SECRET_FLAG_NONE)
+ *has_system = TRUE;
+ }
+ }
+ } else {
+ nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
+ if (secret_flags == NM_SETTING_SECRET_FLAG_NONE)
+ *has_system = TRUE;
+ }
+}
+
+static gboolean
+has_system_secrets (NMConnection *connection)
+{
+ gboolean has_system = FALSE;
+
+ nm_connection_for_each_setting_value (connection, check_system_secrets_cb, &has_system);
+ return has_system;
+}
+
+static void
+get_next_cb (Request *req)
+{
+ NMSettingConnection *s_con;
+ const char *agent_dbus_owner, *perm;
+
+ if (!next_generic (req, "getting"))
+ return;
+
+ agent_dbus_owner = nm_secret_agent_get_dbus_owner (NM_SECRET_AGENT (req->current));
+
+ /* If the request flags allow user interaction, and there are existing
+ * system secrets (or blank secrets that are supposed to be system-owned),
+ * check whether the agent has the 'modify' permission before sending those
+ * secrets to the agent. We shouldn't leak system-owned secrets to
+ * unprivileged users.
+ */
+ if ( (req->flags != NM_SETTINGS_GET_SECRETS_FLAG_NONE)
+ && (req->existing_secrets || has_system_secrets (req->connection))) {
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY",
+ req, req->setting_name, agent_dbus_owner);
+
+ req->chain = nm_auth_chain_new_dbus_sender (req->authority,
+ agent_dbus_owner,
+ get_agent_modify_auth_cb,
+ req);
+ g_assert (req->chain);
+
+ /* If the caller is the only user in the connection's permissions, then
+ * we use the 'modify.own' permission instead of 'modify.system'. If the
+ * request affects more than just the caller, require 'modify.system'.
+ */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ if (nm_setting_connection_get_num_permissions (s_con) == 1)
+ perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
+ else
+ perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
+ nm_auth_chain_set_data (req->chain, "perm", (gpointer) perm, NULL);
+
+ nm_auth_chain_add_call (req->chain, perm, TRUE);
+ } else {
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s",
+ req, req->setting_name, agent_dbus_owner);
+
+ get_agent_request_secrets (req, FALSE);
+ }
+}
+
+static gboolean
+get_start (gpointer user_data)
+{
+ Request *req = user_data;
+ GHashTable *setting_secrets = NULL;
+
+ req->idle_id = 0;
+
+ /* Check if there are any existing secrets */
+ if (req->existing_secrets)
+ setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name);
+
+ if (setting_secrets && g_hash_table_size (setting_secrets)) {
+ NMConnection *tmp;
+ GError *error = NULL;
+ gboolean request_new = (req->flags & NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW);
+
+ /* The connection already had secrets; check if any more are required.
+ * If no more are required, we're done. If secrets are still needed,
+ * ask a secret agent for more. This allows admins to provide generic
+ * secrets but allow additional user-specific ones as well.
+ */
+ tmp = nm_connection_duplicate (req->connection);
+ g_assert (tmp);
+
+ if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) {
+ req_complete_error (req, error);
+ g_clear_error (&error);
+ } else {
+ /* Do we have everything we need? */
+ /* FIXME: handle second check for VPN connections */
+ if ((nm_connection_need_secrets (tmp, NULL) == NULL) && (request_new == FALSE)) {
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient",
+ req, req->setting_name);
+
+ /* Got everything, we're done */
+ req_complete_success (req, req->existing_secrets, NULL, NULL, FALSE);
+ } else {
+ nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents",
+ req, req->setting_name);
+
+ /* We don't, so ask some agents for additional secrets */
+ req->next_callback (req);
+ }
+ }
+ g_object_unref (tmp);
+ } else {
+ /* Couldn't get secrets from system settings, so now we ask the
+ * agents for secrets. Let the Agent Manager handle which agents
+ * we'll ask and in which order.
+ */
+ req->next_callback (req);
+ }
+
+ return FALSE;
+}
+
+static void
+get_complete_cb (Request *req,
+ GHashTable *secrets,
+ const char *agent_dbus_owner,
+ const char *agent_username,
+ gboolean agent_has_modify,
+ GError *error,
+ gpointer user_data)
+{
+ NMAgentManager *self = NM_AGENT_MANAGER (user_data);
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+
+ /* Send secrets back to the requesting object */
+ req->callback (self,
+ req->reqid,
+ agent_dbus_owner,
+ agent_username,
+ agent_has_modify,
+ req->setting_name,
+ req->flags,
+ error ? NULL : secrets,
+ error,
+ req->callback_data,
+ req->other_data2,
+ req->other_data3);
+
+ g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
+}
+
+static void
+get_cancel_cb (Request *req)
+{
+ if (req->current && req->current_call_id)
+ nm_secret_agent_cancel_secrets (req->current, req->current_call_id);
+}
+
+guint32
+nm_agent_manager_get_secrets (NMAgentManager *self,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter,
+ GHashTable *existing_secrets,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMAgentSecretsResultFunc callback,
+ gpointer callback_data,
+ gpointer other_data2,
+ gpointer other_data3)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ Request *req;
+
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (connection != NULL, 0);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
+ g_return_val_if_fail (callback != NULL, 0);
+
+ nm_log_dbg (LOGD_SETTINGS,
+ "Secrets requested for connection %s (%s)",
+ nm_connection_get_path (connection),
+ setting_name);
+
+ /* NOTE: a few things in the Request handling depend on existing_secrets
+ * being NULL if there aren't any system-owned secrets for this connection.
+ * This in turn depends on nm_connection_to_hash() and nm_setting_to_hash()
+ * both returning NULL if they didn't hash anything.
+ */
+
+ req = request_new_get (connection,
+ priv->authority,
+ filter_by_uid,
+ uid_filter,
+ existing_secrets,
+ setting_name,
+ flags,
+ hint,
+ callback,
+ callback_data,
+ other_data2,
+ other_data3,
+ get_complete_cb,
+ self,
+ get_next_cb,
+ get_cancel_cb);
+ g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
+
+ /* Kick off the request */
+ request_add_agents (self, req);
+ req->idle_id = g_idle_add (get_start, req);
+
+ return req->reqid;
+}
+
+void
+nm_agent_manager_cancel_secrets (NMAgentManager *self,
+ guint32 request_id)
+{
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (request_id > 0);
+
+ g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests,
+ GUINT_TO_POINTER (request_id));
+}
+
+/*************************************************************/
+
+static void
+save_done_cb (NMSecretAgent *agent,
+ gconstpointer call_id,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ Request *req = user_data;
+ const char *agent_dbus_owner;
+
+ g_return_if_fail (call_id == req->current_call_id);
+
+ req->current = NULL;
+ req->current_call_id = NULL;
+
+ if (error) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent failed save secrets request %p/%s: (%d) %s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Try the next agent */
+ req->next_callback (req);
+ return;
+ }
+
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent saved secrets for request %p/%s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+
+ agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent);
+ req_complete_success (req, NULL, NULL, agent_dbus_owner, FALSE);
+}
+
+static void
+save_next_cb (Request *req)
+{
+ if (!next_generic (req, "saving"))
+ return;
+
+ req->current_call_id = nm_secret_agent_save_secrets (NM_SECRET_AGENT (req->current),
+ req->connection,
+ save_done_cb,
+ req);
+ if (req->current_call_id == NULL) {
+ /* Shouldn't hit this, but handle it anyway */
+ g_warn_if_fail (req->current_call_id != NULL);
+ req->current = NULL;
+ req->next_callback (req);
+ }
+}
+
+static void
+save_complete_cb (Request *req,
+ GHashTable *secrets,
+ const char *agent_dbus_owner,
+ const char *agent_username,
+ gboolean agent_has_modify,
+ GError *error,
+ gpointer user_data)
+{
+ NMAgentManager *self = NM_AGENT_MANAGER (user_data);
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+
+ g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
+}
+
+guint32
+nm_agent_manager_save_secrets (NMAgentManager *self,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ Request *req;
+
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (connection != NULL, 0);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
+
+ nm_log_dbg (LOGD_SETTINGS,
+ "Saving secrets for connection %s",
+ nm_connection_get_path (connection));
+
+ req = request_new_other (connection,
+ filter_by_uid,
+ uid_filter,
+ save_complete_cb,
+ self,
+ save_next_cb);
+ g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
+
+ /* Kick off the request */
+ request_add_agents (self, req);
+ req->idle_id = g_idle_add (start_generic, req);
+
+ return req->reqid;
+}
+
+/*************************************************************/
+
+static void
+delete_done_cb (NMSecretAgent *agent,
+ gconstpointer call_id,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ Request *req = user_data;
+
+ g_return_if_fail (call_id == req->current_call_id);
+
+ req->current = NULL;
+ req->current_call_id = NULL;
+
+ if (error) {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent failed delete secrets request %p/%s: (%d) %s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ } else {
+ nm_log_dbg (LOGD_AGENTS, "(%s) agent deleted secrets for request %p/%s",
+ nm_secret_agent_get_description (agent),
+ req, req->setting_name);
+ }
+
+ /* Tell the next agent to delete secrets */
+ req->next_callback (req);
+}
+
+static void
+delete_next_cb (Request *req)
+{
+ if (!next_generic (req, "deleting"))
+ return;
+
+ req->current_call_id = nm_secret_agent_delete_secrets (NM_SECRET_AGENT (req->current),
+ req->connection,
+ delete_done_cb,
+ req);
+ if (req->current_call_id == NULL) {
+ /* Shouldn't hit this, but handle it anyway */
+ g_warn_if_fail (req->current_call_id != NULL);
+ req->current = NULL;
+ req->next_callback (req);
+ }
+}
+
+static void
+delete_complete_cb (Request *req,
+ GHashTable *secrets,
+ const char *agent_dbus_owner,
+ const char *agent_username,
+ gboolean agent_has_modify,
+ GError *error,
+ gpointer user_data)
+{
+ NMAgentManager *self = NM_AGENT_MANAGER (user_data);
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+
+ g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
+}
+
+guint32
+nm_agent_manager_delete_secrets (NMAgentManager *self,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ Request *req;
+
+ g_return_val_if_fail (self != NULL, 0);
+ g_return_val_if_fail (connection != NULL, 0);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
+
+ nm_log_dbg (LOGD_SETTINGS,
+ "Deleting secrets for connection %s",
+ nm_connection_get_path (connection));
+
+ req = request_new_other (connection,
+ filter_by_uid,
+ uid_filter,
+ delete_complete_cb,
+ self,
+ delete_next_cb);
+ g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
+
+ /* Kick off the request */
+ request_add_agents (self, req);
+ req->idle_id = g_idle_add (start_generic, req);
+
+ return req->reqid;
+}
+
+/*************************************************************/
+
+static void
+name_owner_changed_cb (NMDBusManager *dbus_mgr,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
+{
+ if (old_owner) {
+ /* The agent quit, so remove it and let interested clients know */
+ remove_agent (NM_AGENT_MANAGER (user_data), old_owner);
+ }
+}
+
+/*************************************************************/
+
+NMAgentManager *
+nm_agent_manager_get (void)
+{
+ static NMAgentManager *singleton = NULL;
+ NMAgentManagerPrivate *priv;
+ DBusGConnection *connection;
+
+ if (singleton)
+ return g_object_ref (singleton);
+
+ singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL);
+ g_assert (singleton);
+
+ priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton);
+ priv->session_monitor = nm_session_monitor_get ();
+ priv->dbus_mgr = nm_dbus_manager_get ();
+
+ connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
+ dbus_g_connection_register_g_object (connection,
+ NM_DBUS_PATH_AGENT_MANAGER,
+ G_OBJECT (singleton));
+
+ g_signal_connect (priv->dbus_mgr,
+ NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
+ G_CALLBACK (name_owner_changed_cb),
+ singleton);
+
+ return singleton;
+}
+
+static void
+nm_agent_manager_init (NMAgentManager *self)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ priv->authority = polkit_authority_get_sync (NULL, &error);
+ if (!priv->authority) {
+ nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+
+ priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ priv->requests = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) request_free);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+
+ g_hash_table_destroy (priv->agents);
+ g_hash_table_destroy (priv->requests);
+
+ g_object_unref (priv->session_monitor);
+ g_object_unref (priv->dbus_mgr);
+ g_object_unref (priv->authority);
+ }
+
+ G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object);
+}
+
+static void
+nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class);
+
+ g_type_class_add_private (agent_manager_class, sizeof (NMAgentManagerPrivate));
+
+ /* virtual methods */
+ object_class->dispose = dispose;
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (agent_manager_class),
+ &dbus_glib_nm_agent_manager_object_info);
+
+ dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR,
+ NM_DBUS_INTERFACE_AGENT_MANAGER,
+ NM_TYPE_AGENT_MANAGER_ERROR);
+}
diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h
new file mode 100644
index 000000000..788a91758
--- /dev/null
+++ b/src/settings/nm-agent-manager.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_AGENT_MANAGER_H
+#define NM_AGENT_MANAGER_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <nm-connection.h>
+#include "nm-settings-flags.h"
+
+#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ())
+#define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager))
+#define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass))
+#define NM_IS_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AGENT_MANAGER))
+#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_AGENT_MANAGER))
+#define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass))
+
+typedef struct {
+ GObject parent;
+} NMAgentManager;
+
+typedef struct {
+ GObjectClass parent;
+} NMAgentManagerClass;
+
+GType nm_agent_manager_get_type (void);
+
+NMAgentManager *nm_agent_manager_get (void);
+
+/* If no agent fulfilled the secrets request, agent_dbus_owner will be NULL */
+typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
+ guint32 call_id,
+ const char *agent_dbus_owner,
+ const char *agent_uname,
+ gboolean agent_has_modify,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data,
+ gpointer other_data2,
+ gpointer other_data3);
+
+guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid,
+ GHashTable *existing_secrets,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMAgentSecretsResultFunc callback,
+ gpointer callback_data,
+ gpointer other_data2,
+ gpointer other_data3);
+
+void nm_agent_manager_cancel_secrets (NMAgentManager *manager,
+ guint32 request_id);
+
+guint32 nm_agent_manager_save_secrets (NMAgentManager *manager,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter);
+
+guint32 nm_agent_manager_delete_secrets (NMAgentManager *manager,
+ NMConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid_filter);
+
+#endif /* NM_AGENT_MANAGER_H */
diff --git a/src/settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c
new file mode 100644
index 000000000..035d851c2
--- /dev/null
+++ b/src/settings/nm-default-wired-connection.c
@@ -0,0 +1,205 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2009 - 2011 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <netinet/ether.h>
+
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-utils.h>
+
+#include "nm-dbus-glib-types.h"
+#include "nm-marshal.h"
+#include "nm-default-wired-connection.h"
+
+G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SETTINGS_CONNECTION)
+
+#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate))
+
+typedef struct {
+ gboolean disposed;
+ NMDevice *device;
+ GByteArray *mac;
+} NMDefaultWiredConnectionPrivate;
+
+enum {
+ PROP_0,
+ PROP_MAC,
+ PROP_DEVICE,
+ PROP_READ_ONLY,
+ LAST_PROP
+};
+
+enum {
+ TRY_UPDATE,
+ DELETED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/****************************************************************/
+
+NMDevice *
+nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired)
+{
+ g_return_val_if_fail (NM_IS_DEFAULT_WIRED_CONNECTION (wired), NULL);
+
+ return NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (wired)->device;
+}
+
+static void
+commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
+
+ /* Keep the object alive over try-update since it might get removed
+ * from the settings service there, but we still need it for the callback.
+ */
+ g_object_ref (connection);
+ g_signal_emit (self, signals[TRY_UPDATE], 0);
+ callback (connection, NULL, user_data);
+ g_object_unref (connection);
+}
+
+static void
+do_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
+ NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (connection);
+
+ g_signal_emit (self, signals[DELETED], 0, priv->mac);
+ NM_SETTINGS_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->delete (connection,
+ callback,
+ user_data);
+}
+
+/****************************************************************/
+
+NMDefaultWiredConnection *
+nm_default_wired_connection_new (const GByteArray *mac,
+ NMDevice *device,
+ const char *defname,
+ gboolean read_only)
+{
+ NMDefaultWiredConnection *self;
+ NMDefaultWiredConnectionPrivate *priv;
+ NMSetting *setting;
+ char *uuid;
+
+ g_return_val_if_fail (mac != NULL, NULL);
+ g_return_val_if_fail (mac->len == ETH_ALEN, NULL);
+ g_return_val_if_fail (device != NULL, NULL);
+ g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (defname != NULL, NULL);
+
+ self = (NMDefaultWiredConnection *) g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, NULL);
+ if (self) {
+ priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (self);
+ priv->device = device;
+ priv->mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (priv->mac, mac->data, mac->len);
+
+ setting = nm_setting_connection_new ();
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (setting,
+ NM_SETTING_CONNECTION_ID, defname,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_READ_ONLY, read_only,
+ NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
+ NULL);
+ g_free (uuid);
+
+ nm_connection_add_setting (NM_CONNECTION (self), setting);
+
+ /* Lock the connection to the specific device */
+ setting = nm_setting_wired_new ();
+ g_object_set (setting, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL);
+ nm_connection_add_setting (NM_CONNECTION (self), setting);
+ }
+
+ return self;
+}
+
+static void
+nm_default_wired_connection_init (NMDefaultWiredConnection *self)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
+
+ if (priv->disposed == FALSE) {
+ priv->disposed = TRUE;
+ g_object_unref (priv->device);
+ g_byte_array_free (priv->mac, TRUE);
+ }
+
+ G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->dispose (object);
+}
+
+static void
+nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->dispose = dispose;
+ settings_class->commit_changes = commit_changes;
+ settings_class->delete = do_delete;
+
+ /* Signals */
+ signals[TRY_UPDATE] =
+ g_signal_new ("try-update",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* The 'deleted' signal is used to signal intentional deletions (like
+ * updating or user-requested deletion) rather than using the
+ * superclass' 'removed' signal, since that signal doesn't have the
+ * semantics we want; it gets emitted as a side-effect of various operations
+ * and is meant more for D-Bus clients instead of in-service uses.
+ */
+ signals[DELETED] =
+ g_signal_new ("deleted",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+}
diff --git a/src/system-settings/nm-default-wired-connection.h b/src/settings/nm-default-wired-connection.h
index de89b6756..cf62d522a 100644
--- a/src/system-settings/nm-default-wired-connection.h
+++ b/src/settings/nm-default-wired-connection.h
@@ -16,13 +16,13 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2008 Novell, Inc.
- * (C) Copyright 2009 Red Hat, Inc.
+ * (C) Copyright 2009 - 2011 Red Hat, Inc.
*/
#ifndef NM_DEFAULT_WIRED_CONNECTION_H
#define NM_DEFAULT_WIRED_CONNECTION_H
-#include "nm-sysconfig-connection.h"
+#include "nm-settings-connection.h"
#include "nm-device.h"
G_BEGIN_DECLS
@@ -34,22 +34,19 @@ G_BEGIN_DECLS
#define NM_IS_DEFAULT_WIRED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION))
#define NM_DEFAULT_WIRED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass))
-#define NM_DEFAULT_WIRED_CONNECTION_MAC "mac"
-#define NM_DEFAULT_WIRED_CONNECTION_DEVICE "device"
-#define NM_DEFAULT_WIRED_CONNECTION_READ_ONLY "read-only"
-
typedef struct {
- NMSysconfigConnection parent;
+ NMSettingsConnection parent;
} NMDefaultWiredConnection;
typedef struct {
- NMSysconfigConnectionClass parent;
+ NMSettingsConnectionClass parent;
} NMDefaultWiredConnectionClass;
GType nm_default_wired_connection_get_type (void);
NMDefaultWiredConnection *nm_default_wired_connection_new (const GByteArray *mac,
NMDevice *device,
+ const char *defname,
gboolean read_only);
NMDevice *nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired);
diff --git a/src/system-settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c
index 0ee168e54..f44fee823 100644
--- a/src/system-settings/nm-inotify-helper.c
+++ b/src/settings/nm-inotify-helper.c
@@ -123,14 +123,14 @@ init_inotify (NMInotifyHelper *self)
priv->ifd = inotify_init ();
if (priv->ifd == -1) {
- nm_log_warn (LOGD_SYS_SET, "couldn't initialize inotify");
+ nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify");
return FALSE;
}
/* Watch the inotify descriptor for file/directory change events */
channel = g_io_channel_unix_new (priv->ifd);
if (!channel) {
- nm_log_warn (LOGD_SYS_SET, "couldn't create new GIOChannel");
+ nm_log_warn (LOGD_SETTINGS, "couldn't create new GIOChannel");
close (priv->ifd);
priv->ifd = -1;
return FALSE;
diff --git a/src/system-settings/nm-inotify-helper.h b/src/settings/nm-inotify-helper.h
index 10d43ac99..10d43ac99 100644
--- a/src/system-settings/nm-inotify-helper.h
+++ b/src/settings/nm-inotify-helper.h
diff --git a/src/system-settings/nm-polkit-helpers.h b/src/settings/nm-polkit-helpers.h
index a37c2eeba..d812e9445 100644
--- a/src/system-settings/nm-polkit-helpers.h
+++ b/src/settings/nm-polkit-helpers.h
@@ -22,14 +22,8 @@
#ifndef NM_POLKIT_HELPERS_H
#define NM_POLKIT_HELPERS_H
-#include <config.h>
#include <polkit/polkit.h>
-#define NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY "org.freedesktop.network-manager-settings.system.modify"
-#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED "org.freedesktop.network-manager-settings.system.wifi.share.protected"
-#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN "org.freedesktop.network-manager-settings.system.wifi.share.open"
-#define NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY "org.freedesktop.network-manager-settings.system.hostname.modify"
-
/* Fix for polkit 0.97 and later */
#if !HAVE_POLKIT_AUTHORITY_GET_SYNC
static inline PolkitAuthority *
diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c
new file mode 100644
index 000000000..2b1156cbc
--- /dev/null
+++ b/src/settings/nm-secret-agent.c
@@ -0,0 +1,398 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "NetworkManager.h"
+#include "nm-secret-agent.h"
+#include "nm-dbus-glib-types.h"
+
+G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
+
+#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_SECRET_AGENT, \
+ NMSecretAgentPrivate))
+
+typedef struct {
+ gboolean disposed;
+
+ char *description;
+ char *owner;
+ char *identifier;
+ uid_t owner_uid;
+ guint32 hash;
+
+ NMDBusManager *dbus_mgr;
+ DBusGProxy *proxy;
+
+ GHashTable *requests;
+} NMSecretAgentPrivate;
+
+/*************************************************************/
+
+typedef struct {
+ NMSecretAgent *agent;
+ DBusGProxyCall *call;
+ char *path;
+ char *setting_name;
+ NMSecretAgentCallback callback;
+ gpointer callback_data;
+} Request;
+
+static Request *
+request_new (NMSecretAgent *agent,
+ const char *path,
+ const char *setting_name,
+ NMSecretAgentCallback callback,
+ gpointer callback_data)
+{
+ Request *r;
+
+ r = g_slice_new0 (Request);
+ r->agent = agent;
+ r->path = g_strdup (path);
+ r->setting_name = g_strdup (setting_name);
+ r->callback = callback;
+ r->callback_data = callback_data;
+ return r;
+}
+
+static void
+request_free (Request *r)
+{
+ g_free (r->path);
+ g_free (r->setting_name);
+ g_slice_free (Request, r);
+}
+
+/*************************************************************/
+
+const char *
+nm_secret_agent_get_description (NMSecretAgent *agent)
+{
+ NMSecretAgentPrivate *priv;
+
+ g_return_val_if_fail (agent != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL);
+
+ priv = NM_SECRET_AGENT_GET_PRIVATE (agent);
+ if (!priv->description) {
+ priv->description = g_strdup_printf ("%s/%s/%u",
+ priv->owner,
+ priv->identifier,
+ priv->owner_uid);
+ }
+
+ return priv->description;
+}
+
+const char *
+nm_secret_agent_get_dbus_owner (NMSecretAgent *agent)
+{
+ g_return_val_if_fail (agent != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL);
+
+ return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner;
+}
+
+const char *
+nm_secret_agent_get_identifier (NMSecretAgent *agent)
+{
+ g_return_val_if_fail (agent != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL);
+
+ return NM_SECRET_AGENT_GET_PRIVATE (agent)->identifier;
+}
+
+uid_t
+nm_secret_agent_get_owner_uid (NMSecretAgent *agent)
+{
+ g_return_val_if_fail (agent != NULL, G_MAXUINT);
+ g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXUINT);
+
+ return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner_uid;
+}
+
+guint32
+nm_secret_agent_get_hash (NMSecretAgent *agent)
+{
+ g_return_val_if_fail (agent != NULL, 0);
+ g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), 0);
+
+ return NM_SECRET_AGENT_GET_PRIVATE (agent)->hash;
+}
+
+/*************************************************************/
+
+static void
+get_callback (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ void *user_data)
+{
+ Request *r = user_data;
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
+ GError *error = NULL;
+ GHashTable *secrets = NULL;
+
+ g_return_if_fail (call == r->call);
+
+ dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets,
+ G_TYPE_INVALID);
+ r->callback (r->agent, r->call, secrets, error, r->callback_data);
+ if (secrets)
+ g_hash_table_unref (secrets);
+ g_clear_error (&error);
+ g_hash_table_remove (priv->requests, call);
+}
+
+gconstpointer
+nm_secret_agent_get_secrets (NMSecretAgent *self,
+ NMConnection *connection,
+ const char *setting_name,
+ const char *hint,
+ NMSettingsGetSecretsFlags flags,
+ NMSecretAgentCallback callback,
+ gpointer callback_data)
+{
+ NMSecretAgentPrivate *priv;
+ GHashTable *hash;
+ const char *hints[2] = { hint, NULL };
+ Request *r;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (setting_name != NULL, NULL);
+
+ priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+
+ r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data);
+ r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
+ "GetSecrets",
+ get_callback,
+ r,
+ NULL,
+ 120000, /* 120 seconds */
+ DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
+ DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection),
+ G_TYPE_STRING, setting_name,
+ G_TYPE_STRV, hints,
+ G_TYPE_UINT, flags,
+ G_TYPE_INVALID);
+ g_hash_table_insert (priv->requests, r->call, r);
+
+ g_hash_table_destroy (hash);
+ return r->call;
+}
+
+void
+nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call)
+{
+ NMSecretAgentPrivate *priv;
+ Request *r;
+
+ g_return_if_fail (self != NULL);
+ priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ r = g_hash_table_lookup (priv->requests, call);
+ g_return_if_fail (r != NULL);
+
+ dbus_g_proxy_cancel_call (NM_SECRET_AGENT_GET_PRIVATE (self)->proxy, (gpointer) call);
+
+ dbus_g_proxy_call_no_reply (priv->proxy,
+ "CancelGetSecrets",
+ G_TYPE_STRING, r->path,
+ G_TYPE_STRING, r->setting_name,
+ G_TYPE_INVALID);
+ g_hash_table_remove (priv->requests, call);
+}
+
+/*************************************************************/
+
+static void
+agent_save_delete_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ void *user_data)
+{
+ Request *r = user_data;
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
+ GError *error = NULL;
+
+ g_return_if_fail (call == r->call);
+
+ dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID);
+ r->callback (r->agent, r->call, NULL, error, r->callback_data);
+ g_clear_error (&error);
+ g_hash_table_remove (priv->requests, call);
+}
+
+static gpointer
+agent_new_save_delete (NMSecretAgent *self,
+ NMConnection *connection,
+ NMSettingHashFlags hash_flags,
+ const char *method,
+ NMSecretAgentCallback callback,
+ gpointer callback_data)
+{
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+ GHashTable *hash;
+ Request *r;
+ const char *cpath = nm_connection_get_path (connection);
+
+ hash = nm_connection_to_hash (connection, hash_flags);
+
+ r = request_new (self, cpath, NULL, callback, callback_data);
+ r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy,
+ method,
+ agent_save_delete_cb,
+ r,
+ NULL,
+ 10000, /* 10 seconds */
+ DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash,
+ DBUS_TYPE_G_OBJECT_PATH, cpath,
+ G_TYPE_INVALID);
+ g_hash_table_insert (priv->requests, r->call, r);
+
+ g_hash_table_destroy (hash);
+ return r->call;
+}
+
+gconstpointer
+nm_secret_agent_save_secrets (NMSecretAgent *self,
+ NMConnection *connection,
+ NMSecretAgentCallback callback,
+ gpointer callback_data)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (connection != NULL, NULL);
+
+ /* Caller should have ensured that only agent-owned secrets exist in 'connection' */
+ return agent_new_save_delete (self,
+ connection,
+ NM_SETTING_HASH_FLAG_ALL,
+ "SaveSecrets",
+ callback,
+ callback_data);
+}
+
+gconstpointer
+nm_secret_agent_delete_secrets (NMSecretAgent *self,
+ NMConnection *connection,
+ NMSecretAgentCallback callback,
+ gpointer callback_data)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (connection != NULL, NULL);
+
+ /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */
+ return agent_new_save_delete (self,
+ connection,
+ NM_SETTING_HASH_FLAG_NO_SECRETS,
+ "DeleteSecrets",
+ callback,
+ callback_data);
+}
+
+/*************************************************************/
+
+NMSecretAgent *
+nm_secret_agent_new (NMDBusManager *dbus_mgr,
+ const char *owner,
+ const char *identifier,
+ uid_t owner_uid)
+{
+ NMSecretAgent *self;
+ NMSecretAgentPrivate *priv;
+ DBusGConnection *bus;
+ char *hash_str;
+
+ g_return_val_if_fail (owner != NULL, NULL);
+ g_return_val_if_fail (identifier != NULL, NULL);
+
+ self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL);
+ if (self) {
+ priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ priv->owner = g_strdup (owner);
+ priv->identifier = g_strdup (identifier);
+ priv->owner_uid = owner_uid;
+
+ hash_str = g_strdup_printf ("%08u%s", owner_uid, identifier);
+ priv->hash = g_str_hash (hash_str);
+ g_free (hash_str);
+
+ priv->dbus_mgr = g_object_ref (dbus_mgr);
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+ priv->proxy = dbus_g_proxy_new_for_name (bus,
+ owner,
+ NM_DBUS_PATH_SECRET_AGENT,
+ NM_DBUS_INTERFACE_SECRET_AGENT);
+ g_assert (priv->proxy);
+ }
+
+ return self;
+}
+
+static void
+nm_secret_agent_init (NMSecretAgent *self)
+{
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
+
+ priv->requests = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify) request_free);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+
+ g_free (priv->description);
+ g_free (priv->owner);
+ g_free (priv->identifier);
+
+ g_hash_table_destroy (priv->requests);
+ g_object_unref (priv->proxy);
+ g_object_unref (priv->dbus_mgr);
+ }
+
+ G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object);
+}
+
+static void
+nm_secret_agent_class_init (NMSecretAgentClass *config_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (config_class);
+
+ g_type_class_add_private (config_class, sizeof (NMSecretAgentPrivate));
+
+ /* virtual methods */
+ object_class->dispose = dispose;
+}
+
diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h
new file mode 100644
index 000000000..597940b44
--- /dev/null
+++ b/src/settings/nm-secret-agent.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_SECRET_AGENT_H
+#define NM_SECRET_AGENT_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <nm-connection.h>
+#include "nm-dbus-manager.h"
+#include "nm-settings-flags.h"
+
+#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ())
+#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent))
+#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
+#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT))
+#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SECRET_AGENT))
+#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
+
+typedef struct {
+ GObject parent;
+} NMSecretAgent;
+
+typedef struct {
+ GObjectClass parent;
+} NMSecretAgentClass;
+
+GType nm_secret_agent_get_type (void);
+
+NMSecretAgent *nm_secret_agent_new (NMDBusManager *dbus_mgr,
+ const char *owner,
+ const char *identifier,
+ uid_t owner_uid);
+
+const char *nm_secret_agent_get_description (NMSecretAgent *agent);
+
+const char *nm_secret_agent_get_dbus_owner (NMSecretAgent *agent);
+
+const char *nm_secret_agent_get_identifier (NMSecretAgent *agent);
+
+uid_t nm_secret_agent_get_owner_uid (NMSecretAgent *agent);
+
+guint32 nm_secret_agent_get_hash (NMSecretAgent *agent);
+
+typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent,
+ gconstpointer call,
+ GHashTable *new_secrets, /* NULL for save & delete */
+ GError *error,
+ gpointer user_data);
+
+gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent,
+ NMConnection *connection,
+ const char *setting_name,
+ const char *hint,
+ NMSettingsGetSecretsFlags flags,
+ NMSecretAgentCallback callback,
+ gpointer callback_data);
+
+void nm_secret_agent_cancel_secrets (NMSecretAgent *agent,
+ gconstpointer call_id);
+
+gconstpointer nm_secret_agent_save_secrets (NMSecretAgent *agent,
+ NMConnection *connection,
+ NMSecretAgentCallback callback,
+ gpointer callback_data);
+
+gconstpointer nm_secret_agent_delete_secrets (NMSecretAgent *agent,
+ NMConnection *connection,
+ NMSecretAgentCallback callback,
+ gpointer callback_data);
+
+#endif /* NM_SECRET_AGENT_H */
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
new file mode 100644
index 000000000..22aef7161
--- /dev/null
+++ b/src/settings/nm-settings-connection.c
@@ -0,0 +1,1510 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2011 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include <NetworkManager.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-vpn.h>
+#include <nm-utils.h>
+
+#include "nm-settings-connection.h"
+#include "nm-session-monitor.h"
+#include "nm-dbus-manager.h"
+#include "nm-settings-error.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-polkit-helpers.h"
+#include "nm-logging.h"
+#include "nm-manager-auth.h"
+#include "nm-marshal.h"
+#include "nm-agent-manager.h"
+
+#define SETTINGS_TIMESTAMPS_FILE LOCALSTATEDIR"/lib/NetworkManager/timestamps"
+
+static void impl_settings_connection_get_settings (NMSettingsConnection *connection,
+ DBusGMethodInvocation *context);
+
+static void impl_settings_connection_update (NMSettingsConnection *connection,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context);
+
+static void impl_settings_connection_delete (NMSettingsConnection *connection,
+ DBusGMethodInvocation *context);
+
+static void impl_settings_connection_get_secrets (NMSettingsConnection *connection,
+ const gchar *setting_name,
+ DBusGMethodInvocation *context);
+
+#include "nm-settings-connection-glue.h"
+
+G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_CONNECTION)
+
+#define NM_SETTINGS_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_SETTINGS_CONNECTION, \
+ NMSettingsConnectionPrivate))
+
+enum {
+ PROP_0 = 0,
+ PROP_VISIBLE,
+};
+
+enum {
+ UPDATED,
+ REMOVED,
+ UNREGISTER,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+ gboolean disposed;
+
+ NMDBusManager *dbus_mgr;
+ NMAgentManager *agent_mgr;
+
+ PolkitAuthority *authority;
+ GSList *pending_auths; /* List of pending authentication requests */
+ NMConnection *secrets;
+ gboolean visible; /* Is this connection is visible by some session? */
+
+ GSList *reqs; /* in-progress secrets requests */
+
+ NMSessionMonitor *session_monitor;
+ guint session_changed_id;
+
+ guint64 timestamp; /* Up-to-date timestamp of connection use */
+} NMSettingsConnectionPrivate;
+
+/**************************************************************/
+
+static void
+set_visible (NMSettingsConnection *self, gboolean new_visible)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ if (new_visible == priv->visible)
+ return;
+ priv->visible = new_visible;
+ g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_VISIBLE);
+}
+
+gboolean
+nm_settings_connection_is_visible (NMSettingsConnection *self)
+{
+ g_return_val_if_fail (NM_SETTINGS_CONNECTION (self), FALSE);
+
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible;
+}
+
+void
+nm_settings_connection_recheck_visibility (NMSettingsConnection *self)
+{
+ NMSettingsConnectionPrivate *priv;
+ NMSettingConnection *s_con;
+ guint32 num, i;
+
+ g_return_if_fail (NM_SETTINGS_CONNECTION (self));
+
+ priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ /* Check every user in the ACL for a session */
+ num = nm_setting_connection_get_num_permissions (s_con);
+ if (num == 0) {
+ /* Visible to all */
+ set_visible (self, TRUE);
+ return;
+ }
+
+ for (i = 0; i < num; i++) {
+ const char *puser;
+
+ if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) {
+ if (nm_session_monitor_user_has_session (priv->session_monitor, puser, NULL, NULL)) {
+ set_visible (self, TRUE);
+ return;
+ }
+ }
+ }
+
+ set_visible (self, FALSE);
+}
+
+static void
+session_changed_cb (NMSessionMonitor *self, gpointer user_data)
+{
+ nm_settings_connection_recheck_visibility (NM_SETTINGS_CONNECTION (user_data));
+}
+
+/**************************************************************/
+
+static void
+only_system_secrets_cb (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
+{
+ if (flags & NM_SETTING_PARAM_SECRET) {
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* VPNs are special; need to handle each secret separately */
+ if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
+ GHashTableIter iter;
+ const char *secret_name = NULL;
+
+ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
+ while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
+ if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
+ if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
+ nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
+ }
+ }
+ } else {
+ nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
+ if (secret_flags != NM_SETTING_SECRET_FLAG_NONE)
+ g_object_set (G_OBJECT (setting), key, NULL, NULL);
+ }
+ }
+}
+
+static void
+update_secrets_cache (NMSettingsConnection *self)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ if (priv->secrets)
+ g_object_unref (priv->secrets);
+ priv->secrets = nm_connection_duplicate (NM_CONNECTION (self));
+
+ /* Clear out non-system-owned and not-saved secrets */
+ nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL);
+}
+
+/* Update the settings of this connection to match that of 'new', taking care to
+ * make a private copy of secrets. */
+gboolean
+nm_settings_connection_replace_settings (NMSettingsConnection *self,
+ NMConnection *new,
+ GError **error)
+{
+ NMSettingsConnectionPrivate *priv;
+ GHashTable *new_settings;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE);
+ g_return_val_if_fail (new != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (new), FALSE);
+
+ priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL);
+ g_assert (new_settings);
+ if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) {
+ /* Copy the connection to keep its secrets around even if NM
+ * calls nm_connection_clear_secrets().
+ */
+ update_secrets_cache (self);
+
+ nm_settings_connection_recheck_visibility (self);
+ success = TRUE;
+ }
+ g_hash_table_destroy (new_settings);
+ return success;
+}
+
+static void
+ignore_cb (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+}
+
+/* Replaces the settings in this connection with those in 'new'. If any changes
+ * are made, commits them to permanent storage and to any other subsystems
+ * watching this connection. Before returning, 'callback' is run with the given
+ * 'user_data' along with any errors encountered.
+ */
+void
+nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
+ NMConnection *new,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self));
+ g_return_if_fail (new != NULL);
+ g_return_if_fail (NM_IS_CONNECTION (new));
+
+ if (!callback)
+ callback = ignore_cb;
+
+ /* Do nothing if there's nothing to update */
+ if (nm_connection_compare (NM_CONNECTION (self),
+ NM_CONNECTION (new),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ callback (self, NULL, user_data);
+ return;
+ }
+
+ if (nm_settings_connection_replace_settings (self, new, &error)) {
+ nm_settings_connection_commit_changes (self, callback, user_data);
+ } else {
+ callback (self, error, user_data);
+ g_clear_error (&error);
+ }
+}
+
+void
+nm_settings_connection_commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
+ g_return_if_fail (callback != NULL);
+
+ if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes) {
+ NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes (connection,
+ callback,
+ user_data);
+ } else {
+ GError *error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__);
+ callback (connection, error, user_data);
+ g_error_free (error);
+ }
+}
+
+void
+nm_settings_connection_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
+ g_return_if_fail (callback != NULL);
+
+ if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete) {
+ NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete (connection,
+ callback,
+ user_data);
+ } else {
+ GError *error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__);
+ callback (connection, error, user_data);
+ g_error_free (error);
+ }
+}
+
+static void
+commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ g_object_ref (connection);
+ g_signal_emit (connection, signals[UPDATED], 0);
+ callback (connection, NULL, user_data);
+ g_object_unref (connection);
+}
+
+static void
+remove_timestamp_from_db (NMSettingsConnection *connection)
+{
+ GKeyFile *timestamps_file;
+
+ timestamps_file = g_key_file_new ();
+ if (g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL)) {
+ const char *connection_uuid;
+ char *data;
+ gsize len;
+ GError *error = NULL;
+
+ connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection));
+
+ g_key_file_remove_key (timestamps_file, "timestamps", connection_uuid, NULL);
+ data = g_key_file_to_data (timestamps_file, &len, &error);
+ if (data) {
+ g_file_set_contents (SETTINGS_TIMESTAMPS_FILE, data, len, &error);
+ g_free (data);
+ }
+ if (error) {
+ nm_log_warn (LOGD_SETTINGS, "error writing timestamps file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message);
+ g_error_free (error);
+ }
+ }
+ g_key_file_free (timestamps_file);
+}
+
+static void
+do_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+ NMConnection *for_agents;
+
+ g_object_ref (connection);
+ set_visible (connection, FALSE);
+
+ /* Tell agents to remove secrets for this connection */
+ for_agents = nm_connection_duplicate (NM_CONNECTION (connection));
+ nm_connection_clear_secrets (for_agents);
+ nm_agent_manager_delete_secrets (priv->agent_mgr, for_agents, FALSE, 0);
+
+ /* Remove timestamp from timestamps database file */
+ remove_timestamp_from_db (connection);
+
+ /* Signal the connection is removed and deleted */
+ g_signal_emit (connection, signals[REMOVED], 0);
+ callback (connection, NULL, user_data);
+ g_object_unref (connection);
+}
+
+/**************************************************************/
+
+static gboolean
+supports_secrets (NMSettingsConnection *connection, const char *setting_name)
+{
+ /* All secrets supported */
+ return TRUE;
+}
+
+/* Return TRUE to continue, FALSE to stop */
+typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter,
+ NMSettingSecretFlags flags,
+ gpointer user_data);
+
+static gboolean
+clear_nonagent_secrets (GHashTableIter *iter,
+ NMSettingSecretFlags flags,
+ gpointer user_data)
+{
+ if (flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ g_hash_table_iter_remove (iter);
+ return TRUE;
+}
+
+static gboolean
+clear_unsaved_secrets (GHashTableIter *iter,
+ NMSettingSecretFlags flags,
+ gpointer user_data)
+{
+ if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
+ g_hash_table_iter_remove (iter);
+ return TRUE;
+}
+
+static gboolean
+has_system_owned_secrets (GHashTableIter *iter,
+ NMSettingSecretFlags flags,
+ gpointer user_data)
+{
+ gboolean *has_system_owned = user_data;
+
+ if (!(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) {
+ *has_system_owned = TRUE;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+for_each_secret (NMConnection *connection,
+ GHashTable *secrets,
+ ForEachSecretFunc callback,
+ gpointer callback_data)
+{
+ GHashTableIter iter;
+ const char *setting_name;
+ GHashTable *setting_hash;
+
+ /* Walk through the list of setting hashes */
+ g_hash_table_iter_init (&iter, secrets);
+ while (g_hash_table_iter_next (&iter,
+ (gpointer *) &setting_name,
+ (gpointer *) &setting_hash)) {
+ GHashTableIter setting_iter;
+ const char *secret_name;
+
+ /* Walk through the list of keys in each setting hash */
+ g_hash_table_iter_init (&setting_iter, setting_hash);
+ while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) {
+ NMSetting *setting;
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* Get the actual NMSetting from the connection so we can get secret flags */
+ setting = nm_connection_get_setting_by_name (connection, setting_name);
+ if (setting && nm_setting_get_secret_flags (setting, secret_name, &flags, NULL)) {
+ if (callback (&setting_iter, flags, callback_data) == FALSE)
+ return;
+ }
+ }
+ }
+}
+
+static void
+new_secrets_commit_cb (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ if (error) {
+ nm_log_warn (LOGD_SETTINGS, "Error saving new secrets to backing storage: (%d) %s",
+ error->code, error->message ? error->message : "(unknown)");
+ }
+}
+
+static void
+agent_secrets_done_cb (NMAgentManager *manager,
+ guint32 call_id,
+ const char *agent_dbus_owner,
+ const char *agent_username,
+ gboolean agent_has_modify,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data,
+ gpointer other_data2,
+ gpointer other_data3)
+{
+ NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ NMSettingsConnectionSecretsFunc callback = other_data2;
+ gpointer callback_data = other_data3;
+ GError *local = NULL;
+ GHashTable *hash;
+ gboolean agent_had_system = FALSE;
+
+ if (error) {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request error: (%d) %s",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ error->code,
+ error->message ? error->message : "(unknown)");
+
+ callback (self, call_id, NULL, setting_name, error, callback_data);
+ return;
+ }
+
+ if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) {
+ local = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING,
+ "%s.%d - Connection didn't have requested setting '%s'.",
+ __FILE__, __LINE__, setting_name);
+ callback (self, call_id, NULL, setting_name, local, callback_data);
+ g_clear_error (&local);
+ return;
+ }
+
+ g_assert (secrets);
+ if (agent_dbus_owner) {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets returned from agent %s",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ agent_dbus_owner);
+
+ /* If the agent returned any system-owned secrets (initial connect and no
+ * secrets given when the connection was created, or something like that)
+ * make sure the agent's UID has the 'modify' permission before we use or
+ * save those system-owned secrets. If not, discard them and use the
+ * existing secrets, or fail the connection.
+ */
+ for_each_secret (NM_CONNECTION (self), secrets, has_system_owned_secrets, &agent_had_system);
+ if (agent_had_system) {
+ if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE) {
+ /* No user interaction was allowed when requesting secrets; the
+ * agent is being bad. Remove system-owned secrets.
+ */
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) interaction forbidden but agent %s returned system secrets",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ agent_dbus_owner);
+
+ for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL);
+ } else if (agent_has_modify == FALSE) {
+ /* Agent didn't successfully authenticate; clear system-owned secrets
+ * from the secrets the agent returned.
+ */
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate but provided system secrets",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id);
+
+ for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL);
+ }
+ }
+ } else {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) existing secrets returned",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id);
+ }
+
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id);
+
+ /* If no user interaction was allowed, make sure that no "unsaved" secrets
+ * came back. Unsaved secrets by definition require user interaction.
+ */
+ if (flags == NM_SETTINGS_GET_SECRETS_FLAG_NONE)
+ for_each_secret (NM_CONNECTION (self), secrets, clear_unsaved_secrets, NULL);
+
+ /* Update the connection with our existing secrets from backing storage */
+ nm_connection_clear_secrets (NM_CONNECTION (self));
+ hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+ if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) {
+ /* Update the connection with the agent's secrets; by this point if any
+ * system-owned secrets exist in 'secrets' the agent that provided them
+ * will have been authenticated, so those secrets can replace the existing
+ * system secrets.
+ */
+ if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) {
+ /* Now that all secrets are updated, copy and cache new secrets,
+ * then save them to backing storage.
+ */
+ update_secrets_cache (self);
+
+ /* Only save secrets to backing storage if the agent returned any
+ * new system secrets. If it didn't, then the secrets are agent-
+ * owned and there's no point to writing out the connection when
+ * nothing has changed, since agent-owned secrets don't get saved here.
+ */
+ if (agent_had_system) {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id);
+
+ nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL);
+ } else {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) new agent secrets processed",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id);
+ }
+ } else {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ local ? local->code : -1,
+ (local && local->message) ? local->message : "(unknown)");
+ }
+ } else {
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ local ? local->code : -1,
+ (local && local->message) ? local->message : "(unknown)");
+ }
+
+ callback (self, call_id, agent_username, setting_name, local, callback_data);
+ g_clear_error (&local);
+ if (hash)
+ g_hash_table_destroy (hash);
+}
+
+/**
+ * nm_settings_connection_get_secrets:
+ * @connection: the #NMSettingsConnection
+ * @filter_by_uid: if TRUE, only request secrets from agents registered by the
+ * same UID as @uid.
+ * @uid: when @filter_by_uid is TRUE, only request secrets from agents belonging
+ * to this UID
+ * @setting_name: the setting to return secrets for
+ * @flags: flags to modify the secrets request
+ * @hint: the name of a key in @setting_name for which a secret may be required
+ * @callback: the function to call with returned secrets
+ * @callback_data: user data to pass to @callback
+ *
+ * Retrieves secrets from persistent storage and queries any secret agents for
+ * additional secrets.
+ *
+ * Returns: a call ID which may be used to cancel the ongoing secrets request
+ **/
+guint32
+nm_settings_connection_get_secrets (NMSettingsConnection *self,
+ gboolean filter_by_uid,
+ gulong uid,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMSettingsConnectionSecretsFunc callback,
+ gpointer callback_data,
+ GError **error)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ GHashTable *existing_secrets;
+ guint32 call_id = 0;
+
+ /* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
+ * will clear secrets on this object's settings. priv->secrets should be
+ * a complete copy of this object and kept in sync by
+ * nm_settings_connection_replace_settings().
+ */
+ if (!priv->secrets) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "%s.%d - Internal error; secrets cache invalid.",
+ __FILE__, __LINE__);
+ return 0;
+ }
+
+ /* Make sure the request actually requests something we can return */
+ if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) {
+ g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING,
+ "%s.%d - Connection didn't have requested setting '%s'.",
+ __FILE__, __LINE__, setting_name);
+ return 0;
+ }
+
+ existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+ call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
+ NM_CONNECTION (self),
+ filter_by_uid,
+ uid,
+ existing_secrets,
+ setting_name,
+ flags,
+ hint,
+ agent_secrets_done_cb,
+ self,
+ callback,
+ callback_data);
+ if (existing_secrets)
+ g_hash_table_unref (existing_secrets);
+
+ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets requested flags 0x%X hint '%s'",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ setting_name,
+ call_id,
+ flags,
+ hint);
+
+ return call_id;
+}
+
+void
+nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
+ guint32 call_id)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+
+ nm_log_dbg (LOGD_SETTINGS, "(%s:%u) secrets canceled",
+ nm_connection_get_uuid (NM_CONNECTION (self)),
+ call_id);
+
+ priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
+ nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id);
+}
+
+/**** User authorization **************************************/
+
+typedef void (*AuthCallback) (NMSettingsConnection *connection,
+ DBusGMethodInvocation *context,
+ gulong sender_uid,
+ GError *error,
+ gpointer data);
+
+static void
+pk_auth_cb (NMAuthChain *chain,
+ GError *chain_error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ GError *error = NULL;
+ NMAuthCallResult result;
+ const char *perm;
+ AuthCallback callback;
+ gpointer callback_data;
+ gulong sender_uid;
+
+ priv->pending_auths = g_slist_remove (priv->pending_auths, chain);
+
+ /* If our NMSettingsConnection is already gone, do nothing */
+ if (chain_error) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_GENERAL,
+ "Error checking authorization: %s",
+ chain_error->message ? chain_error->message : "(unknown)");
+ } else {
+ perm = nm_auth_chain_get_data (chain, "perm");
+ g_assert (perm);
+ result = nm_auth_chain_get_result (chain, perm);
+
+ /* Caller didn't successfully authenticate */
+ if (result != NM_AUTH_CALL_RESULT_YES) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ }
+ }
+
+ callback = nm_auth_chain_get_data (chain, "callback");
+ callback_data = nm_auth_chain_get_data (chain, "callback-data");
+ sender_uid = nm_auth_chain_get_data_ulong (chain, "sender-uid");
+ callback (self, context, sender_uid, error, callback_data);
+
+ g_clear_error (&error);
+ nm_auth_chain_unref (chain);
+}
+
+static gboolean
+check_user_in_acl (NMConnection *connection,
+ DBusGMethodInvocation *context,
+ NMDBusManager *dbus_mgr,
+ NMSessionMonitor *session_monitor,
+ gulong *out_sender_uid,
+ GError **error)
+{
+ gulong sender_uid = G_MAXULONG;
+ char *error_desc = NULL;
+
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (context != NULL, FALSE);
+ g_return_val_if_fail (session_monitor != NULL, FALSE);
+
+ /* Get the caller's UID */
+ if (!nm_auth_get_caller_uid (context, dbus_mgr, &sender_uid, &error_desc)) {
+ g_set_error_literal (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_PERMISSION_DENIED,
+ error_desc);
+ g_free (error_desc);
+ return FALSE;
+ }
+
+ /* Make sure the UID can view this connection */
+ if (0 != sender_uid) {
+ if (!nm_auth_uid_in_acl (connection, session_monitor, sender_uid, &error_desc)) {
+ g_set_error_literal (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_PERMISSION_DENIED,
+ error_desc);
+ g_free (error_desc);
+ return FALSE;
+ }
+ }
+
+ if (out_sender_uid)
+ *out_sender_uid = sender_uid;
+ return TRUE;
+}
+
+static void
+auth_start (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ const char *check_permission,
+ AuthCallback callback,
+ gpointer callback_data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ NMAuthChain *chain;
+ gulong sender_uid = G_MAXULONG;
+ GError *error = NULL;
+
+ if (!check_user_in_acl (NM_CONNECTION (self),
+ context,
+ priv->dbus_mgr,
+ priv->session_monitor,
+ &sender_uid,
+ &error)) {
+ callback (self, context, G_MAXULONG, error, callback_data);
+ g_clear_error (&error);
+ return;
+ }
+
+ if (check_permission) {
+ chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self);
+ g_assert (chain);
+ nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL);
+ nm_auth_chain_set_data (chain, "callback", callback, NULL);
+ nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL);
+ nm_auth_chain_set_data_ulong (chain, "sender-uid", sender_uid);
+
+ nm_auth_chain_add_call (chain, check_permission, TRUE);
+ priv->pending_auths = g_slist_append (priv->pending_auths, chain);
+ } else {
+ /* Don't need polkit auth, automatic success */
+ callback (self, context, sender_uid, NULL, callback_data);
+ }
+}
+
+/**** DBus method handlers ************************************/
+
+static gboolean
+check_writable (NMConnection *connection, GError **error)
+{
+ NMSettingConnection *s_con;
+
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if (!s_con) {
+ g_set_error_literal (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "Connection did not have required 'connection' setting");
+ return FALSE;
+ }
+
+ /* If the connection is read-only, that has to be changed at the source of
+ * the problem (ex a system settings plugin that can't write connections out)
+ * instead of over D-Bus.
+ */
+ if (nm_setting_connection_get_read_only (s_con)) {
+ g_set_error_literal (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
+ "Connection is read-only");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+get_settings_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ gulong sender_uid,
+ GError *error,
+ gpointer data)
+{
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else {
+ GHashTable *settings;
+ NMConnection *dupl_con;
+ NMSettingConnection *s_con;
+ guint64 timestamp;
+
+ dupl_con = nm_connection_duplicate (NM_CONNECTION (self));
+ g_assert (dupl_con);
+
+ /* Timestamp is not updated in connection's 'timestamp' property,
+ * because it would force updating the connection and in turn
+ * writing to /etc periodically, which we want to avoid. Rather real
+ * timestamps are kept track of in a private variable. So, substitute
+ * timestamp property with the real one here before returning the settings.
+ */
+ timestamp = nm_settings_connection_get_timestamp (self);
+ if (timestamp) {
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (dupl_con), NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+ g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL);
+ }
+
+ /* Secrets should *never* be returned by the GetSettings method, they
+ * get returned by the GetSecrets method which can be better
+ * protected against leakage of secrets to unprivileged callers.
+ */
+ settings = nm_connection_to_hash (NM_CONNECTION (dupl_con), NM_SETTING_HASH_FLAG_NO_SECRETS);
+ g_assert (settings);
+ dbus_g_method_return (context, settings);
+ g_hash_table_destroy (settings);
+ g_object_unref (dupl_con);
+ }
+}
+
+static void
+impl_settings_connection_get_settings (NMSettingsConnection *self,
+ DBusGMethodInvocation *context)
+{
+ auth_start (self, context, NULL, get_settings_auth_cb, NULL);
+}
+
+static void
+con_update_cb (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
+
+static void
+only_agent_secrets_cb (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
+{
+ if (flags & NM_SETTING_PARAM_SECRET) {
+ NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* Clear out system-owned or always-ask secrets */
+ if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
+ GHashTableIter iter;
+ const char *secret_name = NULL;
+
+ /* VPNs are special; need to handle each secret separately */
+ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
+ while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) {
+ if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
+ if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name);
+ }
+ }
+ } else {
+ nm_setting_get_secret_flags (setting, key, &secret_flags, NULL);
+ if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ g_object_set (G_OBJECT (setting), key, NULL, NULL);
+ }
+ }
+}
+
+static void
+update_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ gulong sender_uid,
+ GError *error,
+ gpointer data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ NMConnection *new_settings = data;
+ NMConnection *for_agent;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else {
+ /* Update and commit our settings. */
+ nm_settings_connection_replace_and_commit (self,
+ new_settings,
+ con_update_cb,
+ context);
+
+ /* Dupe the connection and clear out non-agent-owned secrets so we can
+ * send the agent-owned ones to agents to be saved. Only send them to
+ * agents of the same UID as the Update() request sender.
+ */
+ for_agent = nm_connection_duplicate (NM_CONNECTION (self));
+ nm_connection_for_each_setting_value (for_agent, only_agent_secrets_cb, NULL);
+ nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, sender_uid);
+ g_object_unref (for_agent);
+ }
+
+ g_object_unref (new_settings);
+}
+
+static const char *
+get_modify_permission_update (NMConnection *old, NMConnection *new)
+{
+ NMSettingConnection *s_con;
+ guint32 orig_num = 0, new_num = 0;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (old, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ orig_num = nm_setting_connection_get_num_permissions (s_con);
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (new, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ new_num = nm_setting_connection_get_num_permissions (s_con);
+
+ /* If the caller is the only user in either connection's permissions, then
+ * we use the 'modify.own' permission instead of 'modify.system'.
+ */
+ if (orig_num == 1 && new_num == 1)
+ return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
+
+ /* If the update request affects more than just the caller (ie if the old
+ * settings were system-wide, or the new ones are), require 'modify.system'.
+ */
+ return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
+}
+
+static void
+impl_settings_connection_update (NMSettingsConnection *self,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ NMConnection *tmp;
+ GError *error = NULL;
+
+ /* If the connection is read-only, that has to be changed at the source of
+ * the problem (ex a system settings plugin that can't write connections out)
+ * instead of over D-Bus.
+ */
+ if (!check_writable (NM_CONNECTION (self), &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (new_settings, &error);
+ if (!tmp) {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ /* And that the new connection settings will be visible to the user
+ * that's sending the update request. You can't make a connection
+ * invisible to yourself.
+ */
+ if (!check_user_in_acl (tmp,
+ context,
+ priv->dbus_mgr,
+ priv->session_monitor,
+ NULL,
+ &error)) {
+ dbus_g_method_return_error (context, error);
+ g_clear_error (&error);
+ g_object_unref (tmp);
+ return;
+ }
+
+ auth_start (self,
+ context,
+ get_modify_permission_update (NM_CONNECTION (self), tmp),
+ update_auth_cb,
+ tmp);
+}
+
+static void
+con_delete_cb (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+ DBusGMethodInvocation *context = user_data;
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+}
+
+static void
+delete_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ gulong sender_uid,
+ GError *error,
+ gpointer data)
+{
+ if (error) {
+ dbus_g_method_return_error (context, error);
+ return;
+ }
+
+ nm_settings_connection_delete (self, con_delete_cb, context);
+}
+
+static const char *
+get_modify_permission_basic (NMSettingsConnection *connection)
+{
+ NMSettingConnection *s_con;
+
+ /* If the caller is the only user in the connection's permissions, then
+ * we use the 'modify.own' permission instead of 'modify.system'. If the
+ * request affects more than just the caller, require 'modify.system'.
+ */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ if (nm_setting_connection_get_num_permissions (s_con) == 1)
+ return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
+
+ return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
+}
+
+static void
+impl_settings_connection_delete (NMSettingsConnection *self,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+
+ if (!check_writable (NM_CONNECTION (self), &error)) {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ auth_start (self, context, get_modify_permission_basic (self), delete_auth_cb, NULL);
+}
+
+/**************************************************************/
+
+static void
+dbus_get_agent_secrets_cb (NMSettingsConnection *self,
+ guint32 call_id,
+ const char *agent_username,
+ const char *setting_name,
+ GError *error,
+ gpointer user_data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ DBusGMethodInvocation *context = user_data;
+ GHashTable *hash;
+
+ priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
+
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else {
+ /* The connection's secrets will have been updated by the agent manager,
+ * so we want to refresh the secrets cache. Note that we will never save
+ * new secrets to backing storage here because D-Bus initated requests will
+ * never ask for completely new secrets from agents. Thus system-owned
+ * secrets should not have changed from backing storage. We also don't
+ * send agent-owned secrets back out to be saved since we assume the agent
+ * that provided the secrets saved them itself.
+ */
+ update_secrets_cache (self);
+
+ hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS);
+ dbus_g_method_return (context, hash);
+ g_hash_table_destroy (hash);
+ }
+}
+
+static void
+dbus_secrets_auth_cb (NMSettingsConnection *self,
+ DBusGMethodInvocation *context,
+ gulong sender_uid,
+ GError *error,
+ gpointer user_data)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ char *setting_name = user_data;
+ guint32 call_id = 0;
+ GError *local = NULL;
+
+ if (!error) {
+ call_id = nm_settings_connection_get_secrets (self,
+ TRUE,
+ sender_uid,
+ setting_name,
+ NM_SETTINGS_GET_SECRETS_FLAG_NONE,
+ NULL,
+ dbus_get_agent_secrets_cb,
+ context,
+ &local);
+ if (call_id > 0) {
+ /* track the request and wait for the callback */
+ priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id));
+ }
+ }
+
+ if (error || local) {
+ dbus_g_method_return_error (context, error ? error : local);
+ g_clear_error (&local);
+ }
+
+ g_free (setting_name);
+}
+
+static void
+impl_settings_connection_get_secrets (NMSettingsConnection *self,
+ const gchar *setting_name,
+ DBusGMethodInvocation *context)
+{
+ auth_start (self,
+ context,
+ get_modify_permission_basic (self),
+ dbus_secrets_auth_cb,
+ g_strdup (setting_name));
+}
+
+/**************************************************************/
+
+void
+nm_settings_connection_signal_remove (NMSettingsConnection *self)
+{
+ /* Emit removed first */
+ g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED);
+
+ /* And unregistered last to ensure the removed signal goes out before
+ * we take the connection off the bus.
+ */
+ g_signal_emit_by_name (self, "unregister");
+}
+
+/**
+ * nm_settings_connection_get_timestamp:
+ * @connection: the #NMSettingsConnection
+ *
+ * Returns current connection's timestamp.
+ *
+ * Returns: timestamp of the last connection use (0 when it's not used)
+ **/
+guint64
+nm_settings_connection_get_timestamp (NMSettingsConnection *connection)
+{
+ g_return_val_if_fail (NM_SETTINGS_CONNECTION (connection), 0);
+
+ return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->timestamp;
+}
+
+/**
+ * nm_settings_connection_update_timestamp:
+ * @connection: the #NMSettingsConnection
+ * @timestamp: timestamp to set into the connection and to store into
+ * the timestamps database
+ *
+ * Updates the connection and timestamps database with the provided timestamp.
+ **/
+void
+nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+ const char *connection_uuid;
+ GKeyFile *timestamps_file;
+ char *data, *tmp;
+ gsize len;
+ GError *error = NULL;
+
+ /* Update timestamp in private storage */
+ priv->timestamp = timestamp;
+
+ /* Save timestamp to timestamps database file */
+ timestamps_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, &error)) {
+ if (!(error->domain == G_FILE_ERROR && error->code == G_FILE_ERROR_NOENT))
+ nm_log_warn (LOGD_SETTINGS, "error parsing timestamps file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message);
+ g_clear_error (&error);
+ }
+
+ connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection));
+ tmp = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp);
+ g_key_file_set_value (timestamps_file, "timestamps", connection_uuid, tmp);
+ g_free (tmp);
+
+ data = g_key_file_to_data (timestamps_file, &len, &error);
+ if (data) {
+ g_file_set_contents (SETTINGS_TIMESTAMPS_FILE, data, len, &error);
+ g_free (data);
+ }
+ if (error) {
+ nm_log_warn (LOGD_SETTINGS, "error saving timestamp to file '%s': %s", SETTINGS_TIMESTAMPS_FILE, error->message);
+ g_error_free (error);
+ }
+ g_key_file_free (timestamps_file);
+}
+
+/**
+ * nm_settings_connection_read_and_fill_timestamp:
+ * @connection: the #NMSettingsConnection
+ *
+ * Retrieves timestamp of the connection's last usage from database file and
+ * stores it into the connection private data.
+ **/
+void
+nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
+ const char *connection_uuid;
+ guint64 timestamp = 0;
+ GKeyFile *timestamps_file;
+ GError *err = NULL;
+ char *tmp_str;
+
+ /* Get timestamp from database file */
+ timestamps_file = g_key_file_new ();
+ g_key_file_load_from_file (timestamps_file, SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL);
+ connection_uuid = nm_connection_get_uuid (NM_CONNECTION (connection));
+ tmp_str = g_key_file_get_value (timestamps_file, "timestamps", connection_uuid, &err);
+ if (tmp_str) {
+ timestamp = g_ascii_strtoull (tmp_str, NULL, 10);
+ g_free (tmp_str);
+ }
+
+ /* Update connection's timestamp */
+ if (!err)
+ priv->timestamp = timestamp;
+ else {
+ nm_log_dbg (LOGD_SETTINGS, "failed to read connection timestamp for '%s': (%d) %s",
+ connection_uuid, err->code, err->message);
+ g_clear_error (&err);
+ }
+ g_key_file_free (timestamps_file);
+}
+
+/**************************************************************/
+
+static void
+nm_settings_connection_init (NMSettingsConnection *self)
+{
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ static guint32 dbus_counter = 0;
+ char *dbus_path;
+ GError *error = NULL;
+
+ priv->dbus_mgr = nm_dbus_manager_get ();
+
+ priv->authority = polkit_authority_get_sync (NULL, &error);
+ if (!priv->authority) {
+ nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+
+ dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++);
+ nm_connection_set_path (NM_CONNECTION (self), dbus_path);
+ g_free (dbus_path);
+ priv->visible = FALSE;
+
+ priv->session_monitor = nm_session_monitor_get ();
+ priv->session_changed_id = g_signal_connect (priv->session_monitor,
+ NM_SESSION_MONITOR_CHANGED,
+ G_CALLBACK (session_changed_cb),
+ self);
+
+ priv->agent_mgr = nm_agent_manager_get ();
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object);
+ NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
+ GSList *iter;
+
+ if (priv->disposed)
+ goto out;
+ priv->disposed = TRUE;
+
+ if (priv->secrets)
+ g_object_unref (priv->secrets);
+
+ /* Cancel PolicyKit requests */
+ for (iter = priv->pending_auths; iter; iter = g_slist_next (iter))
+ nm_auth_chain_unref ((NMAuthChain *) iter->data);
+ g_slist_free (priv->pending_auths);
+ priv->pending_auths = NULL;
+
+ /* Cancel in-progress secrets requests */
+ for (iter = priv->reqs; iter; iter = g_slist_next (iter))
+ nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data));
+ g_slist_free (priv->reqs);
+
+ set_visible (self, FALSE);
+
+ g_object_unref (priv->session_monitor);
+ g_object_unref (priv->agent_mgr);
+ g_object_unref (priv->dbus_mgr);
+ g_object_unref (priv->authority);
+
+out:
+ G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_VISIBLE:
+ g_value_set_boolean (value, NM_SETTINGS_CONNECTION_GET_PRIVATE (object)->visible);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+nm_settings_connection_class_init (NMSettingsConnectionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMSettingsConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->dispose = dispose;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ class->commit_changes = commit_changes;
+ class->delete = do_delete;
+ class->supports_secrets = supports_secrets;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_VISIBLE,
+ g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE,
+ "Visible",
+ "Visible",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* Signals */
+ signals[UPDATED] =
+ g_signal_new (NM_SETTINGS_CONNECTION_UPDATED,
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[REMOVED] =
+ g_signal_new (NM_SETTINGS_CONNECTION_REMOVED,
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* Not exported */
+ signals[UNREGISTER] =
+ g_signal_new ("unregister",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
+ &dbus_glib_nm_settings_connection_object_info);
+}
diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h
new file mode 100644
index 000000000..116bfdcc9
--- /dev/null
+++ b/src/settings/nm-settings-connection.h
@@ -0,0 +1,129 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_CONNECTION_H
+#define NM_SETTINGS_CONNECTION_H
+
+#include <nm-connection.h>
+#include "nm-settings-flags.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ())
+#define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection))
+#define NM_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass))
+#define NM_IS_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION))
+#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION))
+#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass))
+
+#define NM_SETTINGS_CONNECTION_UPDATED "updated"
+#define NM_SETTINGS_CONNECTION_REMOVED "removed"
+#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets"
+#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets"
+
+#define NM_SETTINGS_CONNECTION_VISIBLE "visible"
+
+typedef struct _NMSettingsConnection NMSettingsConnection;
+
+typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
+
+typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data);
+
+struct _NMSettingsConnection {
+ NMConnection parent;
+};
+
+struct _NMSettingsConnectionClass {
+ NMConnectionClass parent;
+
+ /* virtual methods */
+ void (*commit_changes) (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data);
+
+ void (*delete) (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data);
+
+ gboolean (*supports_secrets) (NMSettingsConnection *connection,
+ const char *setting_name);
+};
+
+GType nm_settings_connection_get_type (void);
+
+void nm_settings_connection_commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data);
+
+gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self,
+ NMConnection *new_settings,
+ GError **error);
+
+void nm_settings_connection_replace_and_commit (NMSettingsConnection *self,
+ NMConnection *new_settings,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data);
+
+void nm_settings_connection_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data);
+
+typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connection,
+ guint32 call_id,
+ const char *agent_username,
+ const char *setting_name,
+ GError *error,
+ gpointer user_data);
+
+guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection,
+ gboolean filter_by_uid,
+ gulong uid,
+ const char *setting_name,
+ NMSettingsGetSecretsFlags flags,
+ const char *hint,
+ NMSettingsConnectionSecretsFunc callback,
+ gpointer callback_data,
+ GError **error);
+
+void nm_settings_connection_cancel_secrets (NMSettingsConnection *connection,
+ guint32 call_id);
+
+gboolean nm_settings_connection_is_visible (NMSettingsConnection *self);
+
+void nm_settings_connection_recheck_visibility (NMSettingsConnection *self);
+
+void nm_settings_connection_signal_remove (NMSettingsConnection *self);
+
+guint64 nm_settings_connection_get_timestamp (NMSettingsConnection *connection);
+
+void nm_settings_connection_update_timestamp (NMSettingsConnection *connection, guint64 timestamp);
+
+void nm_settings_connection_read_and_fill_timestamp (NMSettingsConnection *connection);
+
+G_END_DECLS
+
+#endif /* NM_SETTINGS_CONNECTION_H */
diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c
new file mode 100644
index 000000000..7e24fb71f
--- /dev/null
+++ b/src/settings/nm-settings-error.c
@@ -0,0 +1,83 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include "nm-settings-error.h"
+
+GQuark
+nm_settings_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (ret == 0)
+ ret = g_quark_from_static_string ("nm-settings-error");
+
+ return ret;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_settings_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ ENUM_ENTRY (NM_SETTINGS_ERROR_GENERAL, "GeneralError"),
+
+ /* The connection was invalid. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"),
+ /* The connection is read-only; modifications are not allowed. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"),
+ /* A bug in the settings service caused the error. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"),
+ /* Retrieval or request of secrets failed. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"),
+ /* The request for secrets was canceled. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"),
+ /* The request could not be completed because permission was denied. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"),
+ /* The requested setting does not existing in this connection. */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"),
+ /* The caller does not have permission to perform this operation */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
+ /* No plugin supports adding new connections */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"),
+ /* The plugin providing this connection does not support updating it */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"),
+ /* The plugin providing this connection does not support deleting it */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"),
+ /* Failed to add the connection */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"),
+ /* No plugin supports modifying the system hostname */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"),
+ /* Saving the system hostname failed */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"),
+ /* A connection with this UUID already exists */
+ ENUM_ENTRY (NM_SETTINGS_ERROR_UUID_EXISTS, "UuidExists"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("NMSettingsError", values);
+ }
+
+ return etype;
+}
diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h
new file mode 100644
index 000000000..b782a7791
--- /dev/null
+++ b/src/settings/nm-settings-error.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_ERROR_H
+#define NM_SETTINGS_ERROR_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+enum {
+ NM_SETTINGS_ERROR_GENERAL = 0,
+ NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
+ NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED,
+ NM_SETTINGS_ERROR_PERMISSION_DENIED,
+ NM_SETTINGS_ERROR_INVALID_SETTING,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
+ NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED,
+ NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED,
+ NM_SETTINGS_ERROR_ADD_FAILED,
+ NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
+ NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
+ NM_SETTINGS_ERROR_UUID_EXISTS,
+};
+
+#define NM_SETTINGS_ERROR (nm_settings_error_quark ())
+GQuark nm_settings_error_quark (void);
+
+#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ())
+GType nm_settings_error_get_type (void);
+
+#endif /* NM_SETTINGS_ERROR_H */
diff --git a/src/settings/nm-settings-utils.c b/src/settings/nm-settings-utils.c
new file mode 100644
index 000000000..d0e21fbdf
--- /dev/null
+++ b/src/settings/nm-settings-utils.c
@@ -0,0 +1,66 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2011 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include <nm-connection.h>
+#include "nm-settings-utils.h"
+
+char *
+nm_settings_utils_get_default_wired_name (GHashTable *connections)
+{
+ GHashTableIter iter;
+ NMConnection *connection = NULL;
+ GSList *names = NULL, *niter;
+ char *cname = NULL;
+ int i = 0;
+
+ /* Build up a list of all existing connection names for dupe checking */
+ g_hash_table_iter_init (&iter, connections);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) {
+ const char *id;
+
+ id = nm_connection_get_id (connection);
+ g_assert (id);
+ names = g_slist_append (names, (gpointer) id);
+ }
+
+ /* Find the next available unique connection name */
+ while (!cname && (i++ < 10000)) {
+ char *temp;
+ gboolean found = FALSE;
+
+ temp = g_strdup_printf (_("Wired connection %d"), i);
+ for (niter = names; niter; niter = g_slist_next (niter)) {
+ if (g_strcmp0 (niter->data, temp) == 0) {
+ found = TRUE;
+ g_free (temp);
+ break;
+ }
+ }
+
+ if (found == FALSE)
+ cname = temp;
+ }
+ g_slist_free (names);
+
+ return cname;
+}
+
diff --git a/src/settings/nm-settings-utils.h b/src/settings/nm-settings-utils.h
new file mode 100644
index 000000000..f669d2b10
--- /dev/null
+++ b/src/settings/nm-settings-utils.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_UTILS_H
+#define NM_SETTINGS_UTILS_H
+
+#include <glib.h>
+
+char *nm_settings_utils_get_default_wired_name (GHashTable *connections);
+
+#endif /* NM_SETTINGS_UTILS_H */
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
new file mode 100644
index 000000000..f6dbf5e31
--- /dev/null
+++ b/src/settings/nm-settings.c
@@ -0,0 +1,1663 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ * Dan Williams <dcbw@redhat.com>
+ * Tambet Ingo <tambet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2011 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <gmodule.h>
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+#include <pwd.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <NetworkManager.h>
+#include <nm-connection.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-olpc-mesh.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-serial.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+
+#include "../nm-device-ethernet.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-settings.h"
+#include "nm-settings-connection.h"
+#include "nm-polkit-helpers.h"
+#include "nm-settings-error.h"
+#include "nm-default-wired-connection.h"
+#include "nm-logging.h"
+#include "nm-dbus-manager.h"
+#include "nm-manager-auth.h"
+#include "nm-session-monitor.h"
+#include "plugins/keyfile/plugin.h"
+#include "nm-agent-manager.h"
+#include "nm-settings-utils.h"
+
+#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
+
+/* LINKER CRACKROCK */
+#define EXPORT(sym) void * __export_##sym = &sym;
+
+#include "nm-inotify-helper.h"
+EXPORT(nm_inotify_helper_get_type)
+EXPORT(nm_inotify_helper_get)
+EXPORT(nm_inotify_helper_add_watch)
+EXPORT(nm_inotify_helper_remove_watch)
+
+EXPORT(nm_settings_connection_get_type)
+EXPORT(nm_settings_connection_replace_settings)
+EXPORT(nm_settings_connection_replace_and_commit)
+/* END LINKER CRACKROCK */
+
+static void claim_connection (NMSettings *self,
+ NMSettingsConnection *connection,
+ gboolean do_export);
+
+static gboolean impl_settings_list_connections (NMSettings *self,
+ GPtrArray **connections,
+ GError **error);
+
+static void impl_settings_add_connection (NMSettings *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+
+static void impl_settings_save_hostname (NMSettings *self,
+ const char *hostname,
+ DBusGMethodInvocation *context);
+
+#include "nm-settings-glue.h"
+
+static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
+
+typedef struct {
+ NMDBusManager *dbus_mgr;
+ DBusGConnection *bus;
+
+ NMAgentManager *agent_mgr;
+
+ PolkitAuthority *authority;
+ guint auth_changed_id;
+ char *config_file;
+
+ NMSessionMonitor *session_monitor;
+ GSList *auths;
+
+ GSList *plugins;
+ gboolean connections_loaded;
+ GHashTable *connections;
+ GSList *unmanaged_specs;
+} NMSettingsPrivate;
+
+G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT)
+
+#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate))
+
+enum {
+ PROPERTIES_CHANGED,
+ CONNECTION_ADDED,
+ CONNECTION_UPDATED,
+ CONNECTION_REMOVED,
+ CONNECTION_VISIBILITY_CHANGED,
+ CONNECTIONS_LOADED,
+
+ NEW_CONNECTION, /* exported, not used internally */
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+enum {
+ PROP_0,
+ PROP_UNMANAGED_SPECS,
+ PROP_HOSTNAME,
+ PROP_CAN_MODIFY,
+
+ LAST_PROP
+};
+
+static void
+load_connections (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ if (priv->connections_loaded)
+ return;
+
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ GSList *plugin_connections;
+ GSList *elt;
+
+ plugin_connections = nm_system_config_interface_get_connections (plugin);
+
+ // FIXME: ensure connections from plugins loaded with a lower priority
+ // get rejected when they conflict with connections from a higher
+ // priority plugin.
+
+ for (elt = plugin_connections; elt; elt = g_slist_next (elt))
+ claim_connection (self, NM_SETTINGS_CONNECTION (elt->data), TRUE);
+
+ g_slist_free (plugin_connections);
+ }
+
+ priv->connections_loaded = TRUE;
+
+ /* FIXME: Bad hack */
+ unmanaged_specs_changed (NULL, self);
+
+ g_signal_emit (self, signals[CONNECTIONS_LOADED], 0);
+}
+
+void
+nm_settings_for_each_connection (NMSettings *self,
+ NMSettingsForEachFunc for_each_func,
+ gpointer user_data)
+{
+ NMSettingsPrivate *priv;
+ GHashTableIter iter;
+ gpointer data;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (NM_IS_SETTINGS (self));
+ g_return_if_fail (for_each_func != NULL);
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ load_connections (self);
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
+}
+
+static gboolean
+impl_settings_list_connections (NMSettings *self,
+ GPtrArray **connections,
+ GError **error)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer key;
+
+ load_connections (self);
+
+ *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ g_ptr_array_add (*connections, g_strdup ((const char *) key));
+ return TRUE;
+}
+
+static int
+connection_sort (gconstpointer pa, gconstpointer pb)
+{
+ NMConnection *a = NM_CONNECTION (pa);
+ NMSettingConnection *con_a;
+ NMConnection *b = NM_CONNECTION (pb);
+ NMSettingConnection *con_b;
+ guint64 ts_a, ts_b;
+
+ con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION);
+ g_assert (con_a);
+ con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
+ g_assert (con_b);
+
+ if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) {
+ if (nm_setting_connection_get_autoconnect (con_a))
+ return -1;
+ return 1;
+ }
+
+ ts_a = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pa));
+ ts_b = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (pb));
+ if (ts_a > ts_b)
+ return -1;
+ else if (ts_a == ts_b)
+ return 0;
+ return 1;
+}
+
+/* Returns a list of NMSettingsConnections. Caller must free the list with
+ * g_slist_free().
+ */
+GSList *
+nm_settings_get_connections (NMSettings *self)
+{
+ GHashTableIter iter;
+ gpointer data = NULL;
+ GSList *list = NULL;
+
+ g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
+
+ g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ list = g_slist_insert_sorted (list, data, connection_sort);
+ return list;
+}
+
+NMSettingsConnection *
+nm_settings_get_connection_by_path (NMSettings *self, const char *path)
+{
+ NMSettingsPrivate *priv;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS (self), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ load_connections (self);
+
+ return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path);
+}
+
+static void
+clear_unmanaged_specs (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL);
+ g_slist_free (priv->unmanaged_specs);
+ priv->unmanaged_specs = NULL;
+}
+
+static char*
+uscore_to_wincaps (const char *uscore)
+{
+ const char *p;
+ GString *str;
+ gboolean last_was_uscore;
+
+ last_was_uscore = TRUE;
+
+ str = g_string_new (NULL);
+ p = uscore;
+ while (p && *p) {
+ if (*p == '-' || *p == '_')
+ last_was_uscore = TRUE;
+ else {
+ if (last_was_uscore) {
+ g_string_append_c (str, g_ascii_toupper (*p));
+ last_was_uscore = FALSE;
+ } else
+ g_string_append_c (str, *p);
+ }
+ ++p;
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+static void
+notify (GObject *object, GParamSpec *pspec)
+{
+ GValue *value;
+ GHashTable *hash;
+
+ value = g_slice_new0 (GValue);
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
+
+ g_value_init (value, pspec->value_type);
+ g_object_get_property (object, pspec->name, value);
+ g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value);
+ g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash);
+ g_hash_table_destroy (hash);
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+const GSList *
+nm_settings_get_unmanaged_specs (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ load_connections (self);
+ return priv->unmanaged_specs;
+}
+
+static NMSystemConfigInterface *
+get_plugin (NMSettings *self, guint32 capability)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ g_return_val_if_fail (self != NULL, NULL);
+
+ /* Do any of the plugins support setting the hostname? */
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
+
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
+ if (caps & capability)
+ return NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ }
+
+ return NULL;
+}
+
+/* Returns an allocated string which the caller owns and must eventually free */
+char *
+nm_settings_get_hostname (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+ char *hostname = NULL;
+
+ /* Hostname returned is the hostname returned from the first plugin
+ * that provides one.
+ */
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
+
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
+ if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
+ if (hostname && strlen (hostname))
+ return hostname;
+ g_free (hostname);
+ }
+ }
+
+ return NULL;
+}
+
+static void
+plugin_connection_added (NMSystemConfigInterface *config,
+ NMSettingsConnection *connection,
+ gpointer user_data)
+{
+ claim_connection (NM_SETTINGS (user_data), connection, TRUE);
+}
+
+static gboolean
+find_unmanaged_device (NMSettings *self, const char *needle)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) {
+ if (!strcmp ((const char *) iter->data, needle))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+unmanaged_specs_changed (NMSystemConfigInterface *config,
+ gpointer user_data)
+{
+ NMSettings *self = NM_SETTINGS (user_data);
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ clear_unmanaged_specs (self);
+
+ /* Ask all the plugins for their unmanaged specs */
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ GSList *specs, *specs_iter;
+
+ specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
+ for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) {
+ if (!find_unmanaged_device (self, (const char *) specs_iter->data)) {
+ priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data);
+ } else
+ g_free (specs_iter->data);
+ }
+
+ g_slist_free (specs);
+ }
+
+ g_object_notify (G_OBJECT (self), NM_SETTINGS_UNMANAGED_SPECS);
+}
+
+static void
+hostname_changed (NMSystemConfigInterface *config,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME);
+}
+
+static void
+add_plugin (NMSettings *self, NMSystemConfigInterface *plugin)
+{
+ NMSettingsPrivate *priv;
+ char *pname = NULL;
+ char *pinfo = NULL;
+
+ g_return_if_fail (NM_IS_SETTINGS (self));
+ g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
+
+ g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
+ G_CALLBACK (plugin_connection_added), self);
+ g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
+
+ nm_system_config_interface_init (plugin, NULL);
+
+ g_object_get (G_OBJECT (plugin),
+ NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo,
+ NULL);
+
+ g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
+ G_CALLBACK (unmanaged_specs_changed), self);
+
+ nm_log_info (LOGD_SETTINGS, "Loaded plugin %s: %s", pname, pinfo);
+ g_free (pname);
+ g_free (pinfo);
+}
+
+static GObject *
+find_plugin (GSList *list, const char *pname)
+{
+ GSList *iter;
+ GObject *obj = NULL;
+
+ g_return_val_if_fail (pname != NULL, NULL);
+
+ for (iter = list; iter && !obj; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ char *list_pname = NULL;
+
+ g_object_get (G_OBJECT (plugin),
+ NM_SYSTEM_CONFIG_INTERFACE_NAME,
+ &list_pname,
+ NULL);
+ if (list_pname && !strcmp (pname, list_pname))
+ obj = G_OBJECT (plugin);
+
+ g_free (list_pname);
+ }
+
+ return obj;
+}
+
+static gboolean
+load_plugins (NMSettings *self, const char *plugins, GError **error)
+{
+ GSList *list = NULL;
+ char **plist;
+ char **iter;
+ gboolean success = TRUE;
+
+ plist = g_strsplit (plugins, ",", 0);
+ if (!plist)
+ return FALSE;
+
+ for (iter = plist; *iter; iter++) {
+ GModule *plugin;
+ char *full_name, *path;
+ const char *pname = g_strstrip (*iter);
+ GObject *obj;
+ GObject * (*factory_func) (void);
+
+ /* keyfile plugin built in now */
+ if (!strcmp (pname, "keyfile"))
+ continue;
+
+ /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */
+ if (!strcmp (pname, "ifcfg-fedora"))
+ pname = "ifcfg-rh";
+
+ obj = find_plugin (list, pname);
+ if (obj)
+ continue;
+
+ full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
+ path = g_module_build_path (PLUGINDIR, full_name);
+
+ plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
+ if (!plugin) {
+ g_set_error (error, 0, 0,
+ "Could not load plugin '%s': %s",
+ pname, g_module_error ());
+ g_free (full_name);
+ g_free (path);
+ success = FALSE;
+ break;
+ }
+
+ g_free (full_name);
+ g_free (path);
+
+ if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
+ g_set_error (error, 0, 0,
+ "Could not find plugin '%s' factory function.",
+ pname);
+ success = FALSE;
+ break;
+ }
+
+ obj = (*factory_func) ();
+ if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
+ g_set_error (error, 0, 0,
+ "Plugin '%s' returned invalid system config object.",
+ pname);
+ success = FALSE;
+ break;
+ }
+
+ g_module_make_resident (plugin);
+ g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
+ add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
+ list = g_slist_append (list, obj);
+ }
+
+ g_strfreev (plist);
+
+ g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+ g_slist_free (list);
+
+ return success;
+}
+
+#define REMOVED_ID_TAG "removed-id-tag"
+#define UPDATED_ID_TAG "updated-id-tag"
+#define VISIBLE_ID_TAG "visible-id-tag"
+#define UNREG_ID_TAG "unreg-id-tag"
+
+static void
+connection_removed (NMSettingsConnection *obj, gpointer user_data)
+{
+ GObject *connection = G_OBJECT (obj);
+ guint id;
+ g_object_ref (connection);
+
+ /* Disconnect signal handlers, as plugins might still keep references
+ * to the connection (and thus the signal handlers would still be live)
+ * even after NMSettings has dropped all its references.
+ */
+
+ id = GPOINTER_TO_UINT (g_object_get_data (connection, REMOVED_ID_TAG));
+ if (id)
+ g_signal_handler_disconnect (connection, id);
+
+ id = GPOINTER_TO_UINT (g_object_get_data (connection, UPDATED_ID_TAG));
+ if (id)
+ g_signal_handler_disconnect (connection, id);
+
+ id = GPOINTER_TO_UINT (g_object_get_data (connection, VISIBLE_ID_TAG));
+ if (id)
+ g_signal_handler_disconnect (connection, id);
+
+ /* Forget about the connection internall */
+ g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections,
+ (gpointer) nm_connection_get_path (NM_CONNECTION (connection)));
+
+ /* Re-emit for listeners like NMPolicy */
+ g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection);
+
+ g_object_unref (connection);
+}
+
+static void
+connection_unregister (NMSettingsConnection *obj, gpointer user_data)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data);
+ GObject *connection = G_OBJECT (obj);
+ guint id;
+
+ /* Make sure it's unregistered from the bus now that's removed */
+ dbus_g_connection_unregister_g_object (priv->bus, connection);
+
+ id = GPOINTER_TO_UINT (g_object_get_data (connection, UNREG_ID_TAG));
+ if (id)
+ g_signal_handler_disconnect (connection, id);
+}
+
+static void
+connection_updated (NMSettingsConnection *connection, gpointer user_data)
+{
+ /* Re-emit for listeners like NMPolicy */
+ g_signal_emit (NM_SETTINGS (user_data),
+ signals[CONNECTION_UPDATED],
+ 0,
+ connection);
+}
+
+static void
+connection_visibility_changed (NMSettingsConnection *connection,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ /* Re-emit for listeners like NMPolicy */
+ g_signal_emit (NM_SETTINGS (user_data),
+ signals[CONNECTION_VISIBILITY_CHANGED],
+ 0,
+ connection);
+}
+
+static void
+claim_connection (NMSettings *self,
+ NMSettingsConnection *connection,
+ gboolean do_export)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ static guint32 ec_counter = 0;
+ GError *error = NULL;
+ GHashTableIter iter;
+ gpointer data;
+ char *path;
+ guint id;
+
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection));
+ g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &data)) {
+ /* prevent duplicates */
+ if (data == connection)
+ return;
+ }
+
+ if (!nm_connection_verify (NM_CONNECTION (connection), &error)) {
+ nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: '%s' / '%s' invalid: %d",
+ g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
+ error->message, error->code);
+ g_error_free (error);
+ return;
+ }
+
+ /* Read timestamp from look-aside file and put it into the connection's data */
+ nm_settings_connection_read_and_fill_timestamp (connection);
+
+ /* Ensure it's initial visibility is up-to-date */
+ nm_settings_connection_recheck_visibility (connection);
+
+ id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED,
+ G_CALLBACK (connection_removed),
+ self);
+ g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id));
+
+ id = g_signal_connect (connection, "unregister",
+ G_CALLBACK (connection_unregister),
+ self);
+ g_object_set_data (G_OBJECT (connection), UNREG_ID_TAG, GUINT_TO_POINTER (id));
+
+ id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED,
+ G_CALLBACK (connection_updated),
+ self);
+ g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id));
+
+ id = g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE,
+ G_CALLBACK (connection_visibility_changed),
+ self);
+ g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id));
+
+ /* Export the connection over D-Bus */
+ g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL);
+ path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
+ nm_connection_set_path (NM_CONNECTION (connection), path);
+ dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection));
+ g_free (path);
+
+ g_hash_table_insert (priv->connections,
+ (gpointer) nm_connection_get_path (NM_CONNECTION (connection)),
+ g_object_ref (connection));
+
+ /* Only emit the individual connection-added signal after connections
+ * have been initially loaded. While getting the first list of connections
+ * we suppress it, then send the connections-loaded signal after we're all
+ * done to minimize processing.
+ */
+ if (priv->connections_loaded) {
+ /* Internal added signal */
+ g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
+
+ /* Exported D-Bus signal */
+ g_signal_emit (self, signals[NEW_CONNECTION], 0, connection);
+ }
+}
+
+// TODO it seems that this is only ever used to remove a
+// NMDefaultWiredConnection, and it probably needs to stay that way. So this
+// *needs* a better name!
+static void
+remove_default_wired_connection (NMSettings *self,
+ NMSettingsConnection *connection,
+ gboolean do_signal)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ const char *path = nm_connection_get_path (NM_CONNECTION (connection));
+
+ if (g_hash_table_lookup (priv->connections, path)) {
+ g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_CONNECTION_REMOVED);
+ g_hash_table_remove (priv->connections, path);
+ }
+}
+
+static NMSettingsConnection *
+add_new_connection (NMSettings *self,
+ NMConnection *connection,
+ GError **error)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+ NMSettingsConnection *added = NULL;
+ GHashTableIter citer;
+ NMConnection *candidate = NULL;
+
+ /* Make sure a connection with this UUID doesn't already exist */
+ g_hash_table_iter_init (&citer, priv->connections);
+ while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) {
+ if (g_strcmp0 (nm_connection_get_uuid (connection),
+ nm_connection_get_uuid (candidate)) == 0) {
+ g_set_error_literal (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_UUID_EXISTS,
+ "A connection with this UUID already exists.");
+ return NULL;
+ }
+ }
+
+ /* 1) plugin writes the NMConnection to disk
+ * 2) plugin creates a new NMSettingsConnection subclass with the settings
+ * from the NMConnection and returns it to the settings service
+ * 3) settings service exports the new NMSettingsConnection subclass
+ * 4) plugin notices that something on the filesystem has changed
+ * 5) plugin reads the changes and ignores them because they will
+ * contain the same data as the connection it already knows about
+ */
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ GError *add_error = NULL;
+
+ g_clear_error (error);
+ added = nm_system_config_interface_add_connection (plugin, connection, &add_error);
+ if (added) {
+ claim_connection (self, added, TRUE);
+ return added;
+ }
+ g_propagate_error (error, add_error);
+ }
+ return NULL;
+}
+
+static void
+pk_add_cb (NMAuthChain *chain,
+ GError *chain_error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ NMSettings *self = NM_SETTINGS (user_data);
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMAuthCallResult result;
+ GError *error = NULL, *add_error = NULL;
+ NMConnection *connection;
+ NMSettingsConnection *added = NULL;
+ NMSettingsAddCallback callback;
+ gpointer callback_data;
+ const char *perm;
+
+ priv->auths = g_slist_remove (priv->auths, chain);
+
+ if (chain_error) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_GENERAL,
+ "Error checking authorization: %s",
+ chain_error->message ? chain_error->message : "(unknown)");
+ goto done;
+ }
+
+ perm = nm_auth_chain_get_data (chain, "perm");
+ g_assert (perm);
+ result = nm_auth_chain_get_result (chain, perm);
+
+ /* Caller didn't successfully authenticate */
+ if (result != NM_AUTH_CALL_RESULT_YES) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ goto done;
+ }
+
+ connection = nm_auth_chain_get_data (chain, "connection");
+ g_assert (connection);
+ added = add_new_connection (self, connection, &add_error);
+ if (!added) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_ADD_FAILED,
+ "Saving connection failed: (%d) %s",
+ add_error ? add_error->code : -1,
+ (add_error && add_error->message) ? add_error->message : "(unknown)");
+ g_error_free (add_error);
+ }
+
+done:
+ callback = nm_auth_chain_get_data (chain, "callback");
+ callback_data = nm_auth_chain_get_data (chain, "callback-data");
+
+ callback (self, added, error, context, callback_data);
+
+ g_clear_error (&error);
+ nm_auth_chain_unref (chain);
+}
+
+static void
+add_cb (NMSettings *self,
+ NMSettingsConnection *connection,
+ GError *error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection)));
+}
+
+void
+nm_settings_add_connection (NMSettings *self,
+ NMConnection *connection,
+ DBusGMethodInvocation *context,
+ NMSettingsAddCallback callback,
+ gpointer user_data)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMSettingConnection *s_con;
+ NMAuthChain *chain;
+ GError *error = NULL, *tmp_error = NULL;
+ gulong caller_uid = G_MAXULONG;
+ char *error_desc = NULL;
+ const char *perm;
+
+ /* Connection must be valid, of course */
+ if (!nm_connection_verify (connection, &tmp_error)) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "The connection was invalid: %s",
+ tmp_error ? tmp_error->message : "(unknown)");
+ g_error_free (tmp_error);
+ callback (self, NULL, error, context, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Do any of the plugins support adding? */
+ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
+ "None of the registered plugins support add.");
+ callback (self, NULL, error, context, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Get the caller's UID */
+ if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Unable to determine UID of request: %s.",
+ error_desc ? error_desc : "(unknown)");
+ g_free (error_desc);
+ callback (self, NULL, error, context, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Ensure the caller's username exists in the connection's permissions,
+ * or that the permissions is empty (ie, visible by everyone).
+ */
+ if (0 != caller_uid) {
+ if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ error_desc);
+ g_free (error_desc);
+ callback (self, NULL, error, context, user_data);
+ g_error_free (error);
+ return;
+ }
+
+ /* Caller is allowed to add this connection */
+ }
+
+ /* If the caller is the only user in the connection's permissions, then
+ * we use the 'modify.own' permission instead of 'modify.system'. If the
+ * request affects more than just the caller, require 'modify.system'.
+ */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ if (nm_setting_connection_get_num_permissions (s_con) == 1)
+ perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN;
+ else
+ perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM;
+
+ /* Otherwise validate the user request */
+ chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self);
+ g_assert (chain);
+ priv->auths = g_slist_append (priv->auths, chain);
+ nm_auth_chain_add_call (chain, perm, TRUE);
+ nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL);
+ nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref);
+ nm_auth_chain_set_data (chain, "callback", callback, NULL);
+ nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
+}
+
+static void
+impl_settings_add_connection (NMSettings *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context)
+{
+ NMConnection *connection;
+ GError *error = NULL;
+
+ connection = nm_connection_new_from_hash (settings, &error);
+ if (connection) {
+ nm_settings_add_connection (self, connection, context, add_cb, NULL);
+ g_object_unref (connection);
+ } else {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+static void
+pk_hostname_cb (NMAuthChain *chain,
+ GError *chain_error,
+ DBusGMethodInvocation *context,
+ gpointer user_data)
+{
+ NMSettings *self = NM_SETTINGS (user_data);
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMAuthCallResult result;
+ gboolean success = FALSE;
+ GError *error = NULL;
+ GSList *iter;
+ const char *hostname;
+
+ priv->auths = g_slist_remove (priv->auths, chain);
+
+ /* If our NMSettingsConnection is already gone, do nothing */
+ if (chain_error) {
+ error = g_error_new (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_GENERAL,
+ "Error checking authorization: %s",
+ chain_error->message ? chain_error->message : "(unknown)");
+ goto done;
+ }
+
+ result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME);
+
+ /* Caller didn't successfully authenticate */
+ if (result != NM_AUTH_CALL_RESULT_YES) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ goto done;
+ }
+
+ /* Set the hostname in all plugins */
+ hostname = nm_auth_chain_get_data (chain, "hostname");
+ for (iter = priv->plugins; iter; iter = iter->next) {
+ NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
+
+ g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
+ if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
+ g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL);
+ success = TRUE;
+ }
+ }
+
+ if (!success) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
+ "Saving the hostname failed.");
+ }
+
+done:
+ if (error)
+ dbus_g_method_return_error (context, error);
+ else
+ dbus_g_method_return (context);
+
+ g_clear_error (&error);
+ nm_auth_chain_unref (chain);
+}
+
+static void
+impl_settings_save_hostname (NMSettings *self,
+ const char *hostname,
+ DBusGMethodInvocation *context)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMAuthChain *chain;
+ GError *error = NULL;
+
+ /* Do any of the plugins support setting the hostname? */
+ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
+ error = g_error_new_literal (NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
+ "None of the registered plugins support setting the hostname.");
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ /* Otherwise validate the user request */
+ chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self);
+ g_assert (chain);
+ priv->auths = g_slist_append (priv->auths, chain);
+ nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE);
+ nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free);
+}
+
+static gboolean
+have_connection_for_device (NMSettings *self, GByteArray *mac)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer data;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ const GByteArray *setting_mac;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE);
+ g_return_val_if_fail (mac != NULL, FALSE);
+
+ /* Find a wired connection locked to the given MAC address, if any */
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &data)) {
+ NMConnection *connection = NM_CONNECTION (data);
+ const char *connection_type;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+
+ if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
+ && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
+ continue;
+
+ s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+
+ /* No wired setting; therefore the PPPoE connection applies to any device */
+ if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
+ ret = TRUE;
+ break;
+ }
+
+ setting_mac = nm_setting_wired_get_mac_address (s_wired);
+ if (setting_mac) {
+ /* A connection mac-locked to this device */
+ if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) {
+ ret = TRUE;
+ break;
+ }
+ } else {
+ /* A connection that applies to any wired device */
+ ret = TRUE;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/* Search through the list of blacklisted MAC addresses in the config file. */
+static gboolean
+is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GKeyFile *config;
+ char **list, **iter;
+ gboolean found = FALSE;
+
+ g_return_val_if_fail (mac != NULL, FALSE);
+
+ if (!priv->config_file)
+ return FALSE;
+
+ config = g_key_file_new ();
+ if (!config) {
+ nm_log_warn (LOGD_SETTINGS, "not enough memory to load config file.");
+ return FALSE;
+ }
+
+ g_key_file_set_list_separator (config, ',');
+ if (!g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_NONE, NULL))
+ goto out;
+
+ list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL);
+ for (iter = list; iter && *iter; iter++) {
+ struct ether_addr *candidate;
+
+ if (strcmp(g_strstrip(*iter), "*") == 0) {
+ found = TRUE;
+ break;
+ }
+
+ candidate = ether_aton (*iter);
+ if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (list)
+ g_strfreev (list);
+
+out:
+ g_key_file_free (config);
+ return found;
+}
+
+#define DEFAULT_WIRED_TAG "default-wired"
+
+static void
+default_wired_deleted (NMDefaultWiredConnection *wired,
+ const GByteArray *mac,
+ NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ NMSettingConnection *s_con;
+ char *tmp;
+ GKeyFile *config;
+ char **list, **iter, **updated;
+ gboolean found = FALSE;
+ gsize len = 0, i;
+ char *data;
+
+ /* If there was no config file specified, there's nothing to do */
+ if (!priv->config_file)
+ goto cleanup;
+
+ /* When the default wired connection is removed (either deleted or saved
+ * to a new persistent connection by a plugin), write the MAC address of
+ * the wired device to the config file and don't create a new default wired
+ * connection for that device again.
+ */
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
+ NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ /* Ignore removals of read-only connections, since they couldn't have
+ * been removed by the user.
+ */
+ if (nm_setting_connection_get_read_only (s_con))
+ goto cleanup;
+
+ config = g_key_file_new ();
+ if (!config)
+ goto cleanup;
+
+ g_key_file_set_list_separator (config, ',');
+ g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL);
+
+ list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL);
+ for (iter = list; iter && *iter; iter++) {
+ struct ether_addr *candidate;
+
+ if (strcmp(g_strstrip(*iter), "*") == 0) {
+ found = TRUE;
+ break;
+ }
+
+ candidate = ether_aton (*iter);
+ if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ /* Add this device's MAC to the list */
+ if (!found) {
+ tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
+ mac->data[0], mac->data[1], mac->data[2],
+ mac->data[3], mac->data[4], mac->data[5]);
+
+ /* New list; size + 1 for the new element, + 1 again for ending NULL */
+ updated = g_malloc0 (sizeof (char*) * (len + 2));
+
+ /* Copy original list and add new MAC */
+ for (i = 0; list && list[i]; i++)
+ updated[i] = list[i];
+ updated[i++] = tmp;
+ updated[i] = NULL;
+
+ g_key_file_set_string_list (config,
+ "main", CONFIG_KEY_NO_AUTO_DEFAULT,
+ (const char **) updated,
+ len + 2);
+ /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */
+ g_free (updated);
+ g_free (tmp);
+
+ data = g_key_file_to_data (config, &len, NULL);
+ if (data) {
+ g_file_set_contents (priv->config_file, data, len, NULL);
+ g_free (data);
+ }
+ }
+
+ if (list)
+ g_strfreev (list);
+ g_key_file_free (config);
+
+cleanup:
+ g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
+ DEFAULT_WIRED_TAG,
+ NULL);
+}
+
+static void
+delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data)
+{
+}
+
+static gboolean
+default_wired_try_update (NMDefaultWiredConnection *wired,
+ NMSettings *self)
+{
+ GError *error = NULL;
+ const char *id;
+ NMSettingsConnection *added;
+
+ /* Try to move this default wired conneciton to a plugin so that it has
+ * persistent storage.
+ */
+
+ id = nm_connection_get_id (NM_CONNECTION (wired));
+ g_assert (id);
+
+ remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE);
+ added = add_new_connection (self, NM_CONNECTION (wired), &error);
+ if (added) {
+ nm_settings_connection_delete (NM_SETTINGS_CONNECTION (wired), delete_cb, NULL);
+
+ g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
+ DEFAULT_WIRED_TAG,
+ NULL);
+ nm_log_info (LOGD_SETTINGS, "Saved default wired connection '%s' to persistent storage", id);
+ return FALSE;
+ }
+
+ nm_log_warn (LOGD_SETTINGS, "couldn't save default wired connection '%s': %d / %s",
+ id,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+
+ /* If there was an error, don't destroy the default wired connection,
+ * but add it back to the system settings service. Connection is already
+ * exported on the bus, don't export it again, thus do_export == FALSE.
+ */
+ claim_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE);
+ return TRUE;
+}
+
+void
+nm_settings_device_added (NMSettings *self, NMDevice *device)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GByteArray *mac = NULL;
+ struct ether_addr tmp;
+ NMDefaultWiredConnection *wired;
+ gboolean read_only = TRUE;
+ const char *id;
+ char *defname;
+
+ if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
+ return;
+
+ /* If the device isn't managed or it already has a default wired connection,
+ * ignore it.
+ */
+ if ( !nm_device_get_managed (device)
+ || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG))
+ return;
+
+ nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp);
+
+ mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN);
+
+ if ( have_connection_for_device (self, mac)
+ || is_mac_auto_wired_blacklisted (self, mac))
+ goto ignore;
+
+ if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
+ read_only = FALSE;
+
+ defname = nm_settings_utils_get_default_wired_name (priv->connections);
+ wired = nm_default_wired_connection_new (mac, device, defname, read_only);
+ g_free (defname);
+ if (!wired)
+ goto ignore;
+
+ id = nm_connection_get_id (NM_CONNECTION (wired));
+ g_assert (id);
+
+ nm_log_info (LOGD_SETTINGS, "Added default wired connection '%s' for %s",
+ id, nm_device_get_udi (device));
+
+ g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self);
+ g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self);
+ claim_connection (self, NM_SETTINGS_CONNECTION (wired), TRUE);
+ g_object_unref (wired);
+
+ g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired);
+
+ignore:
+ g_byte_array_free (mac, TRUE);
+}
+
+void
+nm_settings_device_removed (NMSettings *self, NMDevice *device)
+{
+ NMDefaultWiredConnection *connection;
+
+ if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
+ return;
+
+ connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
+ if (connection)
+ remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (connection), TRUE);
+}
+
+/***************************************************************/
+
+NMSettings *
+nm_settings_new (const char *config_file,
+ const char *plugins,
+ GError **error)
+{
+ NMSettings *self;
+ NMSettingsPrivate *priv;
+ GObject *keyfile_plugin;
+
+ self = g_object_new (NM_TYPE_SETTINGS, NULL);
+ if (!self)
+ return NULL;
+
+ priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ priv->config_file = g_strdup (config_file);
+ priv->dbus_mgr = nm_dbus_manager_get ();
+ priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+
+ if (plugins) {
+ /* Load the plugins; fail if a plugin is not found. */
+ if (!load_plugins (self, plugins, error)) {
+ g_object_unref (self);
+ return NULL;
+ }
+ }
+
+ /* Add the keyfile plugin last */
+ keyfile_plugin = nm_settings_keyfile_plugin_new ();
+ g_assert (keyfile_plugin);
+ add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin));
+
+ unmanaged_specs_changed (NULL, self);
+
+ dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self));
+ return self;
+}
+
+static void
+nm_settings_init (NMSettings *self)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+ priv->authority = polkit_authority_get_sync (NULL, &error);
+ if (!priv->authority) {
+ nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+
+ priv->session_monitor = nm_session_monitor_get ();
+
+ /* Hold a reference to the agent manager so it stays alive; the only
+ * other holders are NMSettingsConnection objects which are often
+ * transient, and we don't want the agent manager to get destroyed and
+ * recreated often.
+ */
+ priv->agent_mgr = nm_agent_manager_get ();
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSettings *self = NM_SETTINGS (object);
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ if (priv->auth_changed_id) {
+ g_signal_handler_disconnect (priv->authority, priv->auth_changed_id);
+ priv->auth_changed_id = 0;
+ }
+
+ for (iter = priv->auths; iter; iter = g_slist_next (iter))
+ nm_auth_chain_unref ((NMAuthChain *) iter->data);
+ g_slist_free (priv->auths);
+
+ g_object_unref (priv->dbus_mgr);
+
+ g_object_unref (priv->session_monitor);
+ g_object_unref (priv->agent_mgr);
+
+ G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMSettings *self = NM_SETTINGS (object);
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+
+ g_hash_table_destroy (priv->connections);
+
+ clear_unmanaged_specs (self);
+
+ g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->plugins);
+
+ g_free (priv->config_file);
+
+ G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSettings *self = NM_SETTINGS (object);
+ const GSList *specs, *iter;
+ GSList *copy = NULL;
+
+ switch (prop_id) {
+ case PROP_UNMANAGED_SPECS:
+ specs = nm_settings_get_unmanaged_specs (self);
+ for (iter = specs; iter; iter = g_slist_next (iter))
+ copy = g_slist_append (copy, g_strdup (iter->data));
+ g_value_take_boxed (value, copy);
+ break;
+ case PROP_HOSTNAME:
+ g_value_take_string (value, nm_settings_get_hostname (self));
+
+ /* Don't ever pass NULL through D-Bus */
+ if (!g_value_get_string (value))
+ g_value_set_static_string (value, "");
+ break;
+ case PROP_CAN_MODIFY:
+ g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_settings_class_init (NMSettingsClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMSettingsPrivate));
+
+ /* virtual methods */
+ object_class->notify = notify;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ /* properties */
+
+ g_object_class_install_property
+ (object_class, PROP_UNMANAGED_SPECS,
+ g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS,
+ "Unamanged device specs",
+ "Unmanaged device specs",
+ DBUS_TYPE_G_LIST_OF_STRING,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_HOSTNAME,
+ g_param_spec_string (NM_SETTINGS_HOSTNAME,
+ "Hostname",
+ "Persistent hostname",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_CAN_MODIFY,
+ g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY,
+ "CanModify",
+ "Can modify anything (hostname, connections, etc)",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* signals */
+ signals[PROPERTIES_CHANGED] =
+ g_signal_new ("properties-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, properties_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
+ signals[CONNECTION_ADDED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, connection_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONNECTION_UPDATED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, connection_updated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONNECTION_REMOVED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, connection_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONNECTION_VISIBILITY_CHANGED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONNECTIONS_LOADED] =
+ g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsClass, connections_loaded),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_CONNECTION] =
+ g_signal_new ("new-connection",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ dbus_g_error_domain_register (NM_SETTINGS_ERROR,
+ NM_DBUS_IFACE_SETTINGS,
+ NM_TYPE_SETTINGS_ERROR);
+
+ /* And register all the settings errors with D-Bus */
+ dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_BLUETOOTH_ERROR, NULL, NM_TYPE_SETTING_BLUETOOTH_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_CDMA_ERROR, NULL, NM_TYPE_SETTING_CDMA_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_CONNECTION_ERROR, NULL, NM_TYPE_SETTING_CONNECTION_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_GSM_ERROR, NULL, NM_TYPE_SETTING_GSM_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_IP4_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP4_CONFIG_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_IP6_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP6_CONFIG_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_OLPC_MESH_ERROR, NULL, NM_TYPE_SETTING_OLPC_MESH_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR);
+ dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR);
+
+ dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info);
+
+}
+
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
new file mode 100644
index 000000000..a5cb4d7c8
--- /dev/null
+++ b/src/settings/nm-settings.h
@@ -0,0 +1,115 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ * Dan Williams <dcbw@redhat.com>
+ * Tambet Ingo <tambet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
+ */
+
+#ifndef __NM_SETTINGS_H__
+#define __NM_SETTINGS_H__
+
+#include <nm-connection.h>
+
+#include "nm-settings-connection.h"
+#include "nm-system-config-interface.h"
+#include "nm-device.h"
+
+#define NM_TYPE_SETTINGS (nm_settings_get_type ())
+#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings))
+#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass))
+#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS))
+#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS))
+#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass))
+
+#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
+#define NM_SETTINGS_HOSTNAME "hostname"
+#define NM_SETTINGS_CAN_MODIFY "can-modify"
+
+#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added"
+#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated"
+#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed"
+#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed"
+#define NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED "connections-loaded"
+
+typedef struct {
+ GObject parent_instance;
+} NMSettings;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*properties_changed) (NMSettings *self, GHashTable *properties);
+
+ void (*connection_added) (NMSettings *self, NMSettingsConnection *connection);
+
+ void (*connection_updated) (NMSettings *self, NMSettingsConnection *connection);
+
+ void (*connection_removed) (NMSettings *self, NMSettingsConnection *connection);
+
+ void (*connection_visibility_changed) (NMSettings *self, NMSettingsConnection *connection);
+
+ void (*connections_loaded) (NMSettings *self);
+} NMSettingsClass;
+
+GType nm_settings_get_type (void);
+
+NMSettings *nm_settings_new (const char *config_file,
+ const char *plugins,
+ GError **error);
+
+typedef void (*NMSettingsForEachFunc) (NMSettings *settings,
+ NMSettingsConnection *connection,
+ gpointer user_data);
+
+void nm_settings_for_each_connection (NMSettings *settings,
+ NMSettingsForEachFunc for_each_func,
+ gpointer user_data);
+
+typedef void (*NMSettingsAddCallback) (NMSettings *settings,
+ NMSettingsConnection *connection,
+ GError *error,
+ DBusGMethodInvocation *context,
+ gpointer user_data);
+
+void nm_settings_add_connection (NMSettings *self,
+ NMConnection *connection,
+ DBusGMethodInvocation *context,
+ NMSettingsAddCallback callback,
+ gpointer user_data);
+
+/* Returns a list of NMSettingsConnections. Caller must free the list with
+ * g_slist_free().
+ */
+GSList *nm_settings_get_connections (NMSettings *settings);
+
+NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings,
+ const char *path);
+
+const GSList *nm_settings_get_unmanaged_specs (NMSettings *self);
+
+char *nm_settings_get_hostname (NMSettings *self);
+
+void nm_settings_device_added (NMSettings *self, NMDevice *device);
+
+void nm_settings_device_removed (NMSettings *self, NMDevice *device);
+
+#endif /* __NM_SETTINGS_H__ */
diff --git a/src/system-settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c
index 9fb34278d..45aa6305d 100644
--- a/src/system-settings/nm-system-config-interface.c
+++ b/src/settings/nm-system-config-interface.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
@@ -74,7 +74,7 @@ interface_init (gpointer g_iface)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
- NM_TYPE_SETTINGS_CONNECTION_INTERFACE);
+ NM_TYPE_SETTINGS_CONNECTION);
g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
iface_type,
@@ -147,18 +147,16 @@ nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config)
return NULL;
}
-gboolean
+NMSettingsConnection *
nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
NMConnection *connection,
GError **error)
{
- gboolean success = FALSE;
-
- g_return_val_if_fail (config != NULL, FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+ g_return_val_if_fail (config != NULL, NULL);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection)
- success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error);
+ return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error);
- return success;
+ return NULL;
}
diff --git a/src/system-settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h
index d5634aa6b..96a640619 100644
--- a/src/system-settings/nm-system-config-interface.h
+++ b/src/settings/nm-system-config-interface.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2007 - 2010 Red Hat, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
* Copyright (C) 2008 Novell, Inc.
*/
@@ -25,7 +25,7 @@
#include <glib.h>
#include <glib-object.h>
#include <nm-connection.h>
-#include <nm-settings-connection-interface.h>
+#include <nm-settings-connection.h>
G_BEGIN_DECLS
@@ -83,9 +83,9 @@ struct _NMSystemConfigInterface {
/* Called when the plugin is loaded to initialize it */
void (*init) (NMSystemConfigInterface *config);
- /* Returns a GSList of objects that implement NMSettingsConnectionInterface
- * that represent connections the plugin knows about. The returned list
- * is freed by the system settings service.
+ /* Returns a GSList of NMSettingsConnection objects that represent
+ * connections the plugin knows about. The returned list is freed by the
+ * system settings service.
*/
GSList * (*get_connections) (NMSystemConfigInterface *config);
@@ -110,17 +110,19 @@ struct _NMSystemConfigInterface {
GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config);
/*
- * Add a new connection.
+ * Save the given connection to backing storage, and return a new
+ * NMSettingsConnection subclass that contains the same settings as the
+ * original connection.
*/
- gboolean (*add_connection) (NMSystemConfigInterface *config,
- NMConnection *connection,
- GError **error);
+ NMSettingsConnection * (*add_connection) (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ GError **error);
/* Signals */
/* Emitted when a new connection has been found by the plugin */
void (*connection_added) (NMSystemConfigInterface *config,
- NMSettingsConnectionInterface *connection);
+ NMSettingsConnection *connection);
/* Emitted when the list of unmanaged device specifications changes */
void (*unmanaged_specs_changed) (NMSystemConfigInterface *config);
@@ -135,9 +137,9 @@ GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *con
GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config);
-gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
- NMConnection *connection,
- GError **error);
+NMSettingsConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ GError **error);
G_END_DECLS
diff --git a/src/settings/plugins/Makefile.am b/src/settings/plugins/Makefile.am
new file mode 100644
index 000000000..5df57d5ea
--- /dev/null
+++ b/src/settings/plugins/Makefile.am
@@ -0,0 +1,21 @@
+SUBDIRS=keyfile
+
+if TARGET_REDHAT
+SUBDIRS+=ifcfg-rh
+endif
+
+if TARGET_SUSE
+SUBDIRS+=ifcfg-suse
+endif
+
+if TARGET_MANDRIVA
+SUBDIRS+=ifcfg-rh
+endif
+
+if TARGET_DEBIAN
+SUBDIRS+=ifupdown
+endif
+
+if TARGET_GENTOO
+SUBDIRS+=ifnet
+endif
diff --git a/src/settings/plugins/Makefile.in b/src/settings/plugins/Makefile.in
new file mode 100644
index 000000000..d0ade2a17
--- /dev/null
+++ b/src/settings/plugins/Makefile.in
@@ -0,0 +1,660 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@TARGET_REDHAT_TRUE@am__append_1 = ifcfg-rh
+@TARGET_SUSE_TRUE@am__append_2 = ifcfg-suse
+@TARGET_MANDRIVA_TRUE@am__append_3 = ifcfg-rh
+@TARGET_DEBIAN_TRUE@am__append_4 = ifupdown
+@TARGET_GENTOO_TRUE@am__append_5 = ifnet
+subdir = src/settings/plugins
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = keyfile ifcfg-rh ifcfg-suse ifupdown ifnet
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = keyfile $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4) $(am__append_5)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ ctags ctags-recursive distclean distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.am b/src/settings/plugins/ifcfg-rh/Makefile.am
new file mode 100644
index 000000000..9874d352b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/Makefile.am
@@ -0,0 +1,76 @@
+SUBDIRS=. tests
+
+nm-ifcfg-rh-glue.h: nm-ifcfg-rh.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_ifcfg_rh --mode=glib-server --output=$@ $<
+
+BUILT_SOURCES = \
+ nm-ifcfg-rh-glue.h
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-rh.la
+
+noinst_LTLIBRARIES = libifcfg-rh-io.la
+
+libifcfg_rh_io_la_SOURCES = \
+ shvar.c \
+ shvar.h \
+ reader.c \
+ reader.h \
+ writer.c \
+ writer.h \
+ errors.c \
+ common.h \
+ utils.c \
+ utils.h
+
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_builddir)/marshallers
+
+libifcfg_rh_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(NSS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSBINDIR=\"$(sbindir)\"
+
+libifcfg_rh_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS) \
+ $(NSS_LIBS)
+
+libnm_settings_plugin_ifcfg_rh_la_SOURCES = \
+ plugin.c \
+ plugin.h \
+ nm-ifcfg-connection.c \
+ nm-ifcfg-connection.h
+
+libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifcfg_rh_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ libifcfg-rh-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GIO_LIBS)
+
+dbusservicedir = $(DBUS_SYS_DIR)
+dbusservice_DATA = nm-ifcfg-rh.conf
+
+EXTRA_DIST = \
+ $(dbusservice_DATA) \
+ nm-ifcfg-rh.xml
+
+CLEANFILES = $(BUILT_SOURCES)
+
diff --git a/src/settings/plugins/ifcfg-rh/Makefile.in b/src/settings/plugins/ifcfg-rh/Makefile.in
new file mode 100644
index 000000000..dac8fc9ee
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/Makefile.in
@@ -0,0 +1,978 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/ifcfg-rh
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkglibdir)" \
+ "$(DESTDIR)$(dbusservicedir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libifcfg_rh_io_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libifcfg_rh_io_la_OBJECTS = libifcfg_rh_io_la-shvar.lo \
+ libifcfg_rh_io_la-reader.lo libifcfg_rh_io_la-writer.lo \
+ libifcfg_rh_io_la-errors.lo libifcfg_rh_io_la-utils.lo
+libifcfg_rh_io_la_OBJECTS = $(am_libifcfg_rh_io_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ libifcfg-rh-io.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \
+ libnm_settings_plugin_ifcfg_rh_la-plugin.lo \
+ libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo
+libnm_settings_plugin_ifcfg_rh_la_OBJECTS = \
+ $(am_libnm_settings_plugin_ifcfg_rh_la_OBJECTS)
+libnm_settings_plugin_ifcfg_rh_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libnm_settings_plugin_ifcfg_rh_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libifcfg_rh_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifcfg_rh_la_SOURCES)
+DIST_SOURCES = $(libifcfg_rh_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifcfg_rh_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+DATA = $(dbusservice_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = . tests
+BUILT_SOURCES = \
+ nm-ifcfg-rh-glue.h
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-rh.la
+noinst_LTLIBRARIES = libifcfg-rh-io.la
+libifcfg_rh_io_la_SOURCES = \
+ shvar.c \
+ shvar.h \
+ reader.c \
+ reader.h \
+ writer.c \
+ writer.h \
+ errors.c \
+ common.h \
+ utils.c \
+ utils.h
+
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_builddir)/marshallers
+
+libifcfg_rh_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(NSS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSBINDIR=\"$(sbindir)\"
+
+libifcfg_rh_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS) \
+ $(NSS_LIBS)
+
+libnm_settings_plugin_ifcfg_rh_la_SOURCES = \
+ plugin.c \
+ plugin.h \
+ nm-ifcfg-connection.c \
+ nm-ifcfg-connection.h
+
+libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifcfg_rh_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifcfg_rh_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/marshallers/libmarshallers.la \
+ libifcfg-rh-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GIO_LIBS)
+
+dbusservicedir = $(DBUS_SYS_DIR)
+dbusservice_DATA = nm-ifcfg-rh.conf
+EXTRA_DIST = \
+ $(dbusservice_DATA) \
+ nm-ifcfg-rh.xml
+
+CLEANFILES = $(BUILT_SOURCES)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+ }
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libifcfg-rh-io.la: $(libifcfg_rh_io_la_OBJECTS) $(libifcfg_rh_io_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libifcfg_rh_io_la_OBJECTS) $(libifcfg_rh_io_la_LIBADD) $(LIBS)
+libnm-settings-plugin-ifcfg-rh.la: $(libnm_settings_plugin_ifcfg_rh_la_OBJECTS) $(libnm_settings_plugin_ifcfg_rh_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnm_settings_plugin_ifcfg_rh_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifcfg_rh_la_OBJECTS) $(libnm_settings_plugin_ifcfg_rh_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-errors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-reader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-shvar.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifcfg_rh_io_la-writer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libifcfg_rh_io_la-shvar.lo: shvar.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-shvar.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-shvar.Tpo -c -o libifcfg_rh_io_la-shvar.lo `test -f 'shvar.c' || echo '$(srcdir)/'`shvar.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-shvar.Tpo $(DEPDIR)/libifcfg_rh_io_la-shvar.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='shvar.c' object='libifcfg_rh_io_la-shvar.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-shvar.lo `test -f 'shvar.c' || echo '$(srcdir)/'`shvar.c
+
+libifcfg_rh_io_la-reader.lo: reader.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-reader.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-reader.Tpo -c -o libifcfg_rh_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-reader.Tpo $(DEPDIR)/libifcfg_rh_io_la-reader.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reader.c' object='libifcfg_rh_io_la-reader.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
+
+libifcfg_rh_io_la-writer.lo: writer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-writer.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-writer.Tpo -c -o libifcfg_rh_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-writer.Tpo $(DEPDIR)/libifcfg_rh_io_la-writer.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writer.c' object='libifcfg_rh_io_la-writer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
+
+libifcfg_rh_io_la-errors.lo: errors.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-errors.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-errors.Tpo -c -o libifcfg_rh_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-errors.Tpo $(DEPDIR)/libifcfg_rh_io_la-errors.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libifcfg_rh_io_la-errors.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
+
+libifcfg_rh_io_la-utils.lo: utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifcfg_rh_io_la-utils.lo -MD -MP -MF $(DEPDIR)/libifcfg_rh_io_la-utils.Tpo -c -o libifcfg_rh_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifcfg_rh_io_la-utils.Tpo $(DEPDIR)/libifcfg_rh_io_la-utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libifcfg_rh_io_la-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifcfg_rh_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifcfg_rh_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+
+libnm_settings_plugin_ifcfg_rh_la-plugin.lo: plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_rh_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Tpo -c -o libnm_settings_plugin_ifcfg_rh_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-plugin.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifcfg_rh_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_rh_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+
+libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo: nm-ifcfg-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Tpo -c -o libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo `test -f 'nm-ifcfg-connection.c' || echo '$(srcdir)/'`nm-ifcfg-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifcfg-connection.c' object='libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_rh_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_rh_la-nm-ifcfg-connection.lo `test -f 'nm-ifcfg-connection.c' || echo '$(srcdir)/'`nm-ifcfg-connection.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-dbusserviceDATA: $(dbusservice_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(dbusservicedir)" || $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)"
+ @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \
+ done
+
+uninstall-dbusserviceDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(dbusservicedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(dbusservicedir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(dbusservicedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pkglibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-dbusserviceDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-dbusserviceDATA uninstall-pkglibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+ ctags-recursive install install-am install-strip \
+ tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dbusserviceDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pkglibLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-dbusserviceDATA uninstall-pkglibLTLIBRARIES
+
+
+nm-ifcfg-rh-glue.h: nm-ifcfg-rh.xml
+ $(AM_V_GEN) dbus-binding-tool --prefix=nm_ifcfg_rh --mode=glib-server --output=$@ $<
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifcfg-rh/common.h b/src/settings/plugins/ifcfg-rh/common.h
new file mode 100644
index 000000000..74a77c4c4
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/common.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <glib.h>
+
+#define IFCFG_TAG "ifcfg-"
+#define KEYS_TAG "keys-"
+#define ROUTE_TAG "route-"
+#define ROUTE6_TAG "route6-"
+
+#define BAK_TAG ".bak"
+#define TILDE_TAG "~"
+#define ORIG_TAG ".orig"
+#define REJ_TAG ".rej"
+#define RPMNEW_TAG ".rpmnew"
+#define AUGNEW_TAG ".augnew"
+#define AUGTMP_TAG ".augtmp"
+
+#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts"
+
+#define IFCFG_PLUGIN_NAME "ifcfg-rh"
+#define IFCFG_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
+
+#define TYPE_ETHERNET "Ethernet"
+#define TYPE_WIRELESS "Wireless"
+#define TYPE_BRIDGE "Bridge"
+
+#define SECRET_FLAG_AGENT "user"
+#define SECRET_FLAG_NOT_SAVED "ask"
+#define SECRET_FLAG_NOT_REQUIRED "unused"
+
+#define IFCFG_PLUGIN_ERROR (ifcfg_plugin_error_quark ())
+GQuark ifcfg_plugin_error_quark (void);
+
+
+#endif /* __COMMON_H__ */
+
diff --git a/src/settings/plugins/ifcfg-rh/errors.c b/src/settings/plugins/ifcfg-rh/errors.c
new file mode 100644
index 000000000..25039104a
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/errors.c
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include "common.h"
+
+GQuark
+ifcfg_plugin_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (G_UNLIKELY (error_quark == 0))
+ error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark");
+
+ return error_quark;
+}
+
+
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
new file mode 100644
index 000000000..433f933bb
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
@@ -0,0 +1,346 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2010 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+
+#include <glib/gstdio.h>
+
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-8021x.h>
+
+#include "common.h"
+#include "nm-ifcfg-connection.h"
+#include "reader.h"
+#include "writer.h"
+#include "nm-inotify-helper.h"
+
+G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTION)
+
+#define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate))
+
+typedef struct {
+ gulong ih_event_id;
+
+ char *path;
+ int file_wd;
+
+ char *keyfile;
+ int keyfile_wd;
+
+ char *routefile;
+ int routefile_wd;
+
+ char *route6file;
+ int route6file_wd;
+
+ char *unmanaged;
+} NMIfcfgConnectionPrivate;
+
+enum {
+ PROP_0,
+ PROP_UNMANAGED,
+ LAST_PROP
+};
+
+/* Signals */
+enum {
+ IFCFG_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+files_changed_cb (NMInotifyHelper *ih,
+ struct inotify_event *evt,
+ const char *path,
+ gpointer user_data)
+{
+ NMIfcfgConnection *self = NM_IFCFG_CONNECTION (user_data);
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
+
+ if ( (evt->wd != priv->file_wd)
+ && (evt->wd != priv->keyfile_wd)
+ && (evt->wd != priv->routefile_wd)
+ && (evt->wd != priv->route6file_wd))
+ return;
+
+ /* push the event up to the plugin */
+ g_signal_emit (self, signals[IFCFG_CHANGED], 0);
+}
+
+NMIfcfgConnection *
+nm_ifcfg_connection_new (const char *full_path,
+ NMConnection *source,
+ GError **error,
+ gboolean *ignore_error)
+{
+ GObject *object;
+ NMIfcfgConnectionPrivate *priv;
+ NMConnection *tmp;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ NMInotifyHelper *ih;
+
+ g_return_val_if_fail (full_path != NULL, NULL);
+
+ /* If we're given a connection already, prefer that instead of re-reading */
+ if (source)
+ tmp = g_object_ref (source);
+ else {
+ tmp = connection_from_file (full_path, NULL, NULL, NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ error,
+ ignore_error);
+ if (!tmp)
+ return NULL;
+ }
+
+ object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
+ NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
+ NULL);
+ if (!object)
+ goto out;
+
+ /* Update our settings with what was read from the file */
+ if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) {
+ g_object_unref (object);
+ object = NULL;
+ goto out;
+ }
+
+ priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
+ priv->path = g_strdup (full_path);
+
+ ih = nm_inotify_helper_get ();
+ priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object);
+
+ priv->file_wd = nm_inotify_helper_add_watch (ih, full_path);
+
+ priv->keyfile = keyfile;
+ priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile);
+
+ priv->routefile = routefile;
+ priv->routefile_wd = nm_inotify_helper_add_watch (ih, routefile);
+
+ priv->route6file = route6file;
+ priv->route6file_wd = nm_inotify_helper_add_watch (ih, route6file);
+
+out:
+ g_object_unref (tmp);
+ return (NMIfcfgConnection *) object;
+}
+
+const char *
+nm_ifcfg_connection_get_path (NMIfcfgConnection *self)
+{
+ g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
+
+ return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path;
+}
+
+const char *
+nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
+{
+ g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
+
+ return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged;
+}
+
+static void
+commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
+ GError *error = NULL;
+ NMConnection *reread;
+ char *unmanaged = NULL, *keyfile = NULL, *routefile = NULL, *route6file = NULL;
+
+ /* To ensure we don't rewrite files that are only changed from other
+ * processes on-disk, read the existing connection back in and only rewrite
+ * it if it's really changed.
+ */
+ reread = connection_from_file (priv->path, NULL, NULL, NULL,
+ &unmanaged, &keyfile, &routefile, &route6file,
+ NULL, NULL);
+ g_free (unmanaged);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+
+ if (reread && nm_connection_compare (NM_CONNECTION (connection),
+ reread,
+ NM_SETTING_COMPARE_FLAG_EXACT))
+ goto out;
+
+ if (!writer_update_connection (NM_CONNECTION (connection),
+ IFCFG_DIR,
+ priv->path,
+ priv->keyfile,
+ &error)) {
+ callback (connection, error, user_data);
+ g_error_free (error);
+ return;
+ }
+
+out:
+ if (reread)
+ g_object_unref (reread);
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data);
+}
+
+static void
+do_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
+
+ g_unlink (priv->path);
+ if (priv->keyfile)
+ g_unlink (priv->keyfile);
+ if (priv->routefile)
+ g_unlink (priv->routefile);
+
+ if (priv->route6file)
+ g_unlink (priv->route6file);
+
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data);
+}
+
+/* GObject */
+
+static void
+nm_ifcfg_connection_init (NMIfcfgConnection *connection)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
+ NMInotifyHelper *ih;
+
+ nm_connection_clear_secrets (NM_CONNECTION (object));
+
+ ih = nm_inotify_helper_get ();
+
+ if (priv->ih_event_id)
+ g_signal_handler_disconnect (ih, priv->ih_event_id);
+
+ g_free (priv->path);
+ if (priv->file_wd >= 0)
+ nm_inotify_helper_remove_watch (ih, priv->file_wd);
+
+ g_free (priv->keyfile);
+ if (priv->keyfile_wd >= 0)
+ nm_inotify_helper_remove_watch (ih, priv->keyfile_wd);
+
+ g_free (priv->routefile);
+ if (priv->routefile_wd >= 0)
+ nm_inotify_helper_remove_watch (ih, priv->routefile_wd);
+
+ g_free (priv->route6file);
+ if (priv->route6file_wd >= 0)
+ nm_inotify_helper_remove_watch (ih, priv->route6file_wd);
+
+ G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_UNMANAGED:
+ priv->unmanaged = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_UNMANAGED:
+ g_value_set_string (value, priv->unmanaged);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class);
+ NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifcfg_connection_class);
+
+ g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+ settings_class->delete = do_delete;
+ settings_class->commit_changes = commit_changes;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_UNMANAGED,
+ g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED,
+ "Unmanaged",
+ "Unmanaged",
+ NULL,
+ G_PARAM_READWRITE));
+
+ signals[IFCFG_CHANGED] =
+ g_signal_new ("ifcfg-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h
new file mode 100644
index 000000000..731aa598c
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_IFCFG_CONNECTION_H
+#define NM_IFCFG_CONNECTION_H
+
+G_BEGIN_DECLS
+
+#include <NetworkManager.h>
+#include <nm-settings-connection.h>
+
+#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ())
+#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection))
+#define NM_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
+#define NM_IS_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
+#define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
+#define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
+
+#define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged"
+
+typedef struct {
+ NMSettingsConnection parent;
+} NMIfcfgConnection;
+
+typedef struct {
+ NMSettingsConnectionClass parent;
+} NMIfcfgConnectionClass;
+
+GType nm_ifcfg_connection_get_type (void);
+
+NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename,
+ NMConnection *source,
+ GError **error,
+ gboolean *ignore_error);
+
+const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self);
+
+const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self);
+
+gboolean nm_ifcfg_connection_update (NMIfcfgConnection *self,
+ GHashTable *new_settings,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* NM_IFCFG_CONNECTION_H */
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf
new file mode 100644
index 000000000..cade31dd2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.conf
@@ -0,0 +1,18 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <policy user="root">
+ <allow own="com.redhat.ifcfgrh1"/>
+ <allow send_destination="com.redhat.ifcfgrh1"/>
+ </policy>
+ <policy at_console="true">
+ <deny own="com.redhat.ifcfgrh1"/>
+ <allow send_destination="com.redhat.ifcfgrh1"/>
+ </policy>
+ <policy context="default">
+ <deny own="com.redhat.ifcfgrh1"/>
+ <allow send_destination="com.redhat.ifcfgrh1"/>
+ </policy>
+</busconfig>
+
diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml
new file mode 100644
index 000000000..527934529
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-rh.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <interface name="com.redhat.ifcfgrh1">
+ <tp:docstring>
+ Utility methods for handling NM integration with standard Red Hat ifcfg files.
+ </tp:docstring>
+
+ <method name="GetIfcfgDetails">
+ <tp:docstring>
+ Given an ifcfg file, return various internal information about it.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_ifcfgrh_get_ifcfg_details"/>
+ <arg name="ifcfg" type="s" direction="in">
+ <tp:docstring>
+ The full path to an ifcfg file.
+ </tp:docstring>
+ </arg>
+ <arg name="uuid" type="s" direction="out">
+ <tp:docstring>
+ The UUID of the NM connection backed by this ifcfg file. If the ifcfg file does not contain a UUID tag, this UUID is generated by NM, otherwise the UUID from the ifcfg file is used.
+ </tp:docstring>
+ </arg>
+ <arg name="path" type="o" direction="out">
+ <tp:docstring>
+ The object path of the NM connected backed by this ifcfg file.
+ </tp:docstring>
+ </arg>
+ </method>
+ </interface>
+</node>
diff --git a/src/settings/plugins/ifcfg-rh/plugin.c b/src/settings/plugins/ifcfg-rh/plugin.c
new file mode 100644
index 000000000..ae40b90a9
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/plugin.c
@@ -0,0 +1,800 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * Dan Williams <dcbw@redhat.com>
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+
+#include <gmodule.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <nm-setting-connection.h>
+
+#include "common.h"
+#include "nm-dbus-glib-types.h"
+#include "plugin.h"
+#include "nm-system-config-interface.h"
+#include "nm-settings-error.h"
+
+#include "nm-ifcfg-connection.h"
+#include "nm-inotify-helper.h"
+#include "shvar.h"
+#include "writer.h"
+#include "utils.h"
+
+#define DBUS_SERVICE_NAME "com.redhat.ifcfgrh1"
+#define DBUS_OBJECT_PATH "/com/redhat/ifcfgrh1"
+
+static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
+ const char *in_ifcfg,
+ const char **out_uuid,
+ const char **out_path,
+ GError **error);
+
+#include "nm-ifcfg-rh-glue.h"
+
+static void connection_new_or_changed (SCPluginIfcfg *plugin,
+ const char *path,
+ NMIfcfgConnection *existing);
+
+static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+ system_config_interface_init))
+
+#define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate))
+
+
+typedef struct {
+ GHashTable *connections;
+
+ gulong ih_event_id;
+ int sc_network_wd;
+ char *hostname;
+
+ GFileMonitor *monitor;
+ guint monitor_id;
+
+ DBusGConnection *bus;
+} SCPluginIfcfgPrivate;
+
+
+static void
+connection_unmanaged_changed (NMIfcfgConnection *connection,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ g_signal_emit_by_name (SC_PLUGIN_IFCFG (user_data), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
+ const char *path;
+
+ path = nm_ifcfg_connection_get_path (connection);
+ g_return_if_fail (path != NULL);
+
+ connection_new_or_changed (plugin, path, connection);
+}
+
+static NMIfcfgConnection *
+_internal_new_connection (SCPluginIfcfg *self,
+ const char *path,
+ NMConnection *source,
+ GError **error)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ NMIfcfgConnection *connection;
+ const char *cid;
+ GError *local = NULL;
+ gboolean ignore_error = FALSE;
+
+ if (!source) {
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", path);
+ }
+
+ connection = nm_ifcfg_connection_new (path, source, &local, &ignore_error);
+ if (!connection) {
+ if (!ignore_error) {
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " error: %s",
+ (local && local->message) ? local->message : "(unknown)");
+ }
+ g_propagate_error (error, local);
+ return NULL;
+ }
+
+ cid = nm_connection_get_id (NM_CONNECTION (connection));
+ g_assert (cid);
+
+ g_hash_table_insert (priv->connections,
+ (gpointer) nm_ifcfg_connection_get_path (connection),
+ connection);
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid);
+
+ if (nm_ifcfg_connection_get_unmanaged_spec (connection)) {
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
+ "device due to NM_CONTROLLED/BRIDGE/VLAN.", cid);
+ } else {
+ /* Wait for the connection to become unmanaged once it knows the
+ * hardware IDs of its device, if/when the device gets plugged in.
+ */
+ g_signal_connect (G_OBJECT (connection), "notify::" NM_IFCFG_CONNECTION_UNMANAGED,
+ G_CALLBACK (connection_unmanaged_changed), self);
+ }
+
+ /* watch changes of ifcfg hardlinks */
+ g_signal_connect (G_OBJECT (connection), "ifcfg-changed",
+ G_CALLBACK (connection_ifcfg_changed), self);
+
+ return connection;
+}
+
+static void
+read_connections (SCPluginIfcfg *plugin)
+{
+ GDir *dir;
+ GError *err = NULL;
+
+ dir = g_dir_open (IFCFG_DIR, 0, &err);
+ if (dir) {
+ const char *item;
+
+ while ((item = g_dir_read_name (dir))) {
+ char *full_path;
+
+ if (utils_should_ignore_file (item, TRUE))
+ continue;
+
+ full_path = g_build_filename (IFCFG_DIR, item, NULL);
+ if (utils_get_ifcfg_name (full_path, TRUE))
+ _internal_new_connection (plugin, full_path, NULL, NULL);
+ g_free (full_path);
+ }
+
+ g_dir_close (dir);
+ } else {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Can not read directory '%s': %s", IFCFG_DIR, err->message);
+ g_error_free (err);
+ }
+}
+
+/* Monitoring */
+
+/* Callback for nm_settings_connection_replace_and_commit. Report any errors
+ * encountered when commiting connection settings updates. */
+static void
+commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused)
+{
+ if (error) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ }
+}
+
+static void
+remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
+ gboolean managed = FALSE;
+ const char *path;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (connection != NULL);
+
+ managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection);
+ path = nm_ifcfg_connection_get_path (connection);
+
+ g_object_ref (connection);
+ g_hash_table_remove (priv->connections, path);
+ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
+ g_object_unref (connection);
+
+ /* Emit unmanaged changes _after_ removing the connection */
+ if (managed == FALSE)
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+connection_new_or_changed (SCPluginIfcfg *self,
+ const char *path,
+ NMIfcfgConnection *existing)
+{
+ NMIfcfgConnection *new;
+ GError *error = NULL;
+ gboolean ignore_error = FALSE;
+ const char *new_unmanaged = NULL, *old_unmanaged = NULL;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (path != NULL);
+
+ if (!existing) {
+ /* Completely new connection */
+ new = _internal_new_connection (self, path, NULL, NULL);
+ if (new) {
+ if (nm_ifcfg_connection_get_unmanaged_spec (new)) {
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+ } else {
+ /* Only managed connections are announced to the settings service */
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
+ }
+ }
+ return;
+ }
+
+ new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, NULL, &error, &ignore_error);
+ if (!new) {
+ /* errors reading connection; remove it */
+ if (!ignore_error) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ }
+ g_clear_error (&error);
+
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", path);
+ remove_connection (self, existing);
+ return;
+ }
+
+ /* Successfully read connection changes */
+
+ /* When the connections are the same, nothing is done */
+ if (nm_connection_compare (NM_CONNECTION (existing),
+ NM_CONNECTION (new),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ g_object_unref (new);
+ return;
+ }
+
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
+
+ old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing));
+ new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
+
+ if (new_unmanaged) {
+ if (!old_unmanaged) {
+ /* Unexport the connection by telling the settings service it's
+ * been removed, and notify the settings service by signalling that
+ * unmanaged specs have changed.
+ */
+ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (existing));
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+ }
+ } else {
+ if (old_unmanaged) { /* now managed */
+ const char *cid;
+
+ cid = nm_connection_get_id (NM_CONNECTION (new));
+ g_assert (cid);
+
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its "
+ "device because NM_CONTROLLED was true.", cid);
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing);
+ }
+
+ nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (existing),
+ NM_CONNECTION (new),
+ commit_cb, NULL);
+
+ /* Update unmanaged status */
+ g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL);
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+ }
+ g_object_unref (new);
+}
+
+static void
+dir_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ char *path, *name;
+ NMIfcfgConnection *connection;
+
+ path = g_file_get_path (file);
+ if (utils_should_ignore_file (path, FALSE)) {
+ g_free (path);
+ return;
+ }
+
+ /* Given any ifcfg, keys, or routes file, get the ifcfg file path */
+ name = utils_get_ifcfg_path (path);
+ g_free (path);
+ if (name) {
+ connection = g_hash_table_lookup (priv->connections, name);
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name);
+ if (connection)
+ remove_connection (plugin, connection);
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ /* Update or new */
+ connection_new_or_changed (plugin, name, connection);
+ break;
+ default:
+ break;
+ }
+ g_free (name);
+ }
+}
+
+static void
+setup_ifcfg_monitoring (SCPluginIfcfg *plugin)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ GFile *file;
+ GFileMonitor *monitor;
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+ file = g_file_new_for_path (IFCFG_DIR "/");
+ monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), plugin);
+ priv->monitor = monitor;
+ }
+}
+
+static GSList *
+get_connections (NMSystemConfigInterface *config)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ GSList *list = NULL;
+ GHashTableIter iter;
+ gpointer value;
+
+ if (!priv->connections) {
+ setup_ifcfg_monitoring (plugin);
+ read_connections (plugin);
+ }
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &value)) {
+ NMIfcfgConnection *exported = NM_IFCFG_CONNECTION (value);
+
+ if (!nm_ifcfg_connection_get_unmanaged_spec (exported))
+ list = g_slist_prepend (list, value);
+ }
+
+ return list;
+}
+
+static void
+check_unmanaged (gpointer key, gpointer data, gpointer user_data)
+{
+ GSList **list = (GSList **) user_data;
+ NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (data);
+ const char *unmanaged_spec;
+ GSList *iter;
+
+ unmanaged_spec = nm_ifcfg_connection_get_unmanaged_spec (connection);
+ if (!unmanaged_spec)
+ return;
+
+ /* Just return if the unmanaged spec is already in the list */
+ for (iter = *list; iter; iter = g_slist_next (iter)) {
+ if (!strcmp ((char *) iter->data, unmanaged_spec))
+ return;
+ }
+
+ *list = g_slist_prepend (*list, g_strdup (unmanaged_spec));
+}
+
+static GSList *
+get_unmanaged_specs (NMSystemConfigInterface *config)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+ GSList *list = NULL;
+
+ if (!priv->connections) {
+ setup_ifcfg_monitoring (plugin);
+ read_connections (plugin);
+ }
+
+ g_hash_table_foreach (priv->connections, check_unmanaged, &list);
+ return list;
+}
+
+static NMSettingsConnection *
+add_connection (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ GError **error)
+{
+ SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
+ NMIfcfgConnection *added = NULL;
+ char *path = NULL;
+
+ /* Write it out first, then add the connection to our internal list */
+ if (writer_new_connection (connection, IFCFG_DIR, &path, error)) {
+ added = _internal_new_connection (self, path, connection, error);
+ g_free (path);
+ }
+ return (NMSettingsConnection *) added;
+}
+
+#define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network"
+
+static char *
+plugin_get_hostname (SCPluginIfcfg *plugin)
+{
+ shvarFile *network;
+ char *hostname;
+ gboolean ignore_localhost;
+
+ network = svNewFile (SC_NETWORK_FILE);
+ if (!network) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Could not get hostname: failed to read " SC_NETWORK_FILE);
+ return NULL;
+ }
+
+ hostname = svGetValue (network, "HOSTNAME", FALSE);
+ ignore_localhost = svTrueValue (network, "NM_IGNORE_HOSTNAME_LOCALHOST", FALSE);
+ if (ignore_localhost) {
+ /* Ignore a hostname of 'localhost' or 'localhost.localdomain' to preserve
+ * 'network' service behavior.
+ */
+ if (hostname && (!strcmp (hostname, "localhost") || !strcmp (hostname, "localhost.localdomain"))) {
+ g_free (hostname);
+ hostname = NULL;
+ }
+ }
+
+ svCloseFile (network);
+ return hostname;
+}
+
+static gboolean
+plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ shvarFile *network;
+
+ network = svCreateFile (SC_NETWORK_FILE);
+ if (!network) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Could not save hostname: failed to create/open " SC_NETWORK_FILE);
+ return FALSE;
+ }
+
+ svSetValue (network, "HOSTNAME", hostname, FALSE);
+ svWriteFile (network, 0644);
+ svCloseFile (network);
+
+ g_free (priv->hostname);
+ priv->hostname = g_strdup (hostname);
+ return TRUE;
+}
+
+static void
+sc_network_changed_cb (NMInotifyHelper *ih,
+ struct inotify_event *evt,
+ const char *path,
+ gpointer user_data)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ char *new_hostname;
+
+ if (evt->wd != priv->sc_network_wd)
+ return;
+
+ new_hostname = plugin_get_hostname (plugin);
+ if ( (new_hostname && !priv->hostname)
+ || (!new_hostname && priv->hostname)
+ || (priv->hostname && new_hostname && strcmp (priv->hostname, new_hostname))) {
+ g_free (priv->hostname);
+ priv->hostname = new_hostname;
+ g_object_notify (G_OBJECT (plugin), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+ } else
+ g_free (new_hostname);
+}
+
+static gboolean
+impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin,
+ const char *in_ifcfg,
+ const char **out_uuid,
+ const char **out_path,
+ GError **error)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ NMIfcfgConnection *connection;
+ NMSettingConnection *s_con;
+ const char *uuid;
+ const char *path;
+
+ if (!g_path_is_absolute (in_ifcfg)) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "ifcfg path '%s' is not absolute", in_ifcfg);
+ return FALSE;
+ }
+
+ connection = g_hash_table_lookup (priv->connections, in_ifcfg);
+ if (!connection || nm_ifcfg_connection_get_unmanaged_spec (connection)) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INVALID_CONNECTION,
+ "ifcfg file '%s' unknown", in_ifcfg);
+ return FALSE;
+ }
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+ if (!s_con) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ "unable to retrieve the connection setting");
+ return FALSE;
+ }
+
+ uuid = nm_setting_connection_get_uuid (s_con);
+ if (!uuid) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ "unable to get the UUID");
+ return FALSE;
+ }
+
+ path = nm_connection_get_path (NM_CONNECTION (connection));
+ if (!path) {
+ g_set_error (error,
+ NM_SETTINGS_ERROR,
+ NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ "unable to get the connection D-Bus path");
+ return FALSE;
+ }
+
+ *out_uuid = g_strdup (uuid);
+ *out_path = g_strdup (path);
+
+ return TRUE;
+}
+
+static void
+init (NMSystemConfigInterface *config)
+{
+}
+
+static void
+sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ NMInotifyHelper *ih;
+ GError *error = NULL;
+ gboolean success = FALSE;
+
+ ih = nm_inotify_helper_get ();
+ priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (sc_network_changed_cb), plugin);
+ priv->sc_network_wd = nm_inotify_helper_add_watch (ih, SC_NETWORK_FILE);
+
+ priv->hostname = plugin_get_hostname (plugin);
+
+ priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (!priv->bus) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't connect to D-Bus: %s",
+ error->message);
+ g_clear_error (&error);
+ } else {
+ DBusConnection *tmp;
+ DBusGProxy *proxy;
+ int result;
+
+ tmp = dbus_g_connection_get_connection (priv->bus);
+ dbus_connection_set_exit_on_disconnect (tmp, FALSE);
+
+ proxy = dbus_g_proxy_new_for_name (priv->bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+
+ if (!dbus_g_proxy_call (proxy, "RequestName", &error,
+ G_TYPE_STRING, DBUS_SERVICE_NAME,
+ G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &result,
+ G_TYPE_INVALID)) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't acquire D-Bus service: %s",
+ error->message);
+ g_clear_error (&error);
+ } else if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, "Couldn't acquire ifcfgrh1 D-Bus service (already taken)");
+ } else
+ success = TRUE;
+ }
+
+ if (!success) {
+ dbus_g_connection_unref (priv->bus);
+ priv->bus = NULL;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (object);
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ NMInotifyHelper *ih;
+
+ if (priv->bus) {
+ dbus_g_connection_unref (priv->bus);
+ priv->bus = NULL;
+ }
+
+ ih = nm_inotify_helper_get ();
+
+ g_signal_handler_disconnect (ih, priv->ih_event_id);
+
+ if (priv->sc_network_wd >= 0)
+ nm_inotify_helper_remove_watch (ih, priv->sc_network_wd);
+
+ g_free (priv->hostname);
+
+ if (priv->connections)
+ g_hash_table_destroy (priv->connections);
+
+ if (priv->monitor) {
+ if (priv->monitor_id)
+ g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+
+ g_file_monitor_cancel (priv->monitor);
+ g_object_unref (priv->monitor);
+ }
+
+ G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, IFCFG_PLUGIN_NAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, IFCFG_PLUGIN_INFO);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+ g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ g_value_set_string (value, priv->hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ const char *hostname;
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ hostname = g_value_get_string (value);
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ plugin_set_hostname (SC_PLUGIN_IFCFG (object), hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
+
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+ NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class),
+ &dbus_glib_nm_ifcfg_rh_object_info);
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+ /* interface implementation */
+ system_config_interface_class->get_connections = get_connections;
+ system_config_interface_class->add_connection = add_connection;
+ system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
+ system_config_interface_class->init = init;
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+ static SCPluginIfcfg *singleton = NULL;
+ SCPluginIfcfgPrivate *priv;
+
+ if (!singleton) {
+ singleton = SC_PLUGIN_IFCFG (g_object_new (SC_TYPE_PLUGIN_IFCFG, NULL));
+ if (singleton) {
+ priv = SC_PLUGIN_IFCFG_GET_PRIVATE (singleton);
+ if (priv->bus)
+ dbus_g_connection_register_g_object (priv->bus,
+ DBUS_OBJECT_PATH,
+ G_OBJECT (singleton));
+ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Acquired D-Bus service %s", DBUS_SERVICE_NAME);
+ }
+ } else
+ g_object_ref (singleton);
+
+ return G_OBJECT (singleton);
+}
diff --git a/src/settings/plugins/ifcfg-rh/plugin.h b/src/settings/plugins/ifcfg-rh/plugin.h
new file mode 100644
index 000000000..d820a26e0
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/plugin.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * Dan Williams <dcbw@redhat.com>
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 - 2008 Red Hat, Inc.
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ())
+#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg))
+#define SC_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass))
+#define SC_IS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG))
+#define SC_IS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG))
+#define SC_PLUGIN_IFCFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass))
+
+typedef struct _SCPluginIfcfg SCPluginIfcfg;
+typedef struct _SCPluginIfcfgClass SCPluginIfcfgClass;
+
+struct _SCPluginIfcfg {
+ GObject parent;
+};
+
+struct _SCPluginIfcfgClass {
+ GObjectClass parent;
+};
+
+GType sc_plugin_ifcfg_get_type (void);
+
+#endif /* _PLUGIN_H_ */
+
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
new file mode 100644
index 000000000..c366dd405
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -0,0 +1,3466 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <ctype.h>
+#include <sys/inotify.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <netinet/ether.h>
+
+#ifndef __user
+#define __user
+#endif
+#include <linux/types.h>
+#include <wireless.h>
+#undef __user
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <nm-connection.h>
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-8021x.h>
+#include <nm-utils.h>
+
+#include "common.h"
+#include "shvar.h"
+#include "utils.h"
+
+#include "reader.h"
+
+#define PLUGIN_PRINT(pname, fmt, args...) \
+ { g_message (" " pname ": " fmt, ##args); }
+
+#define PLUGIN_WARN(pname, fmt, args...) \
+ { g_warning (" " pname ": " fmt, ##args); }
+
+static gboolean
+get_int (const char *str, int *value)
+{
+ char *e;
+
+ errno = 0;
+ *value = strtol (str, &e, 0);
+ if (errno || *e != '\0')
+ return FALSE;
+
+ return TRUE;
+}
+
+static NMSetting *
+make_connection_setting (const char *file,
+ shvarFile *ifcfg,
+ const char *type,
+ const char *suggested)
+{
+ NMSettingConnection *s_con;
+ const char *ifcfg_name = NULL;
+ char *new_id = NULL, *uuid = NULL, *value;
+ char *ifcfg_id;
+
+ ifcfg_name = utils_get_ifcfg_name (file, TRUE);
+ if (!ifcfg_name)
+ return NULL;
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+
+ /* Try the ifcfg file's internally defined name if available */
+ ifcfg_id = svGetValue (ifcfg, "NAME", FALSE);
+ if (ifcfg_id && strlen (ifcfg_id))
+ g_object_set (s_con, NM_SETTING_CONNECTION_ID, ifcfg_id, NULL);
+
+ if (!nm_setting_connection_get_id (s_con)) {
+ if (suggested) {
+ /* For cosmetic reasons, if the suggested name is the same as
+ * the ifcfg files name, don't use it. Mainly for wifi so that
+ * the SSID is shown in the connection ID instead of just "wlan0".
+ */
+ if (strcmp (ifcfg_name, suggested)) {
+ new_id = g_strdup_printf ("%s %s (%s)", reader_get_prefix (), suggested, ifcfg_name);
+ g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
+ }
+ }
+
+ /* Use the ifcfg file's name as a last resort */
+ if (!nm_setting_connection_get_id (s_con)) {
+ new_id = g_strdup_printf ("%s %s", reader_get_prefix (), ifcfg_name);
+ g_object_set (s_con, NM_SETTING_CONNECTION_ID, new_id, NULL);
+ }
+ }
+
+ g_free (new_id);
+ g_free (ifcfg_id);
+
+ /* Try for a UUID key before falling back to hashing the file name */
+ uuid = svGetValue (ifcfg, "UUID", FALSE);
+ if (!uuid || !strlen (uuid)) {
+ g_free (uuid);
+ uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName);
+ }
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_TYPE, type,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NULL);
+ g_free (uuid);
+
+ /* Missing ONBOOT is treated as "ONBOOT=true" by the old network service */
+ g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT,
+ svTrueValue (ifcfg, "ONBOOT", TRUE),
+ NULL);
+
+ value = svGetValue (ifcfg, "USERS", FALSE);
+ if (value) {
+ char **items, **iter;
+
+ items = g_strsplit_set (value, " ", -1);
+ for (iter = items; iter && *iter; iter++) {
+ if (strlen (*iter)) {
+ if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid USERS item '%s'", *iter);
+ }
+ }
+ g_free (value);
+ }
+
+ return NM_SETTING (s_con);
+}
+
+static gboolean
+read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error)
+{
+ char *value = NULL;
+ struct ether_addr *mac;
+
+ g_return_val_if_fail (ifcfg != NULL, FALSE);
+ g_return_val_if_fail (array != NULL, FALSE);
+ g_return_val_if_fail (*array == NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ value = svGetValue (ifcfg, key, FALSE);
+ if (!value || !strlen (value)) {
+ g_free (value);
+ return TRUE;
+ }
+
+ mac = ether_aton (value);
+ if (!mac) {
+ g_free (value);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "%s: the MAC address '%s' was invalid.", key, value);
+ return FALSE;
+ }
+
+ g_free (value);
+ *array = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN);
+ return TRUE;
+}
+
+static void
+iscsiadm_child_setup (gpointer user_data G_GNUC_UNUSED)
+{
+ /* We are in the child process here; set a different process group to
+ * ensure signal isolation between child and parent.
+ */
+ pid_t pid = getpid ();
+ setpgid (pid, pid);
+}
+
+static char *
+match_iscsiadm_tag (const char *line, const char *tag, gboolean *skip)
+{
+ char *p;
+
+ if (g_ascii_strncasecmp (line, tag, strlen (tag)))
+ return NULL;
+
+ p = strchr (line, '=');
+ if (!p) {
+ g_warning ("%s: malformed iscsiadm record: no = in '%s'.",
+ __func__, line);
+ *skip = TRUE;
+ return NULL;
+ }
+
+ p++; /* advance past = */
+ return g_strstrip (p);
+}
+
+#define ISCSI_HWADDR_TAG "iface.hwaddress"
+#define ISCSI_BOOTPROTO_TAG "iface.bootproto"
+#define ISCSI_IPADDR_TAG "iface.ipaddress"
+#define ISCSI_SUBNET_TAG "iface.subnet_mask"
+#define ISCSI_GATEWAY_TAG "iface.gateway"
+#define ISCSI_DNS1_TAG "iface.primary_dns"
+#define ISCSI_DNS2_TAG "iface.secondary_dns"
+
+static gboolean
+fill_ip4_setting_from_ibft (shvarFile *ifcfg,
+ NMSettingIP4Config *s_ip4,
+ const char *iscsiadm_path,
+ GError **error)
+{
+ const char *argv[4] = { iscsiadm_path, "-m", "fw", NULL };
+ const char *envp[1] = { NULL };
+ gboolean success = FALSE, in_record = FALSE, hwaddr_matched = FALSE, skip = FALSE;
+ char *out = NULL, *err = NULL;
+ gint status = 0;
+ GByteArray *ifcfg_mac = NULL;
+ char **lines = NULL, **iter;
+ const char *method = NULL;
+ struct in_addr ipaddr;
+ struct in_addr gateway;
+ struct in_addr dns1;
+ struct in_addr dns2;
+ guint32 prefix = 0;
+
+ g_return_val_if_fail (s_ip4 != NULL, FALSE);
+ g_return_val_if_fail (iscsiadm_path != NULL, FALSE);
+
+ if (!g_spawn_sync ("/", (char **) argv, (char **) envp, 0,
+ iscsiadm_child_setup, NULL, &out, &err, &status, error))
+ return FALSE;
+
+ if (!WIFEXITED (status)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "%s exited abnormally.", iscsiadm_path);
+ goto done;
+ }
+
+ if (WEXITSTATUS (status) != 0) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "%s exited with error %d. Message: '%s'",
+ iscsiadm_path, WEXITSTATUS (status), err ? err : "(none)");
+ goto done;
+ }
+
+ if (!read_mac_address (ifcfg, "HWADDR", &ifcfg_mac, error))
+ goto done;
+ /* Ensure we got a MAC */
+ if (!ifcfg_mac) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing device MAC address (no HWADDR tag present).");
+ goto done;
+ }
+
+ memset (&ipaddr, 0, sizeof (ipaddr));
+ memset (&gateway, 0, sizeof (gateway));
+ memset (&dns1, 0, sizeof (dns1));
+ memset (&dns2, 0, sizeof (dns2));
+
+ /* Success, lets parse the output */
+ lines = g_strsplit_set (out, "\n\r", -1);
+ for (iter = lines; iter && *iter; iter++) {
+ char *p;
+
+ if (!g_ascii_strcasecmp (*iter, "# BEGIN RECORD")) {
+ if (in_record) {
+ g_warning ("%s: malformed iscsiadm record: already parsing record.", __func__);
+ skip = TRUE;
+ }
+ } else if (!g_ascii_strcasecmp (*iter, "# END RECORD")) {
+ if (!skip && hwaddr_matched) {
+ /* Record is good; fill IP4 config with its info */
+ if (!method) {
+ g_warning ("%s: malformed iscsiadm record: missing BOOTPROTO.", __func__);
+ return FALSE;
+ }
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, method, NULL);
+
+ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
+ NMIP4Address *addr;
+
+ if (!ipaddr.s_addr || !prefix) {
+ g_warning ("%s: malformed iscsiadm record: BOOTPROTO=static "
+ "but missing IP address or prefix.", __func__);
+ return FALSE;
+ }
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ipaddr.s_addr);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gateway.s_addr);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ if (dns1.s_addr)
+ nm_setting_ip4_config_add_dns (s_ip4, dns1.s_addr);
+ if (dns2.s_addr)
+ nm_setting_ip4_config_add_dns (s_ip4, dns2.s_addr);
+
+ // FIXME: DNS search domains?
+ }
+ return TRUE;
+ }
+ skip = FALSE;
+ hwaddr_matched = FALSE;
+ memset (&ipaddr, 0, sizeof (ipaddr));
+ memset (&gateway, 0, sizeof (gateway));
+ memset (&dns1, 0, sizeof (dns1));
+ memset (&dns2, 0, sizeof (dns2));
+ prefix = 0;
+ method = NULL;
+ }
+
+ if (skip)
+ continue;
+
+ /* HWADDR */
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_HWADDR_TAG, &skip))) {
+ struct ether_addr *ibft_mac;
+
+ ibft_mac = ether_aton (p);
+ if (!ibft_mac) {
+ g_warning ("%s: malformed iscsiadm record: invalid hwaddress.", __func__);
+ skip = TRUE;
+ continue;
+ }
+
+ if (memcmp (ifcfg_mac->data, (guint8 *) ibft_mac->ether_addr_octet, ETH_ALEN)) {
+ /* This record isn't for the current device, ignore it */
+ skip = TRUE;
+ continue;
+ }
+
+ /* Success, this record is for this device */
+ hwaddr_matched = TRUE;
+ }
+
+ /* BOOTPROTO */
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_BOOTPROTO_TAG, &skip))) {
+ if (!g_ascii_strcasecmp (p, "dhcp"))
+ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
+ else if (!g_ascii_strcasecmp (p, "static"))
+ method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ else {
+ g_warning ("%s: malformed iscsiadm record: unknown BOOTPROTO '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+ }
+
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_IPADDR_TAG, &skip))) {
+ if (inet_pton (AF_INET, p, &ipaddr) < 1) {
+ g_warning ("%s: malformed iscsiadm record: invalid IP address '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+ }
+
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_SUBNET_TAG, &skip))) {
+ struct in_addr mask;
+
+ if (inet_pton (AF_INET, p, &mask) < 1) {
+ g_warning ("%s: malformed iscsiadm record: invalid subnet mask '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+
+ prefix = nm_utils_ip4_netmask_to_prefix (mask.s_addr);
+ }
+
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_GATEWAY_TAG, &skip))) {
+ if (inet_pton (AF_INET, p, &gateway) < 1) {
+ g_warning ("%s: malformed iscsiadm record: invalid IP gateway '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+ }
+
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS1_TAG, &skip))) {
+ if (inet_pton (AF_INET, p, &dns1) < 1) {
+ g_warning ("%s: malformed iscsiadm record: invalid DNS1 address '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+ }
+
+ if (!skip && (p = match_iscsiadm_tag (*iter, ISCSI_DNS2_TAG, &skip))) {
+ if (inet_pton (AF_INET, p, &dns2) < 1) {
+ g_warning ("%s: malformed iscsiadm record: invalid DNS2 address '%s'.",
+ __func__, p);
+ skip = TRUE;
+ continue;
+ }
+ }
+ }
+
+ success = TRUE;
+
+done:
+ if (ifcfg_mac)
+ g_byte_array_free (ifcfg_mac, TRUE);
+ g_strfreev (lines);
+ g_free (out);
+ g_free (err);
+ return success;
+}
+
+static gboolean
+read_ip4_address (shvarFile *ifcfg,
+ const char *tag,
+ guint32 *out_addr,
+ GError **error)
+{
+ char *value = NULL;
+ struct in_addr ip4_addr;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (ifcfg != NULL, FALSE);
+ g_return_val_if_fail (tag != NULL, FALSE);
+ g_return_val_if_fail (out_addr != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ *out_addr = 0;
+
+ value = svGetValue (ifcfg, tag, FALSE);
+ if (!value)
+ return TRUE;
+
+ if (inet_pton (AF_INET, value, &ip4_addr) > 0) {
+ *out_addr = ip4_addr.s_addr;
+ success = TRUE;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid %s IP4 address '%s'", tag, value);
+ }
+ g_free (value);
+ return success;
+}
+
+static gboolean
+parse_ip6_address (const char *value,
+ struct in6_addr *out_addr,
+ GError **error)
+{
+ struct in6_addr ip6_addr;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (value != NULL, FALSE);
+ g_return_val_if_fail (out_addr != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ *out_addr = in6addr_any;
+
+ if (inet_pton (AF_INET6, value, &ip6_addr) > 0) {
+ *out_addr = ip6_addr;
+ success = TRUE;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 address '%s'", value);
+ }
+ return success;
+}
+
+static NMIP4Address *
+read_full_ip4_address (shvarFile *ifcfg,
+ const char *network_file,
+ guint32 which,
+ GError **error)
+{
+ NMIP4Address *addr;
+ char *ip_tag, *prefix_tag, *netmask_tag, *gw_tag;
+ guint32 tmp;
+ gboolean success = FALSE;
+ shvarFile *network_ifcfg;
+ char *value;
+
+ g_return_val_if_fail (which > 0, NULL);
+ g_return_val_if_fail (ifcfg != NULL, NULL);
+ g_return_val_if_fail (network_file != NULL, NULL);
+
+ addr = nm_ip4_address_new ();
+ if (which == 1) {
+ ip_tag = g_strdup ("IPADDR");
+ prefix_tag = g_strdup ("PREFIX");
+ netmask_tag = g_strdup ("NETMASK");
+ gw_tag = g_strdup ("GATEWAY");
+ } else {
+ ip_tag = g_strdup_printf ("IPADDR%u", which);
+ prefix_tag = g_strdup_printf ("PREFIX%u", which);
+ netmask_tag = g_strdup_printf ("NETMASK%u", which);
+ gw_tag = g_strdup_printf ("GATEWAY%u", which);
+ }
+
+ /* IP address */
+ if (!read_ip4_address (ifcfg, ip_tag, &tmp, error))
+ goto error;
+ if (!tmp) {
+ nm_ip4_address_unref (addr);
+ addr = NULL;
+ success = TRUE; /* done */
+ goto error;
+ }
+ nm_ip4_address_set_address (addr, tmp);
+
+ /* Gateway */
+ if (!read_ip4_address (ifcfg, gw_tag, &tmp, error))
+ goto error;
+ if (tmp)
+ nm_ip4_address_set_gateway (addr, tmp);
+ else {
+ gboolean read_success;
+
+ /* If no gateway in the ifcfg, try /etc/sysconfig/network instead */
+ network_ifcfg = svNewFile (network_file);
+ if (network_ifcfg) {
+ read_success = read_ip4_address (network_ifcfg, "GATEWAY", &tmp, error);
+ svCloseFile (network_ifcfg);
+ if (!read_success)
+ goto error;
+ nm_ip4_address_set_gateway (addr, tmp);
+ }
+ }
+
+ /* Prefix */
+ value = svGetValue (ifcfg, prefix_tag, FALSE);
+ if (value) {
+ long int prefix;
+
+ errno = 0;
+ prefix = strtol (value, NULL, 10);
+ if (errno || prefix <= 0 || prefix > 32) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 prefix '%s'", value);
+ g_free (value);
+ goto error;
+ }
+ nm_ip4_address_set_prefix (addr, (guint32) prefix);
+ g_free (value);
+ }
+
+ /* Fall back to NETMASK if no PREFIX was specified */
+ if (!nm_ip4_address_get_prefix (addr)) {
+ if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error))
+ goto error;
+ nm_ip4_address_set_prefix (addr, nm_utils_ip4_netmask_to_prefix (tmp));
+ }
+
+ /* Try to autodetermine the prefix for the address' class */
+ if (!nm_ip4_address_get_prefix (addr)) {
+ guint32 prefix = 0;
+
+ prefix = nm_utils_ip4_get_default_prefix (nm_ip4_address_get_address (addr));
+ nm_ip4_address_set_prefix (addr, prefix);
+
+ value = svGetValue (ifcfg, ip_tag, FALSE);
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing %s, assuming %s/%u",
+ prefix_tag, value, prefix);
+ g_free (value);
+ }
+
+ /* Validate the prefix */
+ if (nm_ip4_address_get_prefix (addr) > 32) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing or invalid IP4 prefix '%d'",
+ nm_ip4_address_get_prefix (addr));
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ if (!success) {
+ nm_ip4_address_unref (addr);
+ addr = NULL;
+ }
+
+ g_free (ip_tag);
+ g_free (prefix_tag);
+ g_free (netmask_tag);
+ g_free (gw_tag);
+ return addr;
+}
+
+static NMIP4Route *
+read_one_ip4_route (shvarFile *ifcfg,
+ const char *network_file,
+ guint32 which,
+ GError **error)
+{
+ NMIP4Route *route;
+ char *ip_tag, *netmask_tag, *gw_tag, *metric_tag, *value;
+ guint32 tmp;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (ifcfg != NULL, NULL);
+ g_return_val_if_fail (network_file != NULL, NULL);
+ g_return_val_if_fail (which >= 0, NULL);
+
+ route = nm_ip4_route_new ();
+
+ ip_tag = g_strdup_printf ("ADDRESS%u", which);
+ netmask_tag = g_strdup_printf ("NETMASK%u", which);
+ gw_tag = g_strdup_printf ("GATEWAY%u", which);
+ metric_tag = g_strdup_printf ("METRIC%u", which);
+
+ /* Destination */
+ if (!read_ip4_address (ifcfg, ip_tag, &tmp, error))
+ goto out;
+ if (!tmp) {
+ /* Check whether IP is missing or 0.0.0.0 */
+ char *val;
+ val = svGetValue (ifcfg, ip_tag, FALSE);
+ if (!val) {
+ nm_ip4_route_unref (route);
+ route = NULL;
+ success = TRUE; /* done */
+ goto out;
+ }
+ g_free (val);
+ }
+ nm_ip4_route_set_dest (route, tmp);
+
+ /* Next hop */
+ if (!read_ip4_address (ifcfg, gw_tag, &tmp, error))
+ goto out;
+ /* No need to check tmp, because we don't make distinction between missing GATEWAY IP and 0.0.0.0 */
+ nm_ip4_route_set_next_hop (route, tmp);
+
+ /* Prefix */
+ if (!read_ip4_address (ifcfg, netmask_tag, &tmp, error))
+ goto out;
+ nm_ip4_route_set_prefix (route, nm_utils_ip4_netmask_to_prefix (tmp));
+
+ /* Validate the prefix */
+ if ( !nm_ip4_route_get_prefix (route)
+ || nm_ip4_route_get_prefix (route) > 32) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing or invalid IP4 prefix '%d'",
+ nm_ip4_route_get_prefix (route));
+ goto out;
+ }
+
+ /* Metric */
+ value = svGetValue (ifcfg, metric_tag, FALSE);
+ if (value) {
+ long int metric;
+
+ errno = 0;
+ metric = strtol (value, NULL, 10);
+ if (errno || metric < 0) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 route metric '%s'", value);
+ g_free (value);
+ goto out;
+ }
+ nm_ip4_route_set_metric (route, (guint32) metric);
+ g_free (value);
+ }
+
+ success = TRUE;
+
+out:
+ if (!success) {
+ nm_ip4_route_unref (route);
+ route = NULL;
+ }
+
+ g_free (ip_tag);
+ g_free (netmask_tag);
+ g_free (gw_tag);
+ g_free (metric_tag);
+ return route;
+}
+
+static gboolean
+read_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error)
+{
+ char *contents = NULL;
+ gsize len = 0;
+ char **lines = NULL, **iter;
+ GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
+ GMatchInfo *match_info;
+ NMIP4Route *route;
+ struct in_addr ip4_addr;
+ char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
+ long int prefix_int, metric_int;
+ gboolean success = FALSE;
+
+ const char *pattern_empty = "^\\s*(\\#.*)?$";
+ const char *pattern_to1 = "^\\s*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */
+ "(?:/(\\d{1,2}))?"; /* optional prefix */
+ const char *pattern_to2 = "to\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|default)" /* IP or 'default' keyword */
+ "(?:/(\\d{1,2}))?"; /* optional prefix */
+ const char *pattern_via = "via\\s+(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"; /* IP of gateway */
+ const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */
+
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (s_ip4 != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ /* Read the route file */
+ if (!g_file_get_contents (filename, &contents, &len, NULL))
+ return FALSE;
+
+ if (len == 0) {
+ g_free (contents);
+ return FALSE;
+ }
+
+ /* Create regexes for pieces to be matched */
+ regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL);
+ regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL);
+ regex_via = g_regex_new (pattern_via, 0, 0, NULL);
+ regex_metric = g_regex_new (pattern_metric, 0, 0, NULL);
+
+ /* New NMIP4Route structure */
+ route = nm_ip4_route_new ();
+
+ /* Iterate through file lines */
+ lines = g_strsplit_set (contents, "\n\r", -1);
+ for (iter = lines; iter && *iter; iter++) {
+
+ /* Skip empty lines */
+ if (g_regex_match_simple (pattern_empty, *iter, 0, 0))
+ continue;
+
+ /* Destination */
+ g_regex_match (regex_to1, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_regex_match (regex_to2, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IP4 route destination address in record: '%s'", *iter);
+ goto error;
+ }
+ }
+ dest = g_match_info_fetch (match_info, 1);
+ g_match_info_free (match_info);
+ if (!strcmp (dest, "default"))
+ strcpy (dest, "0.0.0.0");
+ if (inet_pton (AF_INET, dest, &ip4_addr) != 1) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 route destination address '%s'", dest);
+ g_free (dest);
+ goto error;
+ }
+ nm_ip4_route_set_dest (route, ip4_addr.s_addr);
+ g_free (dest);
+
+ /* Prefix - is optional; 32 if missing */
+ prefix = g_match_info_fetch (match_info, 2);
+ prefix_int = 32;
+ if (prefix) {
+ errno = 0;
+ prefix_int = strtol (prefix, NULL, 10);
+ if (errno || prefix_int < 0 || prefix_int > 32) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 route destination prefix '%s'", prefix);
+ g_free (prefix);
+ goto error;
+ }
+ }
+
+ nm_ip4_route_set_prefix (route, (guint32) prefix_int);
+ g_free (prefix);
+
+ /* Next hop */
+ g_regex_match (regex_via, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IP4 route gateway address in record: '%s'", *iter);
+ goto error;
+ }
+ next_hop = g_match_info_fetch (match_info, 1);
+ g_match_info_free (match_info);
+ if (inet_pton (AF_INET, next_hop, &ip4_addr) != 1) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 route gateway address '%s'", next_hop);
+ g_free (next_hop);
+ goto error;
+ }
+ nm_ip4_route_set_next_hop (route, ip4_addr.s_addr);
+ g_free (next_hop);
+
+ /* Metric */
+ g_regex_match (regex_metric, *iter, 0, &match_info);
+ metric_int = 0;
+ if (g_match_info_matches (match_info)) {
+ metric = g_match_info_fetch (match_info, 1);
+ errno = 0;
+ metric_int = strtol (metric, NULL, 10);
+ if (errno || metric_int < 0) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP4 route metric '%s'", metric);
+ g_free (metric);
+ goto error;
+ }
+ g_free (metric);
+ }
+
+ nm_ip4_route_set_metric (route, (guint32) metric_int);
+ g_match_info_free (match_info);
+
+ if (!nm_setting_ip4_config_add_route (s_ip4, route))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 route");
+
+ }
+
+ success = TRUE;
+
+error:
+ g_free (contents);
+ g_strfreev (lines);
+ nm_ip4_route_unref (route);
+ g_regex_unref (regex_to1);
+ g_regex_unref (regex_to2);
+ g_regex_unref (regex_via);
+ g_regex_unref (regex_metric);
+
+ return success;
+}
+
+static NMIP6Address *
+parse_full_ip6_address (shvarFile *ifcfg,
+ const char *network_file,
+ const char *addr_str,
+ int i,
+ GError **error)
+{
+ NMIP6Address *addr = NULL;
+ char **list;
+ char *ip_val, *prefix_val;
+ shvarFile *network_ifcfg;
+ char *value = NULL;
+ struct in6_addr tmp = IN6ADDR_ANY_INIT;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (addr_str != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (*error == NULL, NULL);
+
+ /* Split the adddress and prefix */
+ list = g_strsplit_set (addr_str, "/", 2);
+ if (g_strv_length (list) < 1) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 address '%s'", addr_str);
+ goto error;
+ }
+
+ ip_val = list[0];
+ prefix_val = list[1];
+
+ addr = nm_ip6_address_new ();
+ /* IP address */
+ if (ip_val) {
+ if (!parse_ip6_address (ip_val, &tmp, error))
+ goto error;
+ }
+ nm_ip6_address_set_address (addr, &tmp);
+
+ /* Prefix */
+ if (prefix_val) {
+ long int prefix;
+
+ errno = 0;
+ prefix = strtol (prefix_val, NULL, 10);
+ if (errno || prefix <= 0 || prefix > 128) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 prefix '%s'", prefix_val);
+ goto error;
+ }
+ nm_ip6_address_set_prefix (addr, (guint32) prefix);
+ } else {
+ /* Missing prefix is treated as prefix of 64 */
+ nm_ip6_address_set_prefix (addr, 64);
+ }
+
+ /* Gateway */
+ tmp = in6addr_any;
+ value = svGetValue (ifcfg, "IPV6_DEFAULTGW", FALSE);
+ if (i != 0) {
+ /* We don't support gateways for IPV6ADDR_SECONDARIES yet */
+ g_free (value);
+ value = NULL;
+ }
+ if (!value) {
+ /* If no gateway in the ifcfg, try global /etc/sysconfig/network instead */
+ network_ifcfg = svNewFile (network_file);
+ if (network_ifcfg) {
+ value = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
+ svCloseFile (network_ifcfg);
+ }
+ }
+ if (value) {
+ char *ptr;
+
+ if ((ptr = strchr (value, '%')) != NULL)
+ *ptr = '\0'; /* remove %interface prefix if present */
+ if (!parse_ip6_address (value, &tmp, error))
+ goto error;
+ nm_ip6_address_set_gateway (addr, &tmp);
+ }
+
+ success = TRUE;
+
+error:
+ if (!success) {
+ nm_ip6_address_unref (addr);
+ addr = NULL;
+ }
+
+ g_strfreev (list);
+ g_free (value);
+ return addr;
+}
+
+/* IPv6 address is very complex to describe completely by a regular expression,
+ * so don't try to, rather use looser syntax to comprise all possibilities
+ * NOTE: The regexes below don't describe all variants allowed by 'ip route add',
+ * namely destination IP without 'to' keyword is recognized just at line start.
+ */
+#define IPV6_ADDR_REGEX "[0-9A-Fa-f:.]+"
+
+static gboolean
+read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error)
+{
+ char *contents = NULL;
+ gsize len = 0;
+ char **lines = NULL, **iter;
+ GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
+ GMatchInfo *match_info;
+ NMIP6Route *route;
+ struct in6_addr ip6_addr;
+ char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
+ long int prefix_int, metric_int;
+ gboolean success = FALSE;
+
+ const char *pattern_empty = "^\\s*(\\#.*)?$";
+ const char *pattern_to1 = "^\\s*(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */
+ "(?:/(\\d{1,2}))?"; /* optional prefix */
+ const char *pattern_to2 = "to\\s+(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */
+ "(?:/(\\d{1,2}))?"; /* optional prefix */
+ const char *pattern_via = "via\\s+(" IPV6_ADDR_REGEX ")"; /* IPv6 of gateway */
+ const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */
+
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (s_ip6 != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ /* Read the route file */
+ if (!g_file_get_contents (filename, &contents, &len, NULL))
+ return FALSE;
+
+ if (len == 0) {
+ g_free (contents);
+ return FALSE;
+ }
+
+ /* Create regexes for pieces to be matched */
+ regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL);
+ regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL);
+ regex_via = g_regex_new (pattern_via, 0, 0, NULL);
+ regex_metric = g_regex_new (pattern_metric, 0, 0, NULL);
+
+ /* New NMIP6Route structure */
+ route = nm_ip6_route_new ();
+
+ /* Iterate through file lines */
+ lines = g_strsplit_set (contents, "\n\r", -1);
+ for (iter = lines; iter && *iter; iter++) {
+
+ /* Skip empty lines */
+ if (g_regex_match_simple (pattern_empty, *iter, 0, 0))
+ continue;
+
+ /* Destination */
+ g_regex_match (regex_to1, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_regex_match (regex_to2, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IP6 route destination address in record: '%s'", *iter);
+ goto error;
+ }
+ }
+ dest = g_match_info_fetch (match_info, 1);
+ g_match_info_free (match_info);
+ if (!strcmp (dest, "default"))
+ strcpy (dest, "::");
+ if (inet_pton (AF_INET6, dest, &ip6_addr) != 1) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 route destination address '%s'", dest);
+ g_free (dest);
+ goto error;
+ }
+ nm_ip6_route_set_dest (route, &ip6_addr);
+ g_free (dest);
+
+ /* Prefix - is optional; 128 if missing */
+ prefix = g_match_info_fetch (match_info, 2);
+ prefix_int = 128;
+ if (prefix) {
+ errno = 0;
+ prefix_int = strtol (prefix, NULL, 10);
+ if (errno || prefix_int < 0 || prefix_int > 128) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 route destination prefix '%s'", prefix);
+ g_free (prefix);
+ goto error;
+ }
+ }
+
+ nm_ip6_route_set_prefix (route, (guint32) prefix_int);
+ g_free (prefix);
+
+ /* Next hop */
+ g_regex_match (regex_via, *iter, 0, &match_info);
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IP6 route gateway address in record: '%s'", *iter);
+ goto error;
+ }
+ next_hop = g_match_info_fetch (match_info, 1);
+ g_match_info_free (match_info);
+ if (inet_pton (AF_INET6, next_hop, &ip6_addr) != 1) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 route gateway address '%s'", next_hop);
+ g_free (next_hop);
+ goto error;
+ }
+ nm_ip6_route_set_next_hop (route, &ip6_addr);
+ g_free (next_hop);
+
+ /* Metric */
+ g_regex_match (regex_metric, *iter, 0, &match_info);
+ metric_int = 0;
+ if (g_match_info_matches (match_info)) {
+ metric = g_match_info_fetch (match_info, 1);
+ errno = 0;
+ metric_int = strtol (metric, NULL, 10);
+ if (errno || metric_int < 0 || metric_int > G_MAXUINT32) {
+ g_match_info_free (match_info);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid IP6 route metric '%s'", metric);
+ g_free (metric);
+ goto error;
+ }
+ g_free (metric);
+ }
+
+ nm_ip6_route_set_metric (route, (guint32) metric_int);
+ g_match_info_free (match_info);
+
+ if (!nm_setting_ip6_config_add_route (s_ip6, route))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 route");
+ }
+
+ success = TRUE;
+
+error:
+ g_free (contents);
+ g_strfreev (lines);
+ nm_ip6_route_unref (route);
+ g_regex_unref (regex_to1);
+ g_regex_unref (regex_to2);
+ g_regex_unref (regex_via);
+ g_regex_unref (regex_metric);
+
+ return success;
+}
+
+
+static NMSetting *
+make_ip4_setting (shvarFile *ifcfg,
+ const char *network_file,
+ const char *iscsiadm_path,
+ gboolean valid_ip6_config,
+ GError **error)
+{
+ NMSettingIP4Config *s_ip4 = NULL;
+ char *value = NULL;
+ char *route_path = NULL;
+ char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ guint32 i;
+ shvarFile *network_ifcfg;
+ shvarFile *route_ifcfg;
+ gboolean never_default = FALSE, tmp_success;
+
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ if (!s_ip4) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not allocate IP4 setting");
+ return NULL;
+ }
+
+ /* First check if DEFROUTE is set for this device; DEFROUTE has the
+ * opposite meaning from never-default. The default if DEFROUTE is not
+ * specified is DEFROUTE=yes which means that this connection can be used
+ * as a default route
+ */
+ never_default = !svTrueValue (ifcfg, "DEFROUTE", TRUE);
+
+ /* Then check if GATEWAYDEV; it's global and overrides DEFROUTE */
+ network_ifcfg = svNewFile (network_file);
+ if (network_ifcfg) {
+ char *gatewaydev;
+
+ /* Get the connection ifcfg device name and the global gateway device */
+ value = svGetValue (ifcfg, "DEVICE", FALSE);
+ gatewaydev = svGetValue (network_ifcfg, "GATEWAYDEV", FALSE);
+
+ /* If there was a global gateway device specified, then only connections
+ * for that device can be the default connection.
+ */
+ if (gatewaydev && value)
+ never_default = !!strcmp (value, gatewaydev);
+
+ g_free (gatewaydev);
+ g_free (value);
+ svCloseFile (network_ifcfg);
+ }
+
+ value = svGetValue (ifcfg, "BOOTPROTO", FALSE);
+ if (value) {
+ if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp"))
+ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
+ else if (!g_ascii_strcasecmp (value, "ibft")) {
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL);
+ /* iSCSI Boot Firmware Table: need to read values from the iSCSI
+ * firmware for this device and create the IP4 setting using those.
+ */
+ if (fill_ip4_setting_from_ibft (ifcfg, s_ip4, iscsiadm_path, error))
+ return NM_SETTING (s_ip4);
+ g_object_unref (s_ip4);
+ return NULL;
+ } else if (!g_ascii_strcasecmp (value, "autoip")) {
+ g_free (value);
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
+ NULL);
+ return NM_SETTING (s_ip4);
+ } else if (!g_ascii_strcasecmp (value, "shared")) {
+ g_free (value);
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
+ NULL);
+ return NM_SETTING (s_ip4);
+ } else if (!g_ascii_strcasecmp (value, "none") || !g_ascii_strcasecmp (value, "static")) {
+ /* Static IP */
+ } else if (strlen (value)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown BOOTPROTO '%s'", value);
+ g_free (value);
+ goto done;
+ }
+ g_free (value);
+ } else {
+ char *tmp_ip4, *tmp_prefix, *tmp_netmask;
+
+ /* If there is no BOOTPROTO, no IPADDR, no PREFIX, no NETMASK, but
+ * valid IPv6 configuration, assume that IPv4 is disabled. Otherwise,
+ * if there is no IPv6 configuration, assume DHCP is to be used.
+ * Happens with minimal ifcfg files like the following that anaconda
+ * sometimes used to write out:
+ *
+ * DEVICE=eth0
+ * HWADDR=11:22:33:44:55:66
+ *
+ */
+ tmp_ip4 = svGetValue (ifcfg, "IPADDR", FALSE);
+ tmp_prefix = svGetValue (ifcfg, "PREFIX", FALSE);
+ tmp_netmask = svGetValue (ifcfg, "NETMASK", FALSE);
+ if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) {
+ if (valid_ip6_config) {
+ /* Nope, no IPv4 */
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
+ NULL);
+ return NM_SETTING (s_ip4);
+ }
+
+ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
+ }
+ g_free (tmp_ip4);
+ g_free (tmp_prefix);
+ g_free (tmp_netmask);
+ }
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, method,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "PEERDNS", TRUE),
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "PEERROUTES", TRUE),
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
+ NM_SETTING_IP4_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV4_FAILURE_FATAL", TRUE),
+ NULL);
+
+ /* Handle manual settings */
+ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
+ NMIP4Address *addr;
+
+ for (i = 1; i < 256; i++) {
+ addr = read_full_ip4_address (ifcfg, network_file, i, error);
+ if (error && *error)
+ goto done;
+ if (!addr)
+ break;
+
+ if (!nm_setting_ip4_config_add_address (s_ip4, addr))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 address");
+ nm_ip4_address_unref (addr);
+ }
+ } else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
+ value = svGetValue (ifcfg, "DHCP_HOSTNAME", FALSE);
+ if (value && strlen (value))
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, value, NULL);
+ g_free (value);
+
+ value = svGetValue (ifcfg, "DHCP_CLIENT_ID", FALSE);
+ if (value && strlen (value))
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, value, NULL);
+ g_free (value);
+ }
+
+ /* DNS servers
+ * Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
+ */
+ for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) {
+ char *tag;
+ guint32 dns;
+ struct in6_addr ip6_dns;
+ GError *tmp_err = NULL;
+
+ tag = g_strdup_printf ("DNS%u", i);
+ tmp_success = read_ip4_address (ifcfg, tag, &dns, error);
+ if (!tmp_success) {
+ /* if it's IPv6, don't exit */
+ dns = 0;
+ value = svGetValue (ifcfg, tag, FALSE);
+ if (value) {
+ tmp_success = parse_ip6_address (value, &ip6_dns, &tmp_err);
+ g_clear_error (&tmp_err);
+ g_free (value);
+ }
+ if (!tmp_success) {
+ g_free (tag);
+ goto done;
+ }
+ g_clear_error (error);
+ }
+
+ if (dns && !nm_setting_ip4_config_add_dns (s_ip4, dns))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS server %s", tag);
+ g_free (tag);
+ }
+
+ /* DNS searches */
+ value = svGetValue (ifcfg, "DOMAIN", FALSE);
+ if (value) {
+ char **searches = NULL;
+
+ searches = g_strsplit (value, " ", 0);
+ if (searches) {
+ char **item;
+ for (item = searches; *item; item++) {
+ if (strlen (*item)) {
+ if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS domain '%s'", *item);
+ }
+ }
+ g_strfreev (searches);
+ }
+ g_free (value);
+ }
+
+ /* Static routes - route-<name> file */
+ route_path = utils_get_route_path (ifcfg->fileName);
+ if (!route_path) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not get route file path for '%s'", ifcfg->fileName);
+ goto done;
+ }
+
+ /* First test new/legacy syntax */
+ if (utils_has_route_file_new_syntax (route_path)) {
+ /* Parse route file in new syntax */
+ g_free (route_path);
+ route_ifcfg = utils_get_route_ifcfg (ifcfg->fileName, FALSE);
+ if (route_ifcfg) {
+ NMIP4Route *route;
+ for (i = 0; i < 256; i++) {
+ route = read_one_ip4_route (route_ifcfg, network_file, i, error);
+ if (error && *error) {
+ svCloseFile (route_ifcfg);
+ goto done;
+ }
+ if (!route)
+ break;
+
+ if (!nm_setting_ip4_config_add_route (s_ip4, route))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP4 route");
+ nm_ip4_route_unref (route);
+ }
+ svCloseFile (route_ifcfg);
+ }
+ } else {
+ read_route_file_legacy (route_path, s_ip4, error);
+ g_free (route_path);
+ if (error && *error)
+ goto done;
+ }
+
+ /* Legacy value NM used for a while but is incorrect (rh #459370) */
+ if (!nm_setting_ip4_config_get_num_dns_searches (s_ip4)) {
+ value = svGetValue (ifcfg, "SEARCH", FALSE);
+ if (value) {
+ char **searches = NULL;
+
+ searches = g_strsplit (value, " ", 0);
+ if (searches) {
+ char **item;
+ for (item = searches; *item; item++) {
+ if (strlen (*item)) {
+ if (!nm_setting_ip4_config_add_dns_search (s_ip4, *item))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS search '%s'", *item);
+ }
+ }
+ g_strfreev (searches);
+ }
+ g_free (value);
+ }
+ }
+
+ return NM_SETTING (s_ip4);
+
+done:
+ g_object_unref (s_ip4);
+ return NULL;
+}
+
+static NMSetting *
+make_ip6_setting (shvarFile *ifcfg,
+ const char *network_file,
+ const char *iscsiadm_path,
+ GError **error)
+{
+ NMSettingIP6Config *s_ip6 = NULL;
+ char *value = NULL;
+ char *str_value;
+ char *route6_path = NULL;
+ gboolean bool_value, ipv6forwarding, ipv6_autoconf, dhcp6 = FALSE;
+ char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+ guint32 i;
+ shvarFile *network_ifcfg;
+ gboolean never_default = FALSE, tmp_success;
+
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ if (!s_ip6) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not allocate IP6 setting");
+ return NULL;
+ }
+
+ /* Is IPV6 enabled? Set method to "ignored", when not enabled */
+ str_value = svGetValue (ifcfg, "IPV6INIT", FALSE);
+ bool_value = svTrueValue (ifcfg, "IPV6INIT", FALSE);
+ if (!str_value) {
+ network_ifcfg = svNewFile (network_file);
+ if (network_ifcfg) {
+ bool_value = svTrueValue (network_ifcfg, "IPV6INIT", FALSE);
+ svCloseFile (network_ifcfg);
+ }
+ }
+ g_free (str_value);
+
+ if (!bool_value) {
+ /* IPv6 is disabled */
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+ return NM_SETTING (s_ip6);
+ }
+
+ /* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the
+ * opposite meaning from never-default. The default if IPV6_DEFROUTE is not
+ * specified is IPV6_DEFROUTE=yes which means that this connection can be used
+ * as a default route
+ */
+ never_default = !svTrueValue (ifcfg, "IPV6_DEFROUTE", TRUE);
+
+ /* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified;
+ * they are global and override IPV6_DEFROUTE
+ * When both are set, the device specified in IPV6_DEFAULTGW takes preference.
+ */
+ network_ifcfg = svNewFile (network_file);
+ if (network_ifcfg) {
+ char *ipv6_defaultgw, *ipv6_defaultdev;
+ char *default_dev = NULL;
+
+ /* Get the connection ifcfg device name and the global default route device */
+ value = svGetValue (ifcfg, "DEVICE", FALSE);
+ ipv6_defaultgw = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
+ ipv6_defaultdev = svGetValue (network_ifcfg, "IPV6_DEFAULTDEV", FALSE);
+
+ if (ipv6_defaultgw) {
+ default_dev = strchr (ipv6_defaultgw, '%');
+ if (default_dev)
+ default_dev++;
+ }
+ if (!default_dev)
+ default_dev = ipv6_defaultdev;
+
+ /* If there was a global default route device specified, then only connections
+ * for that device can be the default connection.
+ */
+ if (default_dev && value)
+ never_default = !!strcmp (value, default_dev);
+
+ g_free (ipv6_defaultgw);
+ g_free (ipv6_defaultdev);
+ g_free (value);
+ svCloseFile (network_ifcfg);
+ }
+
+ /* Find out method property */
+ ipv6forwarding = svTrueValue (ifcfg, "IPV6FORWARDING", FALSE);
+ ipv6_autoconf = svTrueValue (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding);
+ dhcp6 = svTrueValue (ifcfg, "DHCPV6C", FALSE);
+
+ if (ipv6_autoconf)
+ method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
+ else if (dhcp6)
+ method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
+ else {
+ /* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */
+ str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE);
+ if (!str_value)
+ str_value = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
+
+ if (!str_value)
+ method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
+ g_free (str_value);
+ }
+ /* TODO - handle other methods */
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, method,
+ NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE),
+ NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE),
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
+ NM_SETTING_IP6_CONFIG_MAY_FAIL, !svTrueValue (ifcfg, "IPV6_FAILURE_FATAL", FALSE),
+ NULL);
+
+ if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ NMIP6Address *addr;
+ char *val;
+ char *ipv6addr, *ipv6addr_secondaries;
+ char **list = NULL, **iter;
+
+ ipv6addr = svGetValue (ifcfg, "IPV6ADDR", FALSE);
+ ipv6addr_secondaries = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
+
+ val = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL,
+ ipv6addr ? ipv6addr : "",
+ ipv6addr_secondaries ? ipv6addr_secondaries : "",
+ NULL);
+ g_free (ipv6addr);
+ g_free (ipv6addr_secondaries);
+
+ list = g_strsplit_set (val, " ", 0);
+ g_free (val);
+ for (iter = list, i = 0; iter && *iter; iter++, i++) {
+ addr = parse_full_ip6_address (ifcfg, network_file, *iter, i, error);
+ if (!addr) {
+ g_strfreev (list);
+ goto error;
+ }
+
+ if (!nm_setting_ip6_config_add_address (s_ip6, addr))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 address");
+ nm_ip6_address_unref (addr);
+ }
+ g_strfreev (list);
+ } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ /* TODO - autoconf or DHCPv6 stuff goes here */
+ }
+
+ /* DNS servers
+ * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
+ */
+ for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) {
+ char *tag;
+ struct in6_addr ip6_dns;
+
+ ip6_dns = in6addr_any;
+ tag = g_strdup_printf ("DNS%u", i);
+ value = svGetValue (ifcfg, tag, FALSE);
+ if (value)
+ tmp_success = parse_ip6_address (value, &ip6_dns, error);
+
+ if (!tmp_success) {
+ struct in_addr ip4_addr;
+ if (inet_pton (AF_INET, value, &ip4_addr) != 1) {
+ g_free (tag);
+ g_free (value);
+ goto error;
+ }
+ /* ignore error - it is IPv4 address */
+ tmp_success = TRUE;
+ g_clear_error (error);
+ }
+
+ if (!IN6_IS_ADDR_UNSPECIFIED (&ip6_dns) && !nm_setting_ip6_config_add_dns (s_ip6, &ip6_dns))
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS server %s", tag);
+ g_free (tag);
+ g_free (value);
+ }
+
+ /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */
+
+ /* Read static routes from route6-<interface> file */
+ route6_path = utils_get_route6_path (ifcfg->fileName);
+ if (!route6_path) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not get route6 file path for '%s'", ifcfg->fileName);
+ goto error;
+ }
+
+ read_route6_file (route6_path, s_ip6, error);
+ g_free (route6_path);
+ if (error && *error)
+ goto error;
+
+ return NM_SETTING (s_ip6);
+
+error:
+ g_object_unref (s_ip6);
+ return NULL;
+}
+
+static gboolean
+add_one_wep_key (shvarFile *ifcfg,
+ const char *shvar_key,
+ guint8 key_idx,
+ gboolean passphrase,
+ NMSettingWirelessSecurity *s_wsec,
+ GError **error)
+{
+ char *key = NULL;
+ char *value = NULL;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (ifcfg != NULL, FALSE);
+ g_return_val_if_fail (shvar_key != NULL, FALSE);
+ g_return_val_if_fail (key_idx <= 3, FALSE);
+ g_return_val_if_fail (s_wsec != NULL, FALSE);
+
+ value = svGetValue (ifcfg, shvar_key, FALSE);
+ if (!value || !strlen (value)) {
+ g_free (value);
+ return TRUE;
+ }
+
+ /* Validate keys */
+ if (passphrase) {
+ if (strlen (value) && strlen (value) < 64) {
+ key = g_strdup (value);
+ g_object_set (G_OBJECT (s_wsec),
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
+ NM_WEP_KEY_TYPE_PASSPHRASE,
+ NULL);
+ }
+ } else {
+ if (strlen (value) == 10 || strlen (value) == 26) {
+ /* Hexadecimal WEP key */
+ char *p = value;
+
+ while (*p) {
+ if (!g_ascii_isxdigit (*p)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid hexadecimal WEP key.");
+ goto out;
+ }
+ p++;
+ }
+ key = g_strdup (value);
+ } else if ( !strncmp (value, "s:", 2)
+ && (strlen (value) == 7 || strlen (value) == 15)) {
+ /* ASCII key */
+ char *p = value + 2;
+
+ while (*p) {
+ if (!isascii ((int) (*p))) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid ASCII WEP key.");
+ goto out;
+ }
+ p++;
+ }
+
+ /* Remove 's:' prefix.
+ * Don't convert to hex string. wpa_supplicant takes 'wep_key0' option over D-Bus as byte array
+ * and converts it to hex string itself. Even though we convert hex string keys into a bin string
+ * before passing to wpa_supplicant, this prevents two unnecessary conversions. And mainly,
+ * ASCII WEP key doesn't change to HEX WEP key in UI, which could confuse users.
+ */
+ key = g_strdup (value + 2);
+ }
+ }
+
+ if (key) {
+ nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key);
+ success = TRUE;
+ } else
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid WEP key length.");
+
+out:
+ g_free (value);
+ return success;
+}
+
+static gboolean
+read_wep_keys (shvarFile *ifcfg,
+ guint8 def_idx,
+ NMSettingWirelessSecurity *s_wsec,
+ GError **error)
+{
+ /* Try hex/ascii keys first */
+ if (!add_one_wep_key (ifcfg, "KEY1", 0, FALSE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY2", 1, FALSE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY3", 2, FALSE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY4", 3, FALSE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY", def_idx, FALSE, s_wsec, error))
+ return FALSE;
+
+ /* And then passphrases */
+ if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE1", 0, TRUE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE2", 1, TRUE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE3", 2, TRUE, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ifcfg, "KEY_PASSPHRASE4", 3, TRUE, s_wsec, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+static NMSettingSecretFlags
+read_secret_flags (shvarFile *ifcfg, const char *flags_key)
+{
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+ char *val;
+
+ g_return_val_if_fail (flags_key != NULL, NM_SETTING_SECRET_FLAG_NONE);
+ g_return_val_if_fail (flags_key[0] != '\0', NM_SETTING_SECRET_FLAG_NONE);
+ g_return_val_if_fail (g_str_has_suffix (flags_key, "_FLAGS"), NM_SETTING_SECRET_FLAG_NONE);
+
+ val = svGetValue (ifcfg, flags_key, FALSE);
+ if (val) {
+ if (strstr (val, SECRET_FLAG_AGENT))
+ flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED;
+ if (strstr (val, SECRET_FLAG_NOT_SAVED))
+ flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
+ if (strstr (val, SECRET_FLAG_NOT_REQUIRED))
+ flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED;
+
+ g_free (val);
+ }
+ return flags;
+}
+
+static NMSetting *
+make_wep_setting (shvarFile *ifcfg,
+ const char *file,
+ GError **error)
+{
+ NMSettingWirelessSecurity *s_wsec;
+ char *value;
+ shvarFile *keys_ifcfg = NULL;
+ int default_key_idx = 0;
+ gboolean has_default_key = FALSE, success;
+ NMSettingSecretFlags key_flags;
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL);
+
+ value = svGetValue (ifcfg, "DEFAULTKEY", FALSE);
+ if (value) {
+ success = get_int (value, &default_key_idx);
+ if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) {
+ has_default_key = TRUE;
+ default_key_idx--; /* convert to [0...3] */
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL);
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid default WEP key '%s'", value);
+ g_free (value);
+ goto error;
+ }
+ g_free (value);
+ }
+
+ /* Read WEP key flags */
+ key_flags = read_secret_flags (ifcfg, "WEP_KEY_FLAGS");
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL);
+
+ /* Read keys in the ifcfg file if they are system-owned */
+ if (key_flags == NM_SETTING_SECRET_FLAG_NONE) {
+ if (!read_wep_keys (ifcfg, default_key_idx, s_wsec, error))
+ goto error;
+
+ /* Try to get keys from the "shadow" key file */
+ keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
+ if (keys_ifcfg) {
+ if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wsec, error)) {
+ svCloseFile (keys_ifcfg);
+ goto error;
+ }
+ svCloseFile (keys_ifcfg);
+ g_assert (error == NULL || *error == NULL);
+ }
+ }
+
+ value = svGetValue (ifcfg, "SECURITYMODE", FALSE);
+ if (value) {
+ char *lcase;
+
+ lcase = g_ascii_strdown (value, -1);
+ g_free (value);
+
+ if (!strcmp (lcase, "open")) {
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL);
+ } else if (!strcmp (lcase, "restricted")) {
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", NULL);
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid WEP authentication algorithm '%s'",
+ lcase);
+ g_free (lcase);
+ goto error;
+ }
+ g_free (lcase);
+ }
+
+ /* If no WEP keys were given, and the keys are not agent-owned, and no
+ * default WEP key index was given, then the connection is unencrypted.
+ */
+ if ( !nm_setting_wireless_security_get_wep_key (s_wsec, 0)
+ && !nm_setting_wireless_security_get_wep_key (s_wsec, 1)
+ && !nm_setting_wireless_security_get_wep_key (s_wsec, 2)
+ && !nm_setting_wireless_security_get_wep_key (s_wsec, 3)
+ && (has_default_key == FALSE)
+ && (key_flags == NM_SETTING_SECRET_FLAG_NONE)) {
+ const char *auth_alg;
+
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ if (auth_alg && !strcmp (auth_alg, "shared")) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "WEP Shared Key authentication is invalid for "
+ "unencrypted connections.");
+ goto error;
+ }
+
+ /* Unencrypted */
+ g_object_unref (s_wsec);
+ s_wsec = NULL;
+ }
+
+ return (NMSetting *) s_wsec;
+
+error:
+ if (s_wsec)
+ g_object_unref (s_wsec);
+ return NULL;
+}
+
+static gboolean
+fill_wpa_ciphers (shvarFile *ifcfg,
+ NMSettingWirelessSecurity *wsec,
+ gboolean group,
+ gboolean adhoc)
+{
+ char *value = NULL, *p;
+ char **list = NULL, **iter;
+ int i = 0;
+
+ p = value = svGetValue (ifcfg, group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE", TRUE);
+ if (!value)
+ return TRUE;
+
+ /* Strip quotes */
+ if (p[0] == '"')
+ p++;
+ if (p[strlen (p) - 1] == '"')
+ p[strlen (p) - 1] = '\0';
+
+ list = g_strsplit_set (p, " ", 0);
+ for (iter = list; iter && *iter; iter++, i++) {
+ /* Ad-Hoc configurations cannot have pairwise ciphers, and can only
+ * have one group cipher. Ignore any additional group ciphers and
+ * any pairwise ciphers specified.
+ */
+ if (adhoc) {
+ if (group && (i > 0)) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)",
+ *iter);
+ continue;
+ } else if (!group) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)",
+ *iter);
+ continue;
+ }
+ }
+
+ if (!strcmp (*iter, "CCMP")) {
+ if (group)
+ nm_setting_wireless_security_add_group (wsec, "ccmp");
+ else
+ nm_setting_wireless_security_add_pairwise (wsec, "ccmp");
+ } else if (!strcmp (*iter, "TKIP")) {
+ if (group)
+ nm_setting_wireless_security_add_group (wsec, "tkip");
+ else
+ nm_setting_wireless_security_add_pairwise (wsec, "tkip");
+ } else if (group && !strcmp (*iter, "WEP104"))
+ nm_setting_wireless_security_add_group (wsec, "wep104");
+ else if (group && !strcmp (*iter, "WEP40"))
+ nm_setting_wireless_security_add_group (wsec, "wep40");
+ else {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring invalid %s cipher '%s'",
+ group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE",
+ *iter);
+ }
+ }
+
+ if (list)
+ g_strfreev (list);
+ g_free (value);
+ return TRUE;
+}
+
+#define WPA_PMK_LEN 32
+
+static char *
+parse_wpa_psk (shvarFile *ifcfg,
+ const char *file,
+ const GByteArray *ssid,
+ GError **error)
+{
+ shvarFile *keys_ifcfg;
+ char *psk = NULL, *p, *hashed = NULL;
+ gboolean quoted = FALSE;
+
+ /* Passphrase must be between 10 and 66 characters in length because WPA
+ * hex keys are exactly 64 characters (no quoting), and WPA passphrases
+ * are between 8 and 63 characters (inclusive), plus optional quoting if
+ * the passphrase contains spaces.
+ */
+
+ /* Try to get keys from the "shadow" key file */
+ keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
+ if (keys_ifcfg) {
+ psk = svGetValue (keys_ifcfg, "WPA_PSK", TRUE);
+ svCloseFile (keys_ifcfg);
+ }
+
+ /* Fall back to the original ifcfg */
+ if (!psk)
+ psk = svGetValue (ifcfg, "WPA_PSK", TRUE);
+
+ if (!psk)
+ return NULL;
+
+ p = psk;
+
+ if (p[0] == '"' && psk[strlen (psk) - 1] == '"')
+ quoted = TRUE;
+
+ if (!quoted && (strlen (psk) == 64)) {
+ /* Verify the hex PSK; 64 digits */
+ while (*p) {
+ if (!isxdigit (*p++)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid WPA_PSK (contains non-hexadecimal characters)");
+ goto out;
+ }
+ }
+ hashed = g_strdup (psk);
+ } else {
+ /* Prior to 4f6eef9e77265484555663cf666cde4fa8323469 and
+ * 28e2e446868b94b92edc4a82aa0bf1e3eda8ec54 the writer may not have
+ * properly quoted passphrases, so just handle anything that's unquoted
+ * and between 8 and 63 characters as a passphrase.
+ */
+
+ if (quoted) {
+ /* Get rid of the quotes */
+ p++;
+ p[strlen (p) - 1] = '\0';
+ }
+
+ /* Length check */
+ if (strlen (p) < 8 || strlen (p) > 63) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid WPA_PSK (passphrases must be between "
+ "8 and 63 characters long (inclusive))");
+ goto out;
+ }
+
+ hashed = g_strdup (p);
+ }
+
+ if (!hashed) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid WPA_PSK (doesn't look like a passphrase or hex key)");
+ goto out;
+ }
+
+out:
+ g_free (psk);
+ return hashed;
+}
+
+static gboolean
+eap_simple_reader (const char *eap_method,
+ shvarFile *ifcfg,
+ shvarFile *keys,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ NMSettingSecretFlags flags;
+ char *value;
+
+ value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
+ if (!value) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
+ g_free (value);
+
+ flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS");
+ g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL);
+
+ /* Only read the password if it's system-owned */
+ if (flags == NM_SETTING_SECRET_FLAG_NONE) {
+ value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE);
+ if (!value && keys) {
+ /* Try the lookaside keys file */
+ value = svGetValue (keys, "IEEE_8021X_PASSWORD", FALSE);
+ }
+
+ if (!value) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_PASSWORD for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+
+ g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL);
+ g_free (value);
+ }
+
+ return TRUE;
+}
+
+static char *
+get_cert_file (const char *ifcfg_path, const char *cert_path)
+{
+ const char *base = cert_path;
+ char *p, *ret, *dirname;
+
+ g_return_val_if_fail (ifcfg_path != NULL, NULL);
+ g_return_val_if_fail (cert_path != NULL, NULL);
+
+ if (cert_path[0] == '/')
+ return g_strdup (cert_path);
+
+ p = strrchr (cert_path, '/');
+ if (p)
+ base = p + 1;
+
+ dirname = g_path_get_dirname (ifcfg_path);
+ ret = g_build_path ("/", dirname, base, NULL);
+ g_free (dirname);
+ return ret;
+}
+
+static gboolean
+eap_tls_reader (const char *eap_method,
+ shvarFile *ifcfg,
+ shvarFile *keys,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ char *value;
+ char *ca_cert = NULL;
+ char *real_path = NULL;
+ char *client_cert = NULL;
+ char *privkey = NULL;
+ char *privkey_password = NULL;
+ gboolean success = FALSE;
+ NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ const char *ca_cert_key = phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT";
+ const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD";
+ const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY";
+ const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT";
+ const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS": "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS";
+ const char *pk_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS;
+ NMSettingSecretFlags flags;
+
+ value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
+ if (!value) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
+ g_free (value);
+
+ ca_cert = svGetValue (ifcfg, ca_cert_key, FALSE);
+ if (ca_cert) {
+ real_path = get_cert_file (ifcfg->fileName, ca_cert);
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
+ real_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ real_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ }
+ g_free (real_path);
+ real_path = NULL;
+ } else {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing %s for EAP"
+ " method '%s'; this is insecure!",
+ ca_cert_key,
+ eap_method);
+ }
+
+ /* Read and set private key password flags */
+ flags = read_secret_flags (ifcfg, pk_pw_flags_key);
+ g_object_set (s_8021x, pk_pw_flags_prop, flags, NULL);
+
+ /* Read the private key password if it's system-owned */
+ if (flags == NM_SETTING_SECRET_FLAG_NONE) {
+ /* Private key password */
+ privkey_password = svGetValue (ifcfg, pk_pw_key, FALSE);
+ if (!privkey_password && keys) {
+ /* Try the lookaside keys file */
+ privkey_password = svGetValue (keys, pk_pw_key, FALSE);
+ }
+
+ if (!privkey_password) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing %s for EAP method '%s'.",
+ pk_pw_key,
+ eap_method);
+ goto done;
+ }
+ }
+
+ /* The private key itself */
+ privkey = svGetValue (ifcfg, pk_key, FALSE);
+ if (!privkey) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing %s for EAP method '%s'.",
+ pk_key,
+ eap_method);
+ goto done;
+ }
+
+ real_path = get_cert_file (ifcfg->fileName, privkey);
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_private_key (s_8021x,
+ real_path,
+ privkey_password,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ &privkey_format,
+ error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_private_key (s_8021x,
+ real_path,
+ privkey_password,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ &privkey_format,
+ error))
+ goto done;
+ }
+ g_free (real_path);
+ real_path = NULL;
+
+ /* Only set the client certificate if the private key is not PKCS#12 format,
+ * as NM (due to supplicant restrictions) requires. If the key was PKCS#12,
+ * then nm_setting_802_1x_set_private_key() already set the client certificate
+ * to the same value as the private key.
+ */
+ if ( privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY
+ || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) {
+ client_cert = svGetValue (ifcfg, cli_cert_key, FALSE);
+ if (!client_cert) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing %s for EAP method '%s'.",
+ cli_cert_key,
+ eap_method);
+ goto done;
+ }
+
+ real_path = get_cert_file (ifcfg->fileName, client_cert);
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x,
+ real_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_client_cert (s_8021x,
+ real_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ }
+ g_free (real_path);
+ real_path = NULL;
+ }
+
+ success = TRUE;
+
+done:
+ g_free (real_path);
+ g_free (ca_cert);
+ g_free (client_cert);
+ g_free (privkey);
+ g_free (privkey_password);
+ return success;
+}
+
+static gboolean
+eap_peap_reader (const char *eap_method,
+ shvarFile *ifcfg,
+ shvarFile *keys,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ char *ca_cert = NULL;
+ char *real_cert_path = NULL;
+ char *inner_auth = NULL;
+ char *peapver = NULL;
+ char *lower;
+ char **list = NULL, **iter;
+ gboolean success = FALSE;
+
+ ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
+ if (ca_cert) {
+ real_cert_path = get_cert_file (ifcfg->fileName, ca_cert);
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ real_cert_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ } else {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing "
+ "IEEE_8021X_CA_CERT for EAP method '%s'; this is"
+ " insecure!",
+ eap_method);
+ }
+
+ peapver = svGetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", FALSE);
+ if (peapver) {
+ if (!strcmp (peapver, "0"))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL);
+ else if (!strcmp (peapver, "1"))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL);
+ else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown IEEE_8021X_PEAP_VERSION value '%s'",
+ peapver);
+ goto done;
+ }
+ }
+
+ if (svTrueValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", FALSE))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1", NULL);
+
+ inner_auth = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
+ if (!inner_auth) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+ goto done;
+ }
+
+ /* Handle options for the inner auth method */
+ list = g_strsplit (inner_auth, " ", 0);
+ for (iter = list; iter && *iter; iter++) {
+ if (!strlen (*iter))
+ continue;
+
+ if ( !strcmp (*iter, "MSCHAPV2")
+ || !strcmp (*iter, "MD5")
+ || !strcmp (*iter, "GTC")) {
+ if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+ goto done;
+ } else if (!strcmp (*iter, "TLS")) {
+ if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+ goto done;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
+ *iter);
+ goto done;
+ }
+
+ lower = g_ascii_strdown (*iter, -1);
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower, NULL);
+ g_free (lower);
+ break;
+ }
+
+ if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "No valid IEEE_8021X_INNER_AUTH_METHODS found.");
+ goto done;
+ }
+
+ success = TRUE;
+
+done:
+ if (list)
+ g_strfreev (list);
+ g_free (inner_auth);
+ g_free (peapver);
+ g_free (real_cert_path);
+ g_free (ca_cert);
+ return success;
+}
+
+static gboolean
+eap_ttls_reader (const char *eap_method,
+ shvarFile *ifcfg,
+ shvarFile *keys,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ gboolean success = FALSE;
+ char *anon_ident = NULL;
+ char *ca_cert = NULL;
+ char *real_cert_path = NULL;
+ char *inner_auth = NULL;
+ char *tmp;
+ char **list = NULL, **iter;
+
+ ca_cert = svGetValue (ifcfg, "IEEE_8021X_CA_CERT", FALSE);
+ if (ca_cert) {
+ real_cert_path = get_cert_file (ifcfg->fileName, ca_cert);
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ real_cert_path,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ } else {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: missing "
+ "IEEE_8021X_CA_CERT for EAP method '%s'; this is"
+ " insecure!",
+ eap_method);
+ }
+
+ anon_ident = svGetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY", FALSE);
+ if (anon_ident && strlen (anon_ident))
+ g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, anon_ident, NULL);
+
+ tmp = svGetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", FALSE);
+ if (!tmp) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+ goto done;
+ }
+
+ inner_auth = g_ascii_strdown (tmp, -1);
+ g_free (tmp);
+
+ /* Handle options for the inner auth method */
+ list = g_strsplit (inner_auth, " ", 0);
+ for (iter = list; iter && *iter; iter++) {
+ if (!strlen (*iter))
+ continue;
+
+ if ( !strcmp (*iter, "mschapv2")
+ || !strcmp (*iter, "mschap")
+ || !strcmp (*iter, "pap")
+ || !strcmp (*iter, "chap")) {
+ if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+ goto done;
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL);
+ } else if (!strcmp (*iter, "eap-tls")) {
+ if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+ goto done;
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL);
+ } else if (!strcmp (*iter, "eap-mschapv2") || !strcmp (*iter, "eap-md5")) {
+ if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error))
+ goto done;
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + strlen ("eap-")), NULL);
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
+ *iter);
+ goto done;
+ }
+ break;
+ }
+
+ success = TRUE;
+
+done:
+ if (list)
+ g_strfreev (list);
+ g_free (inner_auth);
+ g_free (real_cert_path);
+ g_free (ca_cert);
+ g_free (anon_ident);
+ return success;
+}
+
+typedef struct {
+ const char *method;
+ gboolean (*reader)(const char *eap_method,
+ shvarFile *ifcfg,
+ shvarFile *keys,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+ gboolean wifi_phase2_only;
+} EAPReader;
+
+static EAPReader eap_readers[] = {
+ { "md5", eap_simple_reader, TRUE },
+ { "pap", eap_simple_reader, TRUE },
+ { "chap", eap_simple_reader, TRUE },
+ { "mschap", eap_simple_reader, TRUE },
+ { "mschapv2", eap_simple_reader, TRUE },
+ { "leap", eap_simple_reader, FALSE },
+ { "tls", eap_tls_reader, FALSE },
+ { "peap", eap_peap_reader, FALSE },
+ { "ttls", eap_ttls_reader, FALSE },
+ { NULL, NULL }
+};
+
+static NMSetting8021x *
+fill_8021x (shvarFile *ifcfg,
+ const char *file,
+ const char *key_mgmt,
+ gboolean wifi,
+ GError **error)
+{
+ NMSetting8021x *s_8021x;
+ shvarFile *keys = NULL;
+ char *value;
+ char **list, **iter;
+
+ value = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE);
+ if (!value) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing IEEE_8021X_EAP_METHODS for key management '%s'",
+ key_mgmt);
+ return NULL;
+ }
+
+ list = g_strsplit (value, " ", 0);
+ g_free (value);
+
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+
+ /* Read in the lookaside keys file, if present */
+ keys = utils_get_keys_ifcfg (file, FALSE);
+
+ /* Validate and handle each EAP method */
+ for (iter = list; iter && *iter; iter++) {
+ EAPReader *eap = &eap_readers[0];
+ gboolean found = FALSE;
+ char *lower = NULL;
+
+ lower = g_ascii_strdown (*iter, -1);
+ while (eap->method && !found) {
+ if (strcmp (eap->method, lower))
+ goto next;
+
+ /* Some EAP methods don't provide keying material, thus they
+ * cannot be used with WiFi unless they are an inner method
+ * used with TTLS or PEAP or whatever.
+ */
+ if (wifi && eap->wifi_phase2_only) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignored invalid "
+ "IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.",
+ lower);
+ goto next;
+ }
+
+ /* Parse EAP method specific options */
+ if (!(*eap->reader)(lower, ifcfg, keys, s_8021x, FALSE, error)) {
+ g_free (lower);
+ goto error;
+ }
+ nm_setting_802_1x_add_eap_method (s_8021x, lower);
+ found = TRUE;
+
+ next:
+ eap++;
+ }
+
+ if (!found) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignored unknown"
+ "IEEE_8021X_EAP_METHOD '%s'.",
+ lower);
+ }
+ g_free (lower);
+ }
+ g_strfreev (list);
+
+ if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "No valid EAP methods found in IEEE_8021X_EAP_METHODS.");
+ goto error;
+ }
+
+ if (keys)
+ svCloseFile (keys);
+ return s_8021x;
+
+error:
+ if (keys)
+ svCloseFile (keys);
+ g_object_unref (s_8021x);
+ return NULL;
+}
+
+static NMSetting *
+make_wpa_setting (shvarFile *ifcfg,
+ const char *file,
+ const GByteArray *ssid,
+ gboolean adhoc,
+ NMSetting8021x **s_8021x,
+ GError **error)
+{
+ NMSettingWirelessSecurity *wsec;
+ char *value, *psk, *lower;
+ gboolean wpa_psk = FALSE, wpa_eap = FALSE, ieee8021x = FALSE;
+
+ wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+
+ value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
+ wpa_psk = !g_strcmp0 (value, "WPA-PSK");
+ wpa_eap = !g_strcmp0 (value, "WPA-EAP");
+ ieee8021x = !g_strcmp0 (value, "IEEE8021X");
+ if (!wpa_psk && !wpa_eap && !ieee8021x)
+ goto error; /* Not WPA or Dynamic WEP */
+
+ /* Pairwise and Group ciphers (only relevant for WPA/RSN) */
+ if (wpa_psk || wpa_eap) {
+ fill_wpa_ciphers (ifcfg, wsec, FALSE, adhoc);
+ fill_wpa_ciphers (ifcfg, wsec, TRUE, adhoc);
+ }
+
+ /* WPA and/or RSN */
+ if (adhoc) {
+ /* Ad-Hoc mode only supports WPA proto for now */
+ nm_setting_wireless_security_add_proto (wsec, "wpa");
+ } else {
+ char *allow_wpa, *allow_rsn;
+
+ allow_wpa = svGetValue (ifcfg, "WPA_ALLOW_WPA", FALSE);
+ allow_rsn = svGetValue (ifcfg, "WPA_ALLOW_WPA2", FALSE);
+
+ if (allow_wpa && svTrueValue (ifcfg, "WPA_ALLOW_WPA", TRUE))
+ nm_setting_wireless_security_add_proto (wsec, "wpa");
+ if (allow_rsn && svTrueValue (ifcfg, "WPA_ALLOW_WPA2", TRUE))
+ nm_setting_wireless_security_add_proto (wsec, "rsn");
+
+ /* If neither WPA_ALLOW_WPA or WPA_ALLOW_WPA2 were present, default
+ * to both WPA and RSN allowed.
+ */
+ if (!allow_wpa && !allow_rsn && !ieee8021x) {
+ nm_setting_wireless_security_add_proto (wsec, "wpa");
+ nm_setting_wireless_security_add_proto (wsec, "rsn");
+ }
+
+ g_free (allow_wpa);
+ g_free (allow_rsn);
+ }
+
+ if (!strcmp (value, "WPA-PSK")) {
+ NMSettingSecretFlags psk_flags;
+
+ psk_flags = read_secret_flags (ifcfg, "WPA_PSK_FLAGS");
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL);
+
+ /* Read PSK if it's system-owned */
+ if (psk_flags == NM_SETTING_SECRET_FLAG_NONE) {
+ psk = parse_wpa_psk (ifcfg, file, ssid, error);
+ if (psk) {
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL);
+ g_free (psk);
+ }
+ }
+
+ if (adhoc)
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL);
+ else
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
+ } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) {
+ /* Adhoc mode is mutually exclusive with any 802.1x-based authentication */
+ if (adhoc) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'", value);
+ goto error;
+ }
+
+ *s_8021x = fill_8021x (ifcfg, file, value, TRUE, error);
+ if (!*s_8021x)
+ goto error;
+
+ lower = g_ascii_strdown (value, -1);
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, lower, NULL);
+ g_free (lower);
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown wireless KEY_MGMT type '%s'", value);
+ goto error;
+ }
+
+ g_free (value);
+ return (NMSetting *) wsec;
+
+error:
+ g_free (value);
+ if (wsec)
+ g_object_unref (wsec);
+ return NULL;
+}
+
+static NMSetting *
+make_leap_setting (shvarFile *ifcfg,
+ const char *file,
+ GError **error)
+{
+ NMSettingWirelessSecurity *wsec;
+ shvarFile *keys_ifcfg;
+ char *value;
+ NMSettingSecretFlags flags;
+
+ wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+
+ value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
+ if (!value || strcmp (value, "IEEE8021X"))
+ goto error; /* Not LEAP */
+
+ g_free (value);
+ value = svGetValue (ifcfg, "SECURITYMODE", FALSE);
+ if (!value || strcasecmp (value, "leap"))
+ goto error; /* Not LEAP */
+
+ g_free (value);
+
+ flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS");
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL);
+
+ /* Read LEAP password if it's system-owned */
+ if (flags == NM_SETTING_SECRET_FLAG_NONE) {
+ value = svGetValue (ifcfg, "IEEE_8021X_PASSWORD", FALSE);
+ if (!value) {
+ /* Try to get keys from the "shadow" key file */
+ keys_ifcfg = utils_get_keys_ifcfg (file, FALSE);
+ if (keys_ifcfg) {
+ value = svGetValue (keys_ifcfg, "IEEE_8021X_PASSWORD", FALSE);
+ svCloseFile (keys_ifcfg);
+ }
+ }
+ if (value && strlen (value))
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, value, NULL);
+ g_free (value);
+ }
+
+ value = svGetValue (ifcfg, "IEEE_8021X_IDENTITY", FALSE);
+ if (!value || !strlen (value)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing LEAP identity");
+ goto error;
+ }
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value, NULL);
+ g_free (value);
+
+ g_object_set (wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
+ NULL);
+
+ return (NMSetting *) wsec;
+
+error:
+ g_free (value);
+ if (wsec)
+ g_object_unref (wsec);
+ return NULL;
+}
+
+static NMSetting *
+make_wireless_security_setting (shvarFile *ifcfg,
+ const char *file,
+ const GByteArray *ssid,
+ gboolean adhoc,
+ NMSetting8021x **s_8021x,
+ GError **error)
+{
+ NMSetting *wsec;
+
+ if (!adhoc) {
+ wsec = make_leap_setting (ifcfg, file, error);
+ if (wsec)
+ return wsec;
+ else if (*error)
+ return NULL;
+ }
+
+ wsec = make_wpa_setting (ifcfg, file, ssid, adhoc, s_8021x, error);
+ if (wsec)
+ return wsec;
+ else if (*error)
+ return NULL;
+
+ wsec = make_wep_setting (ifcfg, file, error);
+ if (wsec)
+ return wsec;
+ else if (*error)
+ return NULL;
+
+ return NULL; /* unencrypted */
+}
+
+static NMSetting *
+make_wireless_setting (shvarFile *ifcfg,
+ gboolean nm_controlled,
+ char **unmanaged,
+ GError **error)
+{
+ NMSettingWireless *s_wireless;
+ GByteArray *array = NULL;
+ char *value;
+
+ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+
+ if (read_mac_address (ifcfg, "HWADDR", &array, error)) {
+ if (array) {
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL);
+
+ /* A connection can only be unmanaged if we know the MAC address */
+ if (!nm_controlled) {
+ *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x",
+ array->data[0], array->data[1], array->data[2],
+ array->data[3], array->data[4], array->data[5]);
+ }
+
+ g_byte_array_free (array, TRUE);
+ } else if (!nm_controlled) {
+ /* If NM_CONTROLLED=no but there wasn't a MAC address, notify
+ * the user that the device cannot be unmanaged.
+ */
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR was missing; device will be managed");
+ }
+ } else {
+ g_object_unref (s_wireless);
+ return NULL;
+ }
+
+ array = NULL;
+ if (read_mac_address (ifcfg, "MACADDR", &array, error)) {
+ if (array) {
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL);
+ g_byte_array_free (array, TRUE);
+ }
+ }
+
+ value = svGetValue (ifcfg, "ESSID", TRUE);
+ if (value) {
+ gsize ssid_len = 0, value_len = strlen (value);
+ char *p = value, *tmp;
+ char buf[33];
+
+ ssid_len = value_len;
+ if ( (value_len >= 2)
+ && (value[0] == '"')
+ && (value[value_len - 1] == '"')) {
+ /* Strip the quotes and unescape */
+ p = value + 1;
+ value[value_len - 1] = '\0';
+ svUnescape (p);
+ ssid_len = strlen (p);
+ } else if ((value_len > 2) && (strncmp (value, "0x", 2) == 0)) {
+ /* Hex representation */
+ if (value_len % 2) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid SSID '%s' size (looks like hex but length not multiple of 2)",
+ value);
+ g_free (value);
+ goto error;
+ }
+
+ p = value + 2;
+ while (*p) {
+ if (!isxdigit (*p)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)",
+ value, *p);
+ g_free (value);
+ goto error;
+ }
+ p++;
+ }
+
+ tmp = utils_hexstr2bin (value + 2, value_len - 2);
+ ssid_len = (value_len - 2) / 2;
+ memcpy (buf, tmp, ssid_len);
+ p = &buf[0];
+ }
+
+ if (ssid_len > 32 || ssid_len == 0) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)",
+ value, ssid_len);
+ g_free (value);
+ goto error;
+ }
+
+ array = g_byte_array_sized_new (ssid_len);
+ g_byte_array_append (array, (const guint8 *) p, ssid_len);
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, array, NULL);
+ g_byte_array_free (array, TRUE);
+ g_free (value);
+ } else {
+ /* Only fail on lack of SSID if device is managed */
+ if (nm_controlled) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Missing SSID");
+ goto error;
+ }
+ }
+
+ if (!nm_controlled)
+ goto done;
+
+ value = svGetValue (ifcfg, "MODE", FALSE);
+ if (value) {
+ char *lcase;
+ const char *mode = NULL;
+
+ lcase = g_ascii_strdown (value, -1);
+ g_free (value);
+
+ if (!strcmp (lcase, "ad-hoc")) {
+ mode = "adhoc";
+ } else if (!strcmp (lcase, "managed") || !strcmp (lcase, "auto")) {
+ mode = "infrastructure";
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid mode '%s' (not 'Ad-Hoc', 'Managed', or 'Auto')",
+ lcase);
+ g_free (lcase);
+ goto error;
+ }
+ g_free (lcase);
+
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, mode, NULL);
+ }
+
+ value = svGetValue (ifcfg, "BSSID", FALSE);
+ if (value) {
+ struct ether_addr *eth;
+ GByteArray *bssid;
+
+ eth = ether_aton (value);
+ if (!eth) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid BSSID '%s'", value);
+ goto error;
+ }
+
+ bssid = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN);
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL);
+ g_byte_array_free (bssid, TRUE);
+ }
+
+ value = svGetValue (ifcfg, "CHANNEL", FALSE);
+ if (value) {
+ long int chan;
+
+ errno = 0;
+ chan = strtol (value, NULL, 10);
+ if (errno || chan <= 0 || chan > 196) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid wireless channel '%s'", value);
+ g_free (value);
+ goto error;
+ }
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_CHANNEL, (guint32) chan, NULL);
+ if (chan > 14)
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL);
+ else
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL);
+ }
+
+ value = svGetValue (ifcfg, "MTU", FALSE);
+ if (value) {
+ long int mtu;
+
+ errno = 0;
+ mtu = strtol (value, NULL, 10);
+ if (errno || mtu < 0 || mtu > 50000) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid wireless MTU '%s'", value);
+ g_free (value);
+ goto error;
+ }
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MTU, (guint32) mtu, NULL);
+ }
+
+done:
+ return NM_SETTING (s_wireless);
+
+error:
+ if (s_wireless)
+ g_object_unref (s_wireless);
+ return NULL;
+}
+
+static NMConnection *
+wireless_connection_from_ifcfg (const char *file,
+ shvarFile *ifcfg,
+ gboolean nm_controlled,
+ char **unmanaged,
+ GError **error)
+{
+ NMConnection *connection = NULL;
+ NMSetting *con_setting = NULL;
+ NMSetting *wireless_setting = NULL;
+ NMSetting8021x *s_8021x = NULL;
+ const GByteArray *ssid;
+ NMSetting *security_setting = NULL;
+ char *printable_ssid = NULL;
+ const char *mode;
+ gboolean adhoc = FALSE;
+
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (ifcfg != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (*error == NULL, NULL);
+
+ connection = nm_connection_new ();
+ if (!connection) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to allocate new connection for %s.", file);
+ return NULL;
+ }
+
+ /* Wireless */
+ wireless_setting = make_wireless_setting (ifcfg, nm_controlled, unmanaged, error);
+ if (!wireless_setting) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ nm_connection_add_setting (connection, wireless_setting);
+
+ ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting));
+ if (ssid)
+ printable_ssid = nm_utils_ssid_to_utf8 (ssid);
+ else
+ printable_ssid = g_strdup_printf ("unmanaged");
+
+ if (nm_controlled) {
+ mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting));
+ if (mode && !strcmp (mode, "adhoc"))
+ adhoc = TRUE;
+
+ /* Wireless security */
+ security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, error);
+ if (*error) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ if (security_setting) {
+ nm_connection_add_setting (connection, security_setting);
+ if (s_8021x)
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_SEC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+ }
+ }
+
+ /* Connection */
+ con_setting = make_connection_setting (file, ifcfg,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ printable_ssid);
+ g_free (printable_ssid);
+ if (!con_setting) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to create connection setting.");
+ g_object_unref (connection);
+ return NULL;
+ }
+ nm_connection_add_setting (connection, con_setting);
+
+ /* Don't verify if unmanaged since we may not have an SSID or whatever */
+ if (nm_controlled) {
+ if (!nm_connection_verify (connection, error)) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ }
+
+ return connection;
+}
+
+static NMSetting *
+make_wired_setting (shvarFile *ifcfg,
+ const char *file,
+ gboolean nm_controlled,
+ char **unmanaged,
+ NMSetting8021x **s_8021x,
+ GError **error)
+{
+ NMSettingWired *s_wired;
+ char *value = NULL;
+ int mtu;
+ GByteArray *mac = NULL;
+ char *nettype;
+
+ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
+
+ value = svGetValue (ifcfg, "MTU", FALSE);
+ if (value) {
+ if (get_int (value, &mtu)) {
+ if (mtu >= 0 && mtu < 65536)
+ g_object_set (s_wired, NM_SETTING_WIRED_MTU, mtu, NULL);
+ } else {
+ /* Shouldn't be fatal... */
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid MTU '%s'", value);
+ }
+ g_free (value);
+ }
+
+ if (read_mac_address (ifcfg, "HWADDR", &mac, error)) {
+ if (mac) {
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
+
+ /* A connection can only be unmanaged if we know the MAC address */
+ if (!nm_controlled) {
+ *unmanaged = g_strdup_printf ("mac:%02x:%02x:%02x:%02x:%02x:%02x",
+ mac->data[0], mac->data[1], mac->data[2],
+ mac->data[3], mac->data[4], mac->data[5]);
+ }
+
+ g_byte_array_free (mac, TRUE);
+ }
+ } else {
+ g_object_unref (s_wired);
+ return NULL;
+ }
+
+ value = svGetValue (ifcfg, "SUBCHANNELS", FALSE);
+ if (value) {
+ const char *p = value;
+ gboolean success = TRUE;
+ char **chans = NULL;
+
+ /* basic sanity checks */
+ while (*p) {
+ if (!isxdigit (*p) && (*p != ',') && (*p != '.')) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s'", value);
+ success = FALSE;
+ break;
+ }
+ p++;
+ }
+
+ if (success) {
+ guint32 num_chans;
+
+ chans = g_strsplit_set (value, ",", 0);
+ num_chans = g_strv_length (chans);
+ if (num_chans < 2 || num_chans > 3) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid SUBCHANNELS '%s' (%d channels, 2 or 3 expected)",
+ value, g_strv_length (chans));
+ } else {
+ GPtrArray *array = g_ptr_array_sized_new (num_chans);
+
+ g_ptr_array_add (array, chans[0]);
+ g_ptr_array_add (array, chans[1]);
+ if (num_chans == 3)
+ g_ptr_array_add (array, chans[2]);
+
+ g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, array, NULL);
+ g_ptr_array_free (array, TRUE);
+
+ /* set the unmanaged spec too */
+ if (!nm_controlled && !*unmanaged)
+ *unmanaged = g_strdup_printf ("s390-subchannels:%s", value);
+ }
+ g_strfreev (chans);
+ }
+ g_free (value);
+ }
+
+ value = svGetValue (ifcfg, "PORTNAME", FALSE);
+ if (value && strlen (value)) {
+ nm_setting_wired_add_s390_option (s_wired, "portname", value);
+ }
+ g_free (value);
+
+ nettype = svGetValue (ifcfg, "NETTYPE", FALSE);
+ if (nettype && strlen (nettype)) {
+ if (!strcmp (nettype, "qeth") || !strcmp (nettype, "lcs") || !strcmp (nettype, "ctc"))
+ g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, nettype, NULL);
+ else
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: unknown s390 NETTYPE '%s'", nettype);
+ }
+
+ value = svGetValue (ifcfg, "OPTIONS", FALSE);
+ if (value && strlen (value)) {
+ char **options, **iter;
+
+ iter = options = g_strsplit_set (value, " ", 0);
+ while (iter && *iter) {
+ char *equals = strchr (*iter, '=');
+ gboolean valid = FALSE;
+
+ if (equals) {
+ *equals = '\0';
+ valid = nm_setting_wired_add_s390_option (s_wired, *iter, equals + 1);
+ }
+ if (!valid)
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid s390 OPTION '%s'", *iter);
+ iter++;
+ }
+ g_strfreev (options);
+ }
+ g_free (value);
+
+ g_free (nettype);
+
+ if (!nm_controlled && !*unmanaged) {
+ /* If NM_CONTROLLED=no but there wasn't a MAC address or z/VM
+ * subchannels, notify the user that the device cannot be unmanaged.
+ */
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: NM_CONTROLLED was false but HWADDR or SUBCHANNELS was missing; device will be managed");
+ }
+
+ mac = NULL;
+ if (read_mac_address (ifcfg, "MACADDR", &mac, error)) {
+ if (mac) {
+ g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL);
+ g_byte_array_free (mac, TRUE);
+ }
+ }
+
+ value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
+ if (value) {
+ if (!strcmp (value, "IEEE8021X")) {
+ *s_8021x = fill_8021x (ifcfg, file, value, FALSE, error);
+ if (!*s_8021x)
+ goto error;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown wired KEY_MGMT type '%s'", value);
+ goto error;
+ }
+ g_free (value);
+ }
+
+ return (NMSetting *) s_wired;
+
+error:
+ g_free (value);
+ g_object_unref (s_wired);
+ return NULL;
+}
+
+static NMConnection *
+wired_connection_from_ifcfg (const char *file,
+ shvarFile *ifcfg,
+ gboolean nm_controlled,
+ char **unmanaged,
+ GError **error)
+{
+ NMConnection *connection = NULL;
+ NMSetting *con_setting = NULL;
+ NMSetting *wired_setting = NULL;
+ NMSetting8021x *s_8021x = NULL;
+
+ g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (ifcfg != NULL, NULL);
+
+ connection = nm_connection_new ();
+ if (!connection) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to allocate new connection for %s.", file);
+ return NULL;
+ }
+
+ con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRED_SETTING_NAME, NULL);
+ if (!con_setting) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to create connection setting.");
+ g_object_unref (connection);
+ return NULL;
+ }
+ nm_connection_add_setting (connection, con_setting);
+
+ wired_setting = make_wired_setting (ifcfg, file, nm_controlled, unmanaged, &s_8021x, error);
+ if (!wired_setting) {
+ g_object_unref (connection);
+ return NULL;
+ }
+ nm_connection_add_setting (connection, wired_setting);
+
+ if (s_8021x)
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ if (!nm_connection_verify (connection, error)) {
+ g_object_unref (connection);
+ return NULL;
+ }
+
+ return connection;
+}
+
+static gboolean
+is_wireless_device (const char *iface)
+{
+ int fd;
+ struct iw_range range;
+ struct iwreq wrq;
+ gboolean is_wireless = FALSE;
+
+ g_return_val_if_fail (iface != NULL, FALSE);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (!fd)
+ return FALSE;
+
+ memset (&wrq, 0, sizeof (struct iwreq));
+ memset (&range, 0, sizeof (struct iw_range));
+ strncpy (wrq.ifr_name, iface, IFNAMSIZ);
+ wrq.u.data.pointer = (caddr_t) &range;
+ wrq.u.data.length = sizeof (struct iw_range);
+
+ if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0)
+ is_wireless = TRUE;
+ else {
+ if (errno == EOPNOTSUPP)
+ is_wireless = FALSE;
+ else {
+ /* Sigh... some wired devices (kvm/qemu) return EINVAL when the
+ * device is down even though it's not a wireless device. So try
+ * IWNAME as a fallback.
+ */
+ memset (&wrq, 0, sizeof (struct iwreq));
+ strncpy (wrq.ifr_name, iface, IFNAMSIZ);
+ if (ioctl (fd, SIOCGIWNAME, &wrq) == 0)
+ is_wireless = TRUE;
+ }
+ }
+
+ close (fd);
+ return is_wireless;
+}
+
+enum {
+ IGNORE_REASON_NONE = 0x00,
+ IGNORE_REASON_BRIDGE = 0x01,
+ IGNORE_REASON_VLAN = 0x02,
+};
+
+NMConnection *
+connection_from_file (const char *filename,
+ const char *network_file, /* for unit tests only */
+ const char *test_type, /* for unit tests only */
+ const char *iscsiadm_path, /* for unit tests only */
+ char **unmanaged,
+ char **keyfile,
+ char **routefile,
+ char **route6file,
+ GError **out_error,
+ gboolean *ignore_error)
+{
+ NMConnection *connection = NULL;
+ shvarFile *parsed;
+ char *type, *nmc = NULL, *bootproto, *tmp;
+ NMSetting *s_ip4, *s_ip6;
+ const char *ifcfg_name = NULL;
+ gboolean nm_controlled = TRUE;
+ gboolean ip6_used = FALSE;
+ GError *error = NULL;
+ guint32 ignore_reason = IGNORE_REASON_NONE;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+ g_return_val_if_fail (unmanaged != NULL, NULL);
+ g_return_val_if_fail (*unmanaged == NULL, NULL);
+ g_return_val_if_fail (keyfile != NULL, NULL);
+ g_return_val_if_fail (*keyfile == NULL, NULL);
+ g_return_val_if_fail (routefile != NULL, NULL);
+ g_return_val_if_fail (*routefile == NULL, NULL);
+ g_return_val_if_fail (route6file != NULL, NULL);
+ g_return_val_if_fail (*route6file == NULL, NULL);
+
+ /* Non-NULL only for unit tests; normally use /etc/sysconfig/network */
+ if (!network_file)
+ network_file = SYSCONFDIR "/sysconfig/network";
+
+ if (!iscsiadm_path)
+ iscsiadm_path = SBINDIR "/iscsiadm";
+
+ ifcfg_name = utils_get_ifcfg_name (filename, TRUE);
+ if (!ifcfg_name) {
+ g_set_error (out_error, IFCFG_PLUGIN_ERROR, 0,
+ "Ignoring connection '%s' because it's not an ifcfg file.", filename);
+ return NULL;
+ }
+
+ parsed = svNewFile (filename);
+ if (!parsed) {
+ g_set_error (out_error, IFCFG_PLUGIN_ERROR, 0,
+ "Couldn't parse file '%s'", filename);
+ return NULL;
+ }
+
+ type = svGetValue (parsed, "TYPE", FALSE);
+ if (!type) {
+ char *device;
+
+ /* If no type, if the device has wireless extensions, it's wifi,
+ * otherwise it's ethernet.
+ */
+ device = svGetValue (parsed, "DEVICE", FALSE);
+ if (!device) {
+ g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+ "File '%s' had neither TYPE nor DEVICE keys.", filename);
+ goto done;
+ }
+
+ if (!strcmp (device, "lo")) {
+ if (ignore_error)
+ *ignore_error = TRUE;
+ g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+ "Ignoring loopback device config.");
+ g_free (device);
+ goto done;
+ }
+
+ if (!test_type) {
+ /* Test wireless extensions */
+ if (is_wireless_device (device))
+ type = g_strdup (TYPE_WIRELESS);
+ else
+ type = g_strdup (TYPE_ETHERNET);
+ } else {
+ /* For the unit tests, there won't necessarily be any
+ * adapters of the connection's type in the system so the
+ * type can't be tested with ioctls.
+ */
+ type = g_strdup (test_type);
+ }
+
+ g_free (device);
+ }
+
+ nmc = svGetValue (parsed, "NM_CONTROLLED", FALSE);
+ if (nmc) {
+ char *lower;
+
+ lower = g_ascii_strdown (nmc, -1);
+ g_free (nmc);
+
+ if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false"))
+ nm_controlled = FALSE;
+ g_free (lower);
+ }
+
+ /* Ignore BRIDGE= and VLAN= connections for now too (rh #619863) */
+ tmp = svGetValue (parsed, "BRIDGE", FALSE);
+ if (tmp) {
+ g_free (tmp);
+ nm_controlled = FALSE;
+ ignore_reason = IGNORE_REASON_BRIDGE;
+ }
+
+ if (nm_controlled) {
+ tmp = svGetValue (parsed, "VLAN", FALSE);
+ if (tmp) {
+ g_free (tmp);
+ nm_controlled = FALSE;
+ ignore_reason = IGNORE_REASON_VLAN;
+ }
+ }
+
+ /* Construct the connection */
+ if (!strcasecmp (type, TYPE_ETHERNET))
+ connection = wired_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
+ else if (!strcasecmp (type, TYPE_WIRELESS))
+ connection = wireless_connection_from_ifcfg (filename, parsed, nm_controlled, unmanaged, &error);
+ else if (!strcasecmp (type, TYPE_BRIDGE)) {
+ g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+ "Bridge connections are not yet supported");
+ } else {
+ g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+ "Unknown connection type '%s'", type);
+ }
+
+ if (nm_controlled) {
+ g_free (*unmanaged);
+ *unmanaged = NULL;
+ }
+
+ g_free (type);
+
+ /* Don't bother reading the connection fully if it's unmanaged or ignored */
+ if (!connection || *unmanaged || ignore_reason) {
+ if (connection && !*unmanaged) {
+ /* However,BRIDGE and VLAN connections that don't have HWADDR won't
+ * be unmanaged because the unmanaged state is keyed off HWADDR.
+ * They willl still be tagged 'ignore' from code that checks BRIDGE
+ * and VLAN above. Since they aren't marked unmanaged, kill them
+ * completely.
+ */
+ if (ignore_reason) {
+ g_object_unref (connection);
+ connection = NULL;
+ g_set_error (&error, IFCFG_PLUGIN_ERROR, 0,
+ "%s connections are not yet supported",
+ ignore_reason == IGNORE_REASON_BRIDGE ? "Bridge" : "VLAN");
+ }
+ }
+ goto done;
+ }
+
+ s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, &error);
+ if (error) {
+ g_object_unref (connection);
+ connection = NULL;
+ goto done;
+ } else if (s_ip6) {
+ const char *method;
+
+ nm_connection_add_setting (connection, s_ip6);
+ method = nm_setting_ip6_config_get_method (NM_SETTING_IP6_CONFIG (s_ip6));
+ if (method && strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE))
+ ip6_used = TRUE;
+ }
+
+ s_ip4 = make_ip4_setting (parsed, network_file, iscsiadm_path, ip6_used, &error);
+ if (error) {
+ g_object_unref (connection);
+ connection = NULL;
+ goto done;
+ } else if (s_ip4)
+ nm_connection_add_setting (connection, s_ip4);
+
+ /* iSCSI / ibft connections are read-only since their settings are
+ * stored in NVRAM and can only be changed in BIOS.
+ */
+ bootproto = svGetValue (parsed, "BOOTPROTO", FALSE);
+ if ( bootproto
+ && connection
+ && !g_ascii_strcasecmp (bootproto, "ibft")) {
+ NMSettingConnection *s_con;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_READ_ONLY, TRUE, NULL);
+ }
+
+ if (!nm_connection_verify (connection, &error)) {
+ g_object_unref (connection);
+ connection = NULL;
+ }
+
+ *keyfile = utils_get_keys_path (filename);
+ *routefile = utils_get_route_path (filename);
+ *route6file = utils_get_route6_path (filename);
+
+done:
+ svCloseFile (parsed);
+ if (error && out_error)
+ *out_error = error;
+ else
+ g_clear_error (&error);
+ return connection;
+}
+
+const char *
+reader_get_prefix (void)
+{
+ return _("System");
+}
+
diff --git a/src/system-settings/nm-system-config-error.h b/src/settings/plugins/ifcfg-rh/reader.h
index 63896fcd0..2a031977d 100644
--- a/src/system-settings/nm-system-config-error.h
+++ b/src/settings/plugins/ifcfg-rh/reader.h
@@ -15,31 +15,28 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2008 Novell, Inc.
* Copyright (C) 2008 Red Hat, Inc.
*/
-#ifndef NM_SYSTEM_CONFIG_ERROR_H
-#define NM_SYSTEM_CONFIG_ERROR_H
+#ifndef __READER_H__
+#define __READER_H__
#include <glib.h>
-#include <glib-object.h>
+#include <nm-connection.h>
-enum {
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
- NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED,
- NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
-};
+#include "shvar.h"
-#define NM_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_quark ())
-#define NM_TYPE_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_get_type ())
+NMConnection *connection_from_file (const char *filename,
+ const char *network_file, /* for unit tests only */
+ const char *test_type, /* for unit tests only */
+ const char *iscsiadm_path, /* for unit tests only */
+ char **unmanaged,
+ char **keyfile,
+ char **routefile,
+ char **route6file,
+ GError **error,
+ gboolean *ignore_error);
-GQuark nm_sysconfig_settings_error_quark (void);
-GType nm_sysconfig_settings_error_get_type (void);
+const char *reader_get_prefix (void);
-#endif /* NM_SYSTEM_CONFIG_ERROR_H */
+#endif /* __READER_H__ */
diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c
new file mode 100644
index 000000000..0481e1f6c
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/shvar.c
@@ -0,0 +1,396 @@
+/*
+ * shvar.c
+ *
+ * Implementation of non-destructively reading/writing files containing
+ * only shell variable declarations and full-line comments.
+ *
+ * Includes explicit inheritance mechanism intended for use with
+ * Red Hat Linux ifcfg-* files. There is no protection against
+ * inheritance loops; they will generally cause stack overflows.
+ * Furthermore, they are only intended for one level of inheritance;
+ * the value setting algorithm assumes this.
+ *
+ * Copyright 1999,2000 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "shvar.h"
+
+/* Open the file <name>, returning a shvarFile on success and NULL on failure.
+ Add a wrinkle to let the caller specify whether or not to create the file
+ (actually, return a structure anyway) if it doesn't exist. */
+static shvarFile *
+svOpenFile(const char *name, gboolean create)
+{
+ shvarFile *s = NULL;
+ int closefd = 0;
+
+ s = g_malloc0(sizeof(shvarFile));
+
+ s->fd = -1;
+ if (create)
+ s->fd = open(name, O_RDWR); /* NOT O_CREAT */
+
+ if (!create || s->fd == -1) {
+ /* try read-only */
+ s->fd = open(name, O_RDONLY); /* NOT O_CREAT */
+ if (s->fd != -1) closefd = 1;
+ }
+ s->fileName = g_strdup(name);
+
+ if (s->fd != -1) {
+ struct stat buf;
+ char *p, *q;
+
+ if (fstat(s->fd, &buf) < 0) goto bail;
+ s->arena = g_malloc0(buf.st_size + 1);
+
+ if (read(s->fd, s->arena, buf.st_size) < 0) goto bail;
+
+ /* we'd use g_strsplit() here, but we want a list, not an array */
+ for(p = s->arena; (q = strchr(p, '\n')) != NULL; p = q + 1) {
+ s->lineList = g_list_append(s->lineList, g_strndup(p, q - p));
+ }
+
+ /* closefd is set if we opened the file read-only, so go ahead and
+ close it, because we can't write to it anyway */
+ if (closefd) {
+ close(s->fd);
+ s->fd = -1;
+ }
+
+ return s;
+ }
+
+ if (create) {
+ return s;
+ }
+
+bail:
+ if (s->fd != -1) close(s->fd);
+ g_free (s->arena);
+ g_free (s->fileName);
+ g_free (s);
+ return NULL;
+}
+
+/* Open the file <name>, return shvarFile on success, NULL on failure */
+shvarFile *
+svNewFile(const char *name)
+{
+ return svOpenFile(name, FALSE);
+}
+
+/* Create a new file structure, returning actual data if the file exists,
+ * and a suitable starting point if it doesn't. */
+shvarFile *
+svCreateFile(const char *name)
+{
+ return svOpenFile(name, TRUE);
+}
+
+/* remove escaped characters in place */
+void
+svUnescape(char *s) {
+ int len, i;
+
+ len = strlen(s);
+ if ((s[0] == '"' || s[0] == '\'') && s[0] == s[len-1]) {
+ i = len - 2;
+ if (i == 0)
+ s[0] = '\0';
+ else {
+ memmove(s, s+1, i);
+ s[i+1] = '\0';
+ len = i;
+ }
+ }
+ for (i = 0; i < len; i++) {
+ if (s[i] == '\\') {
+ memmove(s+i, s+i+1, len-(i+1));
+ len--;
+ }
+ s[len] = '\0';
+ }
+}
+
+
+/* create a new string with all necessary characters escaped.
+ * caller must free returned string
+ */
+static const char escapees[] = "\"'\\$~`"; /* must be escaped */
+static const char spaces[] = " \t|&;()<>"; /* only require "" */
+char *
+svEscape(const char *s) {
+ char *new;
+ int i, j, mangle = 0, space = 0;
+ int newlen, slen;
+ static int esclen, splen;
+
+ if (!esclen) esclen = strlen(escapees);
+ if (!splen) splen = strlen(spaces);
+ slen = strlen(s);
+
+ for (i = 0; i < slen; i++) {
+ if (strchr(escapees, s[i])) mangle++;
+ if (strchr(spaces, s[i])) space++;
+ }
+ if (!mangle && !space) return strdup(s);
+
+ newlen = slen + mangle + 3; /* 3 is extra ""\0 */
+ new = g_malloc0(newlen);
+ if (!new) return NULL;
+
+ j = 0;
+ new[j++] = '"';
+ for (i = 0; i < slen; i++) {
+ if (strchr(escapees, s[i])) {
+ new[j++] = '\\';
+ }
+ new[j++] = s[i];
+ }
+ new[j++] = '"';
+ g_assert(j == slen + mangle + 2); /* j is the index of the '\0' */
+
+ return new;
+}
+
+/* Get the value associated with the key, and leave the current pointer
+ * pointing at the line containing the value. The char* returned MUST
+ * be freed by the caller.
+ */
+char *
+svGetValue(shvarFile *s, const char *key, gboolean verbatim)
+{
+ char *value = NULL;
+ char *line;
+ char *keyString;
+ int len;
+
+ g_assert(s);
+ g_assert(key);
+
+ keyString = g_malloc0(strlen(key) + 2);
+ strcpy(keyString, key);
+ keyString[strlen(key)] = '=';
+ len = strlen(keyString);
+
+ for (s->current = s->lineList; s->current; s->current = s->current->next) {
+ line = s->current->data;
+ if (!strncmp(keyString, line, len)) {
+ value = g_strdup(line + len);
+ if (!verbatim)
+ svUnescape(value);
+ break;
+ }
+ }
+ g_free(keyString);
+
+ if (value) {
+ if (value[0]) {
+ return value;
+ } else {
+ g_free(value);
+ return NULL;
+ }
+ }
+ if (s->parent) value = svGetValue(s->parent, key, verbatim);
+ return value;
+}
+
+/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true")
+ * return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false")
+ * return <default> otherwise
+ */
+int
+svTrueValue(shvarFile *s, const char *key, int def)
+{
+ char *tmp;
+ int returnValue = def;
+
+ tmp = svGetValue(s, key, FALSE);
+ if (!tmp) return returnValue;
+
+ if ( (!strcasecmp("yes", tmp)) ||
+ (!strcasecmp("true", tmp)) ||
+ (!strcasecmp("t", tmp)) ||
+ (!strcasecmp("y", tmp)) ) returnValue = 1;
+ else
+ if ( (!strcasecmp("no", tmp)) ||
+ (!strcasecmp("false", tmp)) ||
+ (!strcasecmp("f", tmp)) ||
+ (!strcasecmp("n", tmp)) ) returnValue = 0;
+
+ g_free (tmp);
+ return returnValue;
+}
+
+
+/* Set the variable <key> equal to the value <value>.
+ * If <key> does not exist, and the <current> pointer is set, append
+ * the key=value pair after that line. Otherwise, prepend the pair
+ * to the top of the file. Here's the algorithm, as the C code
+ * seems to be rather dense:
+ *
+ * if (value == NULL), then:
+ * if val2 (parent): change line to key= or append line key=
+ * if val1 (this) : delete line
+ * else noop
+ * else use this table:
+ * val2
+ * NULL value other
+ * v NULL append line noop append line
+ * a
+ * l value noop noop noop
+ * 1
+ * other change line delete line change line
+ *
+ * No changes are ever made to the parent config file, only to the
+ * specific file passed on the command line.
+ *
+ */
+void
+svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim)
+{
+ char *newval = NULL, *val1 = NULL, *val2 = NULL;
+ char *keyValue;
+
+ g_assert(s);
+ g_assert(key);
+ /* value may be NULL */
+
+ if (value)
+ newval = verbatim ? g_strdup(value) : svEscape(value);
+ keyValue = g_strdup_printf("%s=%s", key, newval ? newval : "");
+
+ val1 = svGetValue(s, key, FALSE);
+ if (val1 && newval && !strcmp(val1, newval)) goto bail;
+ if (s->parent) val2 = svGetValue(s->parent, key, FALSE);
+
+ if (!newval || !newval[0]) {
+ /* delete value somehow */
+ if (val2) {
+ /* change/append line to get key= */
+ if (s->current) s->current->data = keyValue;
+ else s->lineList = g_list_append(s->lineList, keyValue);
+ s->modified = 1;
+ } else if (val1) {
+ /* delete line */
+ s->lineList = g_list_remove_link(s->lineList, s->current);
+ g_list_free_1(s->current);
+ s->modified = 1;
+ goto bail; /* do not need keyValue */
+ }
+ goto end;
+ }
+
+ if (!val1) {
+ if (val2 && !strcmp(val2, newval)) goto end;
+ /* append line */
+ s->lineList = g_list_append(s->lineList, keyValue);
+ s->modified = 1;
+ goto end;
+ }
+
+ /* deal with a whole line of noops */
+ if (val1 && !strcmp(val1, newval)) goto end;
+
+ /* At this point, val1 && val1 != value */
+ if (val2 && !strcmp(val2, newval)) {
+ /* delete line */
+ s->lineList = g_list_remove_link(s->lineList, s->current);
+ g_list_free_1(s->current);
+ s->modified = 1;
+ goto bail; /* do not need keyValue */
+ } else {
+ /* change line */
+ if (s->current) s->current->data = keyValue;
+ else s->lineList = g_list_append(s->lineList, keyValue);
+ s->modified = 1;
+ }
+
+end:
+ if (newval) free(newval);
+ if (val1) free(val1);
+ if (val2) free(val2);
+ return;
+
+bail:
+ if (keyValue) free (keyValue);
+ goto end;
+}
+
+/* Write the current contents iff modified. Returns -1 on error
+ * and 0 on success. Do not write if no values have been modified.
+ * The mode argument is only used if creating the file, not if
+ * re-writing an existing file, and is passed unchanged to the
+ * open() syscall.
+ */
+int
+svWriteFile(shvarFile *s, int mode)
+{
+ FILE *f;
+ int tmpfd;
+
+ if (s->modified) {
+ if (s->fd == -1)
+ s->fd = open(s->fileName, O_WRONLY|O_CREAT, mode);
+ if (s->fd == -1)
+ return -1;
+ if (ftruncate(s->fd, 0) < 0)
+ return -1;
+
+ tmpfd = dup(s->fd);
+ f = fdopen(tmpfd, "w");
+ fseek(f, 0, SEEK_SET);
+ for (s->current = s->lineList; s->current; s->current = s->current->next) {
+ char *line = s->current->data;
+ fprintf(f, "%s\n", line);
+ }
+ fclose(f);
+ }
+
+ return 0;
+}
+
+
+/* Close the file descriptor (if open) and delete the shvarFile.
+ * Returns -1 on error and 0 on success.
+ */
+int
+svCloseFile(shvarFile *s)
+{
+
+ g_assert(s);
+
+ if (s->fd != -1) close(s->fd);
+
+ g_free(s->arena);
+ g_free(s->fileName);
+ g_list_foreach (s->lineList, (GFunc) g_free, NULL);
+ g_list_free(s->lineList); /* implicitly frees s->current */
+ g_free(s);
+ return 0;
+}
diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h
new file mode 100644
index 000000000..4b650d2a9
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/shvar.h
@@ -0,0 +1,110 @@
+/*
+ * shvar.h
+ *
+ * Interface for non-destructively reading/writing files containing
+ * only shell variable declarations and full-line comments.
+ *
+ * Includes explicit inheritance mechanism intended for use with
+ * Red Hat Linux ifcfg-* files. There is no protection against
+ * inheritance loops; they will generally cause stack overflows.
+ * Furthermore, they are only intended for one level of inheritance;
+ * the value setting algorithm assumes this.
+ *
+ * Copyright 1999 Red Hat, Inc.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#ifndef _SHVAR_H
+#define _SHVAR_H
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _shvarFile shvarFile;
+struct _shvarFile {
+ char *fileName; /* read-only */
+ int fd; /* read-only */
+ char *arena; /* ignore */
+ GList *lineList; /* read-only */
+ GList *current; /* set implicitly or explicitly,
+ points to element of lineList */
+ shvarFile *parent; /* set explicitly */
+ int modified; /* ignore */
+};
+
+
+/* Create the file <name>, return shvarFile on success, NULL on failure */
+shvarFile *
+svCreateFile(const char *name);
+
+/* Open the file <name>, return shvarFile on success, NULL on failure */
+shvarFile *
+svNewFile(const char *name);
+
+/* Get the value associated with the key, and leave the current pointer
+ * pointing at the line containing the value. The char* returned MUST
+ * be freed by the caller.
+ */
+char *
+svGetValue(shvarFile *s, const char *key, gboolean verbatim);
+
+/* return 1 if <key> resolves to any truth value (e.g. "yes", "y", "true")
+ * return 0 if <key> resolves to any non-truth value (e.g. "no", "n", "false")
+ * return <def> otherwise
+ */
+int
+svTrueValue(shvarFile *s, const char *key, int def);
+
+/* Set the variable <key> equal to the value <value>.
+ * If <key> does not exist, and the <current> pointer is set, append
+ * the key=value pair after that line. Otherwise, prepend the pair
+ * to the top of the file.
+ */
+void
+svSetValue(shvarFile *s, const char *key, const char *value, gboolean verbatim);
+
+
+/* Write the current contents iff modified. Returns -1 on error
+ * and 0 on success. Do not write if no values have been modified.
+ * The mode argument is only used if creating the file, not if
+ * re-writing an existing file, and is passed unchanged to the
+ * open() syscall.
+ */
+int
+svWriteFile(shvarFile *s, int mode);
+
+/* Close the file descriptor (if open) and delete the shvarFile.
+ * Returns -1 on error and 0 on success.
+ */
+int
+svCloseFile(shvarFile *s);
+
+/* Return a new escaped string */
+char *
+svEscape(const char *s);
+
+/* Unescape a string in-place */
+void
+svUnescape(char *s);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* ! _SHVAR_H */
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/Makefile.am
new file mode 100644
index 000000000..1b76a4742
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.am
@@ -0,0 +1,53 @@
+SUBDIRS=network-scripts
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+noinst_PROGRAMS = test-ifcfg-rh test-ifcfg-rh-utils
+
+test_ifcfg_rh_SOURCES = \
+ test-ifcfg-rh.c
+
+test_ifcfg_rh_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \
+ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\"
+
+test_ifcfg_rh_LDADD = \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifcfg-rh-io.la \
+ $(DBUS_LIBS)
+
+test_ifcfg_rh_utils_SOURCES = \
+ test-ifcfg-rh-utils.c
+
+test_ifcfg_rh_utils_CPPFLAGS = \
+ $(GLIB_CFLAGS)
+
+test_ifcfg_rh_utils_LDADD = \
+ $(builddir)/../libifcfg-rh-io.la
+
+if WITH_TESTS
+
+check-local: test-ifcfg-rh
+ $(abs_builddir)/test-ifcfg-rh-utils
+ $(abs_builddir)/test-ifcfg-rh
+
+endif
+
+EXTRA_DIST = \
+ iscsiadm-test-dhcp \
+ iscsiadm-test-static \
+ iscsiadm-test-bad-ipaddr \
+ iscsiadm-test-bad-gateway \
+ iscsiadm-test-bad-dns1 \
+ iscsiadm-test-bad-dns2 \
+ iscsiadm-test-bad-entry \
+ iscsiadm-test-bad-record
+
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
new file mode 100644
index 000000000..171cd5e5f
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/Makefile.in
@@ -0,0 +1,826 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = test-ifcfg-rh$(EXEEXT) test-ifcfg-rh-utils$(EXEEXT)
+subdir = src/settings/plugins/ifcfg-rh/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_ifcfg_rh_OBJECTS = test_ifcfg_rh-test-ifcfg-rh.$(OBJEXT)
+test_ifcfg_rh_OBJECTS = $(am_test_ifcfg_rh_OBJECTS)
+am__DEPENDENCIES_1 =
+test_ifcfg_rh_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifcfg-rh-io.la $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+am_test_ifcfg_rh_utils_OBJECTS = \
+ test_ifcfg_rh_utils-test-ifcfg-rh-utils.$(OBJEXT)
+test_ifcfg_rh_utils_OBJECTS = $(am_test_ifcfg_rh_utils_OBJECTS)
+test_ifcfg_rh_utils_DEPENDENCIES = $(builddir)/../libifcfg-rh-io.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(test_ifcfg_rh_SOURCES) $(test_ifcfg_rh_utils_SOURCES)
+DIST_SOURCES = $(test_ifcfg_rh_SOURCES) $(test_ifcfg_rh_utils_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = network-scripts
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+test_ifcfg_rh_SOURCES = \
+ test-ifcfg-rh.c
+
+test_ifcfg_rh_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_IFCFG_DIR=\"$(abs_srcdir)\" \
+ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/\"
+
+test_ifcfg_rh_LDADD = \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifcfg-rh-io.la \
+ $(DBUS_LIBS)
+
+test_ifcfg_rh_utils_SOURCES = \
+ test-ifcfg-rh-utils.c
+
+test_ifcfg_rh_utils_CPPFLAGS = \
+ $(GLIB_CFLAGS)
+
+test_ifcfg_rh_utils_LDADD = \
+ $(builddir)/../libifcfg-rh-io.la
+
+EXTRA_DIST = \
+ iscsiadm-test-dhcp \
+ iscsiadm-test-static \
+ iscsiadm-test-bad-ipaddr \
+ iscsiadm-test-bad-gateway \
+ iscsiadm-test-bad-dns1 \
+ iscsiadm-test-bad-dns2 \
+ iscsiadm-test-bad-entry \
+ iscsiadm-test-bad-record
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+test-ifcfg-rh$(EXEEXT): $(test_ifcfg_rh_OBJECTS) $(test_ifcfg_rh_DEPENDENCIES)
+ @rm -f test-ifcfg-rh$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ifcfg_rh_OBJECTS) $(test_ifcfg_rh_LDADD) $(LIBS)
+test-ifcfg-rh-utils$(EXEEXT): $(test_ifcfg_rh_utils_OBJECTS) $(test_ifcfg_rh_utils_DEPENDENCIES)
+ @rm -f test-ifcfg-rh-utils$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ifcfg_rh_utils_OBJECTS) $(test_ifcfg_rh_utils_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+test_ifcfg_rh-test-ifcfg-rh.o: test-ifcfg-rh.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh-test-ifcfg-rh.o -MD -MP -MF $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o test_ifcfg_rh-test-ifcfg-rh.o `test -f 'test-ifcfg-rh.c' || echo '$(srcdir)/'`test-ifcfg-rh.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh.c' object='test_ifcfg_rh-test-ifcfg-rh.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh-test-ifcfg-rh.o `test -f 'test-ifcfg-rh.c' || echo '$(srcdir)/'`test-ifcfg-rh.c
+
+test_ifcfg_rh-test-ifcfg-rh.obj: test-ifcfg-rh.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh-test-ifcfg-rh.obj -MD -MP -MF $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo -c -o test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'test-ifcfg-rh.c'; then $(CYGPATH_W) 'test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Tpo $(DEPDIR)/test_ifcfg_rh-test-ifcfg-rh.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh.c' object='test_ifcfg_rh-test-ifcfg-rh.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh-test-ifcfg-rh.obj `if test -f 'test-ifcfg-rh.c'; then $(CYGPATH_W) 'test-ifcfg-rh.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh.c'; fi`
+
+test_ifcfg_rh_utils-test-ifcfg-rh-utils.o: test-ifcfg-rh-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh_utils-test-ifcfg-rh-utils.o -MD -MP -MF $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.o `test -f 'test-ifcfg-rh-utils.c' || echo '$(srcdir)/'`test-ifcfg-rh-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh-utils.c' object='test_ifcfg_rh_utils-test-ifcfg-rh-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.o `test -f 'test-ifcfg-rh-utils.c' || echo '$(srcdir)/'`test-ifcfg-rh-utils.c
+
+test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj: test-ifcfg-rh-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj -MD -MP -MF $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj `if test -f 'test-ifcfg-rh-utils.c'; then $(CYGPATH_W) 'test-ifcfg-rh-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh-utils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Tpo $(DEPDIR)/test_ifcfg_rh_utils-test-ifcfg-rh-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifcfg-rh-utils.c' object='test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifcfg_rh_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifcfg_rh_utils-test-ifcfg-rh-utils.obj `if test -f 'test-ifcfg-rh-utils.c'; then $(CYGPATH_W) 'test-ifcfg-rh-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-ifcfg-rh-utils.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+@WITH_TESTS_FALSE@check-local:
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am check-local clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am
+
+
+@WITH_TESTS_TRUE@check-local: test-ifcfg-rh
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifcfg-rh-utils
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifcfg-rh
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1
new file mode 100755
index 000000000..4a6a93822
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns1
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress = 192.168.32.72
+iface.subnet_mask = 255.255.252.0
+iface.gateway = 192.168.35.254
+iface.primary_dns = 10000.500.250.1
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2 b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2
new file mode 100755
index 000000000..9bd5839bd
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-dns2
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress = 192.168.32.72
+iface.subnet_mask = 255.255.252.0
+iface.gateway = 192.168.35.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = blah.foo.bar.baz
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry
new file mode 100755
index 000000000..eba0ec673
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-entry
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress 192.168.32.72
+iface.subnet_mask = 255.255.252.0
+iface.gateway = 192.168.35.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f1
+iface.bootproto = DHCP
+iface.gateway = 10.16.52.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth1
+node.name = iqn.1.2008-11.com.blahblah:iscsi1
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway
new file mode 100755
index 000000000..b3dc74478
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-gateway
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress = aa.bb.cc.dd
+iface.subnet_mask = 255.255.252.0
+iface.gateway = 192.168.35.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr
new file mode 100755
index 000000000..92f44777b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-ipaddr
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress = 192.168.32.72
+iface.subnet_mask = 255.255.252.0
+iface.gateway = bb.cc.dd.ee
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record
new file mode 100755
index 000000000..a2d215fe2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-bad-record
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = DHCP
+iface.gateway = 10.16.52.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp
new file mode 100755
index 000000000..6de0637cb
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-dhcp
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = DHCP
+iface.gateway = 10.16.52.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f1
+iface.bootproto = DHCP
+iface.gateway = 10.16.52.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth1
+node.name = iqn.1.2008-11.com.blahblah:iscsi1
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static
new file mode 100755
index 000000000..99a6e7c17
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/iscsiadm-test-static
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+cat << EOF
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f0
+iface.bootproto = STATIC
+iface.ipaddress = 192.168.32.72
+iface.subnet_mask = 255.255.252.0
+iface.gateway = 192.168.35.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth0
+node.name = iqn.0.2008-11.com.blahblah:iscsi0
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+# BEGIN RECORD
+iface.initiatorname = iqn.pjones6
+iface.hwaddress = 00:33:21:98:b9:f1
+iface.bootproto = DHCP
+iface.gateway = 10.16.52.254
+iface.primary_dns = 10.16.255.2
+iface.secondary_dns = 10.16.255.3
+iface.vlan = 0
+iface.net_ifacename = eth1
+node.name = iqn.1.2008-11.com.blahblah:iscsi1
+node.conn[0].address = 10.16.52.16
+node.conn[0].port = 3260
+node.boot_lun = 00000000
+# END RECORD
+EOF
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
new file mode 100644
index 000000000..22d1b4a7e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am
@@ -0,0 +1,90 @@
+EXTRA_DIST = \
+ ifcfg-test-minimal \
+ ifcfg-test-nm-controlled \
+ ifcfg-test-wired-static \
+ ifcfg-test-wired-static-bootproto \
+ ifcfg-test-wired-dhcp \
+ ifcfg-test-wired-dhcp6-only \
+ ifcfg-test-wired-global-gateway \
+ network-test-wired-global-gateway \
+ ifcfg-test-wired-never-default \
+ network-test-wired-never-default \
+ ifcfg-test-wired-defroute-no \
+ ifcfg-test-wired-defroute-no-gatewaydev-yes \
+ network-test-wired-defroute-no-gatewaydev-yes \
+ ifcfg-test-wired-8021x-peap-mschapv2 \
+ keys-test-wired-8021x-peap-mschapv2 \
+ ifcfg-test-wired-8021x-tls-agent \
+ ifcfg-test-wired-8021x-tls-always \
+ ifcfg-test-onboot-no \
+ ifcfg-test-wifi-open \
+ ifcfg-test-wifi-open-auto \
+ ifcfg-test-wifi-open-ssid-quoted \
+ ifcfg-test-wifi-open-ssid-long-quoted \
+ ifcfg-test-wifi-open-ssid-hex \
+ ifcfg-test-wifi-open-ssid-long-hex \
+ ifcfg-test-wifi-open-ssid-bad-hex \
+ ifcfg-test-wifi-wep \
+ keys-test-wifi-wep \
+ ifcfg-test-wifi-wep-adhoc \
+ keys-test-wifi-wep-adhoc \
+ ifcfg-test-wifi-wep-eap-ttls-chap \
+ keys-test-wifi-wep-eap-ttls-chap \
+ ifcfg-test-wifi-leap \
+ keys-test-wifi-leap \
+ ifcfg-test-wifi-leap-agent \
+ ifcfg-test-wifi-leap-always-ask \
+ ifcfg-test-wifi-wpa-psk \
+ keys-test-wifi-wpa-psk \
+ ifcfg-test-wifi-wpa-psk-unquoted \
+ keys-test-wifi-wpa-psk-unquoted \
+ ifcfg-test-wifi-wpa-psk-unquoted2 \
+ keys-test-wifi-wpa-psk-unquoted2 \
+ ifcfg-test-wifi-wpa-psk-adhoc \
+ keys-test-wifi-wpa-psk-adhoc \
+ ifcfg-test-wifi-wpa-psk-hex \
+ keys-test-wifi-wpa-psk-hex \
+ ifcfg-test-wifi-wpa-eap-tls \
+ keys-test-wifi-wpa-eap-tls \
+ ifcfg-test-wifi-wpa-eap-ttls-tls \
+ keys-test-wifi-wpa-eap-ttls-tls \
+ test_ca_cert.pem \
+ test1_key_and_cert.pem \
+ ifcfg-test-ibft-dhcp \
+ ifcfg-test-ibft-static \
+ ifcfg-test-static-routes-legacy \
+ route-test-static-routes-legacy \
+ ifcfg-test-wired-static-routes \
+ route-test-wired-static-routes \
+ ifcfg-test-wired-static-routes-legacy \
+ route-test-wired-static-routes-legacy \
+ ifcfg-test-wired-ipv6-manual \
+ route6-test-wired-ipv6-manual \
+ ifcfg-test-wired-static-no-prefix-8 \
+ ifcfg-test-wired-static-no-prefix-16 \
+ ifcfg-test-wired-static-no-prefix-24 \
+ ifcfg-test-wired-ipv6-only \
+ ifcfg-test-wifi-wep-passphrase \
+ keys-test-wifi-wep-passphrase \
+ ifcfg-test-wifi-wep-40-ascii \
+ keys-test-wifi-wep-40-ascii \
+ ifcfg-test-wifi-wep-104-ascii \
+ keys-test-wifi-wep-104-ascii \
+ ifcfg-test-wired-qeth-static \
+ ifcfg-test-bridge-main \
+ ifcfg-test-bridge-component \
+ ifcfg-test-vlan-interface \
+ ifcfg-test-wifi-wep-no-keys \
+ ifcfg-test-permissions \
+ ifcfg-test-wifi-wep-agent-keys \
+ ifcfg-test-wifi-dynamic-wep-leap \
+ keys-test-wifi-dynamic-wep-leap
+
+check-local:
+ @for f in $(EXTRA_DIST); do \
+ chmod 0600 $(abs_srcdir)/$$f; \
+ done
+
+# Make the special temp dir for some written connections
+ mkdir -p $(abs_builddir)/tmp
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
new file mode 100644
index 000000000..4f95948f9
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.in
@@ -0,0 +1,543 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/ifcfg-rh/tests/network-scripts
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+ ifcfg-test-minimal \
+ ifcfg-test-nm-controlled \
+ ifcfg-test-wired-static \
+ ifcfg-test-wired-static-bootproto \
+ ifcfg-test-wired-dhcp \
+ ifcfg-test-wired-dhcp6-only \
+ ifcfg-test-wired-global-gateway \
+ network-test-wired-global-gateway \
+ ifcfg-test-wired-never-default \
+ network-test-wired-never-default \
+ ifcfg-test-wired-defroute-no \
+ ifcfg-test-wired-defroute-no-gatewaydev-yes \
+ network-test-wired-defroute-no-gatewaydev-yes \
+ ifcfg-test-wired-8021x-peap-mschapv2 \
+ keys-test-wired-8021x-peap-mschapv2 \
+ ifcfg-test-wired-8021x-tls-agent \
+ ifcfg-test-wired-8021x-tls-always \
+ ifcfg-test-onboot-no \
+ ifcfg-test-wifi-open \
+ ifcfg-test-wifi-open-auto \
+ ifcfg-test-wifi-open-ssid-quoted \
+ ifcfg-test-wifi-open-ssid-long-quoted \
+ ifcfg-test-wifi-open-ssid-hex \
+ ifcfg-test-wifi-open-ssid-long-hex \
+ ifcfg-test-wifi-open-ssid-bad-hex \
+ ifcfg-test-wifi-wep \
+ keys-test-wifi-wep \
+ ifcfg-test-wifi-wep-adhoc \
+ keys-test-wifi-wep-adhoc \
+ ifcfg-test-wifi-wep-eap-ttls-chap \
+ keys-test-wifi-wep-eap-ttls-chap \
+ ifcfg-test-wifi-leap \
+ keys-test-wifi-leap \
+ ifcfg-test-wifi-leap-agent \
+ ifcfg-test-wifi-leap-always-ask \
+ ifcfg-test-wifi-wpa-psk \
+ keys-test-wifi-wpa-psk \
+ ifcfg-test-wifi-wpa-psk-unquoted \
+ keys-test-wifi-wpa-psk-unquoted \
+ ifcfg-test-wifi-wpa-psk-unquoted2 \
+ keys-test-wifi-wpa-psk-unquoted2 \
+ ifcfg-test-wifi-wpa-psk-adhoc \
+ keys-test-wifi-wpa-psk-adhoc \
+ ifcfg-test-wifi-wpa-psk-hex \
+ keys-test-wifi-wpa-psk-hex \
+ ifcfg-test-wifi-wpa-eap-tls \
+ keys-test-wifi-wpa-eap-tls \
+ ifcfg-test-wifi-wpa-eap-ttls-tls \
+ keys-test-wifi-wpa-eap-ttls-tls \
+ test_ca_cert.pem \
+ test1_key_and_cert.pem \
+ ifcfg-test-ibft-dhcp \
+ ifcfg-test-ibft-static \
+ ifcfg-test-static-routes-legacy \
+ route-test-static-routes-legacy \
+ ifcfg-test-wired-static-routes \
+ route-test-wired-static-routes \
+ ifcfg-test-wired-static-routes-legacy \
+ route-test-wired-static-routes-legacy \
+ ifcfg-test-wired-ipv6-manual \
+ route6-test-wired-ipv6-manual \
+ ifcfg-test-wired-static-no-prefix-8 \
+ ifcfg-test-wired-static-no-prefix-16 \
+ ifcfg-test-wired-static-no-prefix-24 \
+ ifcfg-test-wired-ipv6-only \
+ ifcfg-test-wifi-wep-passphrase \
+ keys-test-wifi-wep-passphrase \
+ ifcfg-test-wifi-wep-40-ascii \
+ keys-test-wifi-wep-40-ascii \
+ ifcfg-test-wifi-wep-104-ascii \
+ keys-test-wifi-wep-104-ascii \
+ ifcfg-test-wired-qeth-static \
+ ifcfg-test-bridge-main \
+ ifcfg-test-bridge-component \
+ ifcfg-test-vlan-interface \
+ ifcfg-test-wifi-wep-no-keys \
+ ifcfg-test-permissions \
+ ifcfg-test-wifi-wep-agent-keys \
+ ifcfg-test-wifi-dynamic-wep-leap \
+ keys-test-wifi-dynamic-wep-leap
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-am check-local clean clean-generic \
+ clean-libtool distclean distclean-generic distclean-libtool \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am
+
+
+check-local:
+ @for f in $(EXTRA_DIST); do \
+ chmod 0600 $(abs_srcdir)/$$f; \
+ done
+
+# Make the special temp dir for some written connections
+ mkdir -p $(abs_builddir)/tmp
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component
new file mode 100644
index 000000000..f586637ec
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-component
@@ -0,0 +1,5 @@
+DEVICE=eth0
+HWADDR=00:22:15:59:62:97
+ONBOOT=no
+BRIDGE=br0
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main
new file mode 100644
index 000000000..c5caf3fc9
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-bridge-main
@@ -0,0 +1,7 @@
+DEVICE=br0
+ONBOOT=no
+TYPE=Bridge
+BOOTPROTO=dhcp
+STP=on
+DELAY=0
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp
new file mode 100644
index 000000000..abfcd6e4c
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-dhcp
@@ -0,0 +1,4 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+DEVICE=eth0
+HWADDR=00:33:21:98:b9:f1
+BOOTPROTO=ibft
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static
new file mode 100644
index 000000000..99b02e42b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-ibft-static
@@ -0,0 +1,4 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+DEVICE=eth0
+HWADDR=00:33:21:98:b9:f0
+BOOTPROTO=ibft
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal
new file mode 100644
index 000000000..63bcc840d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-minimal
@@ -0,0 +1,4 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+DEVICE=eth0
+HWADDR=00:16:41:11:22:33
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled
new file mode 100644
index 000000000..a38f1f5f1
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-nm-controlled
@@ -0,0 +1,9 @@
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:f8:9f
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=no
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no
new file mode 100644
index 000000000..b94917110
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-onboot-no
@@ -0,0 +1,5 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+ONBOOT=no
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions
new file mode 100644
index 000000000..5b413aa97
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions
@@ -0,0 +1,8 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERS="dcbw ssmith johnny5"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy
new file mode 100644
index 000000000..2173729d1
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-static-routes-legacy
@@ -0,0 +1,12 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+DEVICE=eth0
+HWADDR=00:16:41:11:22:33
+NAME="test-static-routes-legacy"
+TYPE=Ethernet
+BOOTPROTO=dhcp
+DEFROUTE=yes
+UUID=ba60d05a-7898-820d-c2db-427a88f8f2a5
+ONBOOT=yes
+IPV6INIT=no
+PEERDNS=yes
+PEERROUTES=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
new file mode 100644
index 000000000..6c841855e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-interface
@@ -0,0 +1,7 @@
+DEVICE=eth1.43
+VLAN=yes
+ONBOOT=yes
+BOOTPROTO=none
+IPADDR=192.168.43.149
+NETMASK=255.255.255.0
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap
new file mode 100644
index 000000000..d9c95cc24
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-dynamic-wep-leap
@@ -0,0 +1,17 @@
+ESSID="sdasdsdg"
+MODE=Managed
+KEY_MGMT=IEEE8021X
+CIPHER_GROUP="WEP40 WEP104"
+TYPE=Wireless
+IEEE_8021X_EAP_METHODS=LEAP
+IEEE_8021X_IDENTITY="bill smith"
+BOOTPROTO=dhcp
+DEFROUTE=yes
+PEERDNS=yes
+PEERROUTES=yes
+IPV4_FAILURE_FATAL=yes
+IPV6INIT=no
+NAME="Test Dynamic WEP LEAP"
+UUID=aca7a23c-d934-49a3-8bfb-ad66f846c57b
+ONBOOT=yes
+USERS=dcbw
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap
new file mode 100644
index 000000000..50f4fd31e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap
@@ -0,0 +1,17 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+KEY_MGMT=IEEE8021X
+SECURITYMODE=LEAP
+IEEE_8021X_IDENTITY="Bill Smith"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent
new file mode 100644
index 000000000..991ba67aa
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-agent
@@ -0,0 +1,17 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+KEY_MGMT=IEEE8021X
+SECURITYMODE=LEAP
+IEEE_8021X_IDENTITY="Bill Smith"
+IEEE_8021X_PASSWORD_FLAGS=user
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask
new file mode 100644
index 000000000..5bb02b5ce
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-leap-always-ask
@@ -0,0 +1,17 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+KEY_MGMT=IEEE8021X
+SECURITYMODE=LEAP
+IEEE_8021X_IDENTITY="Bill Smith"
+IEEE_8021X_PASSWORD_FLAGS="user ask"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open
new file mode 100644
index 000000000..d4bb8f75b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto
new file mode 100644
index 000000000..42ee200af
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-auto
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Auto
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex
new file mode 100644
index 000000000..32d633428
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=0x626cxx
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex
new file mode 100644
index 000000000..dcb46da7f
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-hex
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=0x626c6168626c6168
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex
new file mode 100644
index 000000000..37bb085b5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-hex
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=0x626c6168626c6168626c6168626c6168626c6168626c6168626c6168626c6168AA
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted
new file mode 100644
index 000000000..0b46acd66
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID="foo\"bar\\foo\"bar\\foo\"bar\\foo\"bar\\1"
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted
new file mode 100644
index 000000000..08496bb56
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-open-ssid-quoted
@@ -0,0 +1,13 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID="foo\"bar\\"
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep
new file mode 100644
index 000000000..e1ce20d6d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep
@@ -0,0 +1,14 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+SECURITYMODE=restricted
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii
new file mode 100644
index 000000000..250efa134
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-104-ascii
@@ -0,0 +1,14 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+SECURITYMODE=open
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii
new file mode 100644
index 000000000..250efa134
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-40-ascii
@@ -0,0 +1,14 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+SECURITYMODE=open
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc
new file mode 100644
index 000000000..9d0bacfc7
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-adhoc
@@ -0,0 +1,15 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=11
+MODE=Ad-Hoc
+RATE=auto
+ONBOOT=no
+USERCTL=yes
+PEERDNS=no
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPV6INIT=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys
new file mode 100644
index 000000000..2bc16b6e5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-agent-keys
@@ -0,0 +1,18 @@
+ESSID="foobar"
+MODE=Managed
+TYPE=Wireless
+BOOTPROTO=dhcp
+DEFROUTE=yes
+IPV4_FAILURE_FATAL=yes
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
+IPV6_DEFROUTE=yes
+IPV6_FAILURE_FATAL=no
+UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd
+ONBOOT=yes
+HWADDR=00:16:BB:AA:CC:DD
+WEP_KEY_FLAGS=user
+PEERDNS=yes
+PEERROUTES=yes
+IPV6_PEERDNS=yes
+IPV6_PEERROUTES=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap
new file mode 100644
index 000000000..bdea6aa3b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap
@@ -0,0 +1,20 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+BOOTPROTO=dhcp
+ONBOOT=yes
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+PEERDNS=yes
+ESSID=blahblah
+MODE=Managed
+RATE=auto
+KEY_MGMT=IEEE8021X
+IEEE_8021X_EAP_METHODS=TTLS
+IEEE_8021X_IDENTITY="David Smith"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_INNER_AUTH_METHODS=CHAP
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys
new file mode 100644
index 000000000..cb4da43f7
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys
@@ -0,0 +1,18 @@
+ESSID="foobar"
+MODE=Managed
+TYPE=Wireless
+BOOTPROTO=dhcp
+DEFROUTE=yes
+IPV4_FAILURE_FATAL=yes
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
+IPV6_DEFROUTE=yes
+IPV6_FAILURE_FATAL=no
+UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd
+ONBOOT=yes
+HWADDR=00:16:BB:AA:CC:DD
+DEFAULTKEY=1
+PEERDNS=yes
+PEERROUTES=yes
+IPV6_PEERDNS=yes
+IPV6_PEERROUTES=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase
new file mode 100644
index 000000000..250efa134
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-passphrase
@@ -0,0 +1,14 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+SECURITYMODE=open
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls
new file mode 100644
index 000000000..92aaeeab9
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-tls
@@ -0,0 +1,25 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+BOOTPROTO=dhcp
+ONBOOT=yes
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+PEERDNS=yes
+ESSID=blahblah
+MODE=Managed
+RATE=auto
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-EAP
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+IEEE_8021X_EAP_METHODS=TLS
+IEEE_8021X_IDENTITY="Bill Smith"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem
+IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls
new file mode 100644
index 000000000..42ed1d68a
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls
@@ -0,0 +1,28 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+BOOTPROTO=dhcp
+ONBOOT=yes
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+PEERDNS=yes
+ESSID=blahblah
+MODE=Managed
+RATE=auto
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-EAP
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+IEEE_8021X_EAP_METHODS=TTLS
+IEEE_8021X_IDENTITY="Chuck Shumer"
+IEEE_8021X_ANON_IDENTITY="anonymous"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_INNER_AUTH_METHODS=EAP-TLS
+IEEE_8021X_INNER_CA_CERT=test_ca_cert.pem
+IEEE_8021X_INNER_CLIENT_CERT=test1_key_and_cert.pem
+IEEE_8021X_INNER_PRIVATE_KEY=test1_key_and_cert.pem
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk
new file mode 100644
index 000000000..2119ba8e6
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk
@@ -0,0 +1,19 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-PSK
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc
new file mode 100644
index 000000000..aa00925e1
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc
@@ -0,0 +1,16 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Ad-Hoc
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_GROUP=CCMP
+KEY_MGMT=WPA-PSK
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex
new file mode 100644
index 000000000..2119ba8e6
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-hex
@@ -0,0 +1,19 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-PSK
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted
new file mode 100644
index 000000000..2119ba8e6
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted
@@ -0,0 +1,19 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-PSK
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2
new file mode 100644
index 000000000..2119ba8e6
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2
@@ -0,0 +1,19 @@
+TYPE=Wireless
+DEVICE=eth2
+HWADDR=00:16:41:11:22:33
+NM_CONTROLLED=yes
+BOOTPROTO=dhcp
+ESSID=blahblah
+CHANNEL=1
+MODE=Managed
+RATE=auto
+ONBOOT=yes
+USERCTL=yes
+PEERDNS=yes
+IPV6INIT=no
+CIPHER_PAIRWISE="TKIP CCMP"
+CIPHER_GROUP="TKIP CCMP WEP40 WEP104"
+KEY_MGMT=WPA-PSK
+WPA_ALLOW_WPA=yes
+WPA_ALLOW_WPA2=yes
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2
new file mode 100644
index 000000000..6d68eca13
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+NM_CONTROLLED=yes
+KEY_MGMT=IEEE8021X
+IEEE_8021X_EAP_METHODS=PEAP
+IEEE_8021X_IDENTITY="David Smith"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_PEAP_VERSION=1
+IEEE_8021X_PEAP_FORCE_NEW_LABEL=yes
+IEEE_8021X_INNER_AUTH_METHODS=MSCHAPV2
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent
new file mode 100644
index 000000000..052ab425a
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-agent
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+NM_CONTROLLED=yes
+KEY_MGMT=IEEE8021X
+IEEE_8021X_EAP_METHODS=TLS
+IEEE_8021X_IDENTITY="David Smith"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem
+IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem
+IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS=user
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always
new file mode 100644
index 000000000..5deee0663
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-8021x-tls-always
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+NM_CONTROLLED=yes
+KEY_MGMT=IEEE8021X
+IEEE_8021X_EAP_METHODS=TLS
+IEEE_8021X_IDENTITY="David Smith"
+IEEE_8021X_CA_CERT=test_ca_cert.pem
+IEEE_8021X_CLIENT_CERT=test1_key_and_cert.pem
+IEEE_8021X_PRIVATE_KEY=test1_key_and_cert.pem
+IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS="user ask"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no
new file mode 100644
index 000000000..fe8b15b29
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth4
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+NM_CONTROLLED=yes
+PEERDNS=yes
+DEFROUTE=no
+
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
+IPV6_DEFROUTE=no
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes
new file mode 100644
index 000000000..3cf4323dd
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+NM_CONTROLLED=yes
+PEERDNS=yes
+DEFROUTE=no
+
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
+IPV6_DEFROUTE=no
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp
new file mode 100644
index 000000000..727d2cebc
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+PEERDNS=no
+DHCP_HOSTNAME=foobar
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only
new file mode 100644
index 000000000..de03e0448
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-dhcp6-only
@@ -0,0 +1,11 @@
+DEVICE="eth0"
+ONBOOT=no
+TYPE=Ethernet
+DEFROUTE=yes
+PEERDNS=yes
+PEERROUTES=yes
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+DHCPV6C=yes
+HWADDR=00:13:20:F5:F5:E4
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway
new file mode 100644
index 000000000..98d910531
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-global-gateway
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+PREFIX=24
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual
new file mode 100644
index 000000000..45db0e4c4
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-manual
@@ -0,0 +1,19 @@
+# Intel Corporation 82567LM Gigabit Network Connection
+TYPE=Ethernet
+DEVICE=eth2
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+NM_CONTROLLED=yes
+PEERDNS=yes
+DNS1=10.2.0.4
+DNS2=10.2.0.5
+DNS3=1:2:3:4::a
+DNS4=1:2:3:4::b
+DOMAIN="lorem.com ipsum.org dolor.edu"
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+IPV6ADDR="1001:abba::1234/56"
+IPV6ADDR_SECONDARIES="2001:abba::2234/64 3001:abba::3234/96"
+IPV6_FAILURE_FATAL=no
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only
new file mode 100644
index 000000000..59ec32e5b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-ipv6-only
@@ -0,0 +1,14 @@
+# Intel Corporation 82567LM Gigabit Network Connection
+TYPE=Ethernet
+DEVICE=eth2
+HWADDR=00:11:22:33:44:ee
+ONBOOT=yes
+USERCTL=yes
+NM_CONTROLLED=yes
+PEERDNS=yes
+DNS1=1:2:3:4::a
+DOMAIN="lorem.com ipsum.org dolor.edu"
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+IPV6ADDR="1001:abba::1234/56"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default
new file mode 100644
index 000000000..12d5b5e63
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-never-default
@@ -0,0 +1,11 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth4
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=dhcp
+ONBOOT=yes
+USERCTL=yes
+NM_CONTROLLED=yes
+PEERDNS=yes
+IPV6INIT=yes
+IPV6_AUTOCONF=yes
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static
new file mode 100644
index 000000000..4719de217
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-qeth-static
@@ -0,0 +1,13 @@
+# IBM QETH
+DEVICE=eth1
+BOOTPROTO=static
+IPADDR=192.168.70.87
+NETMASK=255.255.255.0
+ONBOOT=yes
+NETTYPE=qeth
+SUBCHANNELS=0.0.0600,0.0.0601,0.0.0602
+TYPE=Ethernet
+PORTNAME=OSAPORT
+OPTIONS='layer2=1 portno=0'
+MACADDR=02:00:00:23:65:1a
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static
new file mode 100644
index 000000000..c8315f45d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static
@@ -0,0 +1,20 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+IPV6ADDR=dead:beaf::1
+IPV6ADDR_SECONDARIES="dead:beaf::2/56"
+DNS3=1:2:3:4::a
+DNS4=1:2:3:4::b
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto
new file mode 100644
index 000000000..ee821503e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-bootproto
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=static
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16
new file mode 100644
index 000000000..079990388
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-16
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=172.16.3.4
+GATEWAY=172.16.3.1
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24
new file mode 100644
index 000000000..688143cd2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-24
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+GATEWAY=192.168.1.1
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8
new file mode 100644
index 000000000..0433c62a8
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-no-prefix-8
@@ -0,0 +1,14 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=10.11.12.13
+GATEWAY=10.0.0.1
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes
new file mode 100644
index 000000000..7faf49bda
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy
new file mode 100644
index 000000000..7faf49bda
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wired-static-routes-legacy
@@ -0,0 +1,15 @@
+# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile)
+TYPE=Ethernet
+DEVICE=eth0
+HWADDR=00:11:22:33:44:ee
+BOOTPROTO=none
+ONBOOT=yes
+USERCTL=yes
+IPV6INIT=no
+MTU=1492
+NM_CONTROLLED=yes
+DNS1=4.2.2.1
+DNS2=4.2.2.2
+IPADDR=192.168.1.5
+NETMASK=255.255.255.0
+GATEWAY=192.168.1.1
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap
new file mode 100644
index 000000000..6936f2e06
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-dynamic-wep-leap
@@ -0,0 +1,2 @@
+IEEE_8021X_PASSWORD="foobar baz"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap
new file mode 100644
index 000000000..fe78177e7
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-leap
@@ -0,0 +1 @@
+IEEE_8021X_PASSWORD="foobarblah"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep
new file mode 100644
index 000000000..0bd766c27
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep
@@ -0,0 +1 @@
+KEY=0123456789abcdef0123456789
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii
new file mode 100644
index 000000000..f5d532b28
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-104-ascii
@@ -0,0 +1 @@
+KEY1=s:LoremIpsumSit
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii
new file mode 100644
index 000000000..b0d147082
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-40-ascii
@@ -0,0 +1 @@
+KEY1=s:Lorem
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc
new file mode 100644
index 000000000..0bd766c27
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-adhoc
@@ -0,0 +1 @@
+KEY=0123456789abcdef0123456789
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap
new file mode 100644
index 000000000..6936f2e06
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-eap-ttls-chap
@@ -0,0 +1,2 @@
+IEEE_8021X_PASSWORD="foobar baz"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase
new file mode 100644
index 000000000..d45c0ea8e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wep-passphrase
@@ -0,0 +1 @@
+KEY_PASSPHRASE1="foobar222blahblah"
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls
new file mode 100644
index 000000000..0c3bc1e1d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-tls
@@ -0,0 +1,2 @@
+IEEE_8021X_PRIVATE_KEY_PASSWORD="test1"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls
new file mode 100644
index 000000000..b6256b951
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-eap-ttls-tls
@@ -0,0 +1,2 @@
+IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD="test1"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk
new file mode 100644
index 000000000..d7813b2f5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk
@@ -0,0 +1,2 @@
+WPA_PSK="I wonder what the king is doing tonight?"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc
new file mode 100644
index 000000000..d7813b2f5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-adhoc
@@ -0,0 +1,2 @@
+WPA_PSK="I wonder what the king is doing tonight?"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex
new file mode 100644
index 000000000..d0576a8de
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-hex
@@ -0,0 +1,2 @@
+WPA_PSK=1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted
new file mode 100644
index 000000000..9a47196a2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted
@@ -0,0 +1,2 @@
+WPA_PSK=54336845e2f3f321c4c7
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2
new file mode 100644
index 000000000..347bb85e5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wifi-wpa-psk-unquoted2
@@ -0,0 +1,2 @@
+WPA_PSK="a5d4d45e78e1455d8e6124e81ea137f9a5d4d45e78e1455d8e6124e81ea137f9"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2
new file mode 100644
index 000000000..6936f2e06
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/keys-test-wired-8021x-peap-mschapv2
@@ -0,0 +1,2 @@
+IEEE_8021X_PASSWORD="foobar baz"
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes
new file mode 100644
index 000000000..0d6a302f1
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-defroute-no-gatewaydev-yes
@@ -0,0 +1,2 @@
+GATEWAYDEV=eth0
+IPV6_DEFAULTDEV=eth0
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway
new file mode 100644
index 000000000..7987d1058
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-global-gateway
@@ -0,0 +1 @@
+GATEWAY=192.168.1.2
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default
new file mode 100644
index 000000000..9a292679a
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/network-test-wired-never-default
@@ -0,0 +1,4 @@
+GATEWAYDEV=eth0
+# when devices in IPV6_DEFAULTDEV and IPV6_DEFAULTGW don't match the one in IPV6_DEFAULTGW is prefered
+IPV6_DEFAULTDEV=eth4
+IPV6_DEFAULTGW=2001::1234%eth0
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy
new file mode 100644
index 000000000..3db42ab5b
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-static-routes-legacy
@@ -0,0 +1,3 @@
+1.2.3.0/24 via 222.173.190.239 metric 0
+3.2.1.0/24 via 202.254.171.190 metric 77
+7.7.7.7/32 via 10.0.2.2 metric 11
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes
new file mode 100644
index 000000000..ee2a32d8e
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes
@@ -0,0 +1,8 @@
+ADDRESS0=11.22.33.0
+NETMASK0=255.255.255.0
+GATEWAY0=192.168.1.5
+
+ADDRESS1=44.55.66.77
+NETMASK1=255.255.255.255
+GATEWAY1=192.168.1.7
+METRIC1=3
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy
new file mode 100644
index 000000000..cb7d42bde
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route-test-wired-static-routes-legacy
@@ -0,0 +1,7 @@
+# Test route file in legacy format; i.e. lines passed as argumet to "ip route add"
+
+
+21.31.41.0/24 via 9.9.9.9 metric 1
+ via 8.8.8.8 to 32.42.52.62
+ 43.53.0.0/16 metric 3 via 7.7.7.7 dev eth2
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual
new file mode 100644
index 000000000..ae4e47ae5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/route6-test-wired-ipv6-manual
@@ -0,0 +1 @@
+9876::1234/96 via 9876::7777 metric 2
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem
new file mode 100644
index 000000000..dec9aa1b8
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test1_key_and_cert.pem
@@ -0,0 +1,118 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,4DE0615F23D82107
+
+QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz
+L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7
+zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU
+h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW
+ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv
+QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na
+eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo
+cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m
+RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8
+xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr
+T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI
+ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo
+RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ
+EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt
+lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5
+r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4
+aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W
+GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e
+DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE
+lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO
+8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3
+VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt
+G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ
+tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW
+QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1
+-----END RSA PRIVATE KEY-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com
+ Validity
+ Not Before: Mar 10 15:13:16 2009 GMT
+ Not After : Mar 8 15:13:16 2019 GMT
+ Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (2048 bit)
+ Modulus (2048 bit):
+ 00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a:
+ 82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48:
+ ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49:
+ c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8:
+ 03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14:
+ ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9:
+ c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c:
+ 60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d:
+ 44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b:
+ f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d:
+ c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75:
+ d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2:
+ 06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38:
+ ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba:
+ ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36:
+ 2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11:
+ a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f:
+ a3:43
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C
+ X509v3 Authority Key Identifier:
+ keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10
+ DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com
+ serial:EB:E7:64:FB:79:F7:22:19
+
+ Signature Algorithm: md5WithRSAEncryption
+ 7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82:
+ f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89:
+ b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b:
+ 12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76:
+ 1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48:
+ 32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02:
+ 85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1:
+ fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c:
+ cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43:
+ 8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71:
+ 1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19:
+ 07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69:
+ 7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62:
+ 8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7:
+ 3b:65:fe:f9
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx
+EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO
+TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx
+HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN
+MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl
+MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG
+A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR
+XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA
+vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9
+jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF
+TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX
+gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj
+ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
+YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww
+gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx
+FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD
+VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3
+IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/
+DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2
+8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr
+vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD
+T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa
+PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk=
+-----END CERTIFICATE-----
diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem
new file mode 100644
index 000000000..ef1be20d2
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/test_ca_cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw
+FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE
+AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx
+NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ
+QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55
+IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3
+DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU
+xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc
+Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3
+FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4
+HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm
+J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P
+T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF
+ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO
+BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL
+EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl
+c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
+AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc
+JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT
+p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t
+qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn
+B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp
+3nniskIjbH0xjgZf/nVMyLnjxg==
+-----END CERTIFICATE-----
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
new file mode 100644
index 000000000..a6c54fd3d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils.c
@@ -0,0 +1,164 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2009 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "nm-test-helpers.h"
+
+#include "common.h"
+#include "utils.h"
+
+
+static void
+test_get_ifcfg_name (const char *desc,
+ const char *path,
+ gboolean only_ifcfg,
+ const char *expected)
+{
+ const char *result;
+
+ result = utils_get_ifcfg_name (path, only_ifcfg);
+ if (expected == NULL) {
+ ASSERT (result == NULL, desc, "unexpected valid ifcfg name '%s'", result);
+ } else {
+ ASSERT (result != NULL, desc, "failed to create ifcfg name for '%s'", path);
+
+ ASSERT (strcmp (result, expected) == 0,
+ desc, "unexpected ifcfg name '%s' created for '%s'", result, path);
+ }
+}
+
+static void
+test_get_ifcfg_path (const char *desc,
+ const char *path,
+ const char *expected)
+{
+ const char *result;
+
+ result = utils_get_ifcfg_path (path);
+ if (expected == NULL) {
+ ASSERT (result == NULL, desc, "unexpected valid ifcfg name '%s'", result);
+ } else {
+ ASSERT (result != NULL, desc, "failed to create ifcfg name for '%s'", path);
+
+ ASSERT (strcmp (result, expected) == 0,
+ desc, "unexpected ifcfg name '%s' created for '%s'", result, path);
+ }
+}
+
+static void
+test_get_keys_path (const char *desc,
+ const char *path,
+ const char *expected)
+{
+ const char *result;
+
+ result = utils_get_keys_path (path);
+ if (expected == NULL) {
+ ASSERT (result == NULL, desc, "unexpected valid extra path '%s'", result);
+ } else {
+ ASSERT (result != NULL, desc, "failed to create extra path for '%s'", path);
+
+ ASSERT (strcmp (result, expected) == 0,
+ desc, "unexpected extra path '%s' created for '%s'", result, path);
+ }
+}
+
+static void
+test_get_route_path (const char *desc,
+ const char *path,
+ const char *expected)
+{
+ const char *result;
+
+ result = utils_get_route_path (path);
+ if (expected == NULL) {
+ ASSERT (result == NULL, desc, "unexpected valid extra path '%s'", result);
+ } else {
+ ASSERT (result != NULL, desc, "failed to create extra path for '%s'", path);
+
+ ASSERT (strcmp (result, expected) == 0,
+ desc, "unexpected extra path '%s' created for '%s'", result, path);
+ }
+}
+
+static void
+test_ignored (const char *desc, const char *path, gboolean expected_ignored)
+{
+ gboolean result;
+
+ result = utils_should_ignore_file (path, FALSE);
+ ASSERT (result == expected_ignored, desc, "unexpected ignore result for path '%s'", path);
+}
+
+int main (int argc, char **argv)
+{
+ char *base;
+
+ /* The tests */
+ test_get_ifcfg_name ("get-ifcfg-name-bad", "/foo/bar/adfasdfadf", FALSE, NULL);
+ test_get_ifcfg_name ("get-ifcfg-name-good", "/foo/bar/ifcfg-FooBar", FALSE, "FooBar");
+ test_get_ifcfg_name ("get-ifcfg-name-keys", "/foo/bar/keys-BlahLbah", FALSE, "BlahLbah");
+ test_get_ifcfg_name ("get-ifcfg-name-route", "/foo/bar/route-Lalalala", FALSE, "Lalalala");
+ test_get_ifcfg_name ("get-ifcfg-name-only-ifcfg-route", "/foo/bar/route-Lalalala", TRUE, NULL);
+ test_get_ifcfg_name ("get-ifcfg-name-only-ifcfg-keys", "/foo/bar/keys-Lalalala", TRUE, NULL);
+ test_get_ifcfg_name ("get-ifcfg-name-no-path-ifcfg", "ifcfg-Lalalala", FALSE, "Lalalala");
+ test_get_ifcfg_name ("get-ifcfg-name-no-path-keys", "keys-Lalalala", FALSE, "Lalalala");
+ test_get_ifcfg_name ("get-ifcfg-name-no-path-route", "route-Lalalala", FALSE, "Lalalala");
+
+ test_get_ifcfg_name ("get-ifcfg-name-bad2-ifcfg", "/foo/bar/asdfasifcfg-Foobar", FALSE, NULL);
+ test_get_ifcfg_name ("get-ifcfg-name-bad2-keys", "/foo/bar/asdfaskeys-Foobar", FALSE, NULL);
+ test_get_ifcfg_name ("get-ifcfg-name-bad2-route", "/foo/bar/asdfasroute-Foobar", FALSE, NULL);
+
+ test_get_ifcfg_path ("ifcfg-path-bad", "/foo/bar/adfasdfasdf", NULL);
+ test_get_ifcfg_path ("ifcfg-path-from-keys-no-path", "keys-BlahBlah", "ifcfg-BlahBlah");
+ test_get_ifcfg_path ("ifcfg-path-from-keys", "/foo/bar/keys-BlahBlah", "/foo/bar/ifcfg-BlahBlah");
+ test_get_ifcfg_path ("ifcfg-path-from-route", "/foo/bar/route-BlahBlah", "/foo/bar/ifcfg-BlahBlah");
+
+ test_get_keys_path ("keys-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL);
+ test_get_keys_path ("keys-path-from-ifcfg-no-path", "ifcfg-FooBar", "keys-FooBar");
+ test_get_keys_path ("keys-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/keys-FooBar");
+ test_get_keys_path ("keys-path-from-route", "/foo/bar/route-FooBar", "/foo/bar/keys-FooBar");
+
+ test_get_route_path ("route-path-bad", "/foo/bar/asdfasdfasdfasdf", NULL);
+ test_get_route_path ("route-path-from-ifcfg-no-path", "ifcfg-FooBar", "route-FooBar");
+ test_get_route_path ("route-path-from-ifcfg", "/foo/bar/ifcfg-FooBar", "/foo/bar/route-FooBar");
+ test_get_route_path ("route-path-from-keys", "/foo/bar/keys-FooBar", "/foo/bar/route-FooBar");
+
+ test_ignored ("ignored-ifcfg", "ifcfg-FooBar", FALSE);
+ test_ignored ("ignored-keys", "keys-FooBar", FALSE);
+ test_ignored ("ignored-route", "route-FooBar", FALSE);
+ test_ignored ("ignored-bak", "ifcfg-FooBar" BAK_TAG, TRUE);
+ test_ignored ("ignored-tilde", "ifcfg-FooBar" TILDE_TAG, TRUE);
+ test_ignored ("ignored-orig", "ifcfg-FooBar" ORIG_TAG, TRUE);
+ test_ignored ("ignored-rej", "ifcfg-FooBar" REJ_TAG, TRUE);
+ test_ignored ("ignored-rpmnew", "ifcfg-FooBar" RPMNEW_TAG, TRUE);
+ test_ignored ("ignored-augnew", "ifcfg-FooBar" AUGNEW_TAG, TRUE);
+ test_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE);
+
+ base = g_path_get_basename (argv[0]);
+ fprintf (stdout, "%s: SUCCESS\n", base);
+ g_free (base);
+ return 0;
+}
+
diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
new file mode 100644
index 000000000..ebe9e47fb
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c
@@ -0,0 +1,10849 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <netinet/ether.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <nm-utils.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-serial.h>
+
+#include "nm-test-helpers.h"
+
+#include "common.h"
+#include "reader.h"
+#include "writer.h"
+#include "utils.h"
+
+#if 0
+static void
+connection_diff (NMConnection *a, NMConnection *b)
+{
+ GHashTable *hash;
+ GHashTableIter iter, siter;
+ const char *setting_name, *key;
+ GHashTable *setting_hash = NULL;
+
+ if (!nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &hash)) {
+ g_hash_table_iter_init (&iter, hash);
+ while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) {
+ g_hash_table_iter_init (&siter, setting_hash);
+ while (g_hash_table_iter_next (&siter, (gpointer) &key, NULL))
+ g_message (":: %s :: %s", setting_name,key);
+ }
+ g_hash_table_destroy (hash);
+ }
+}
+#endif
+
+typedef enum {
+ CK_CA_CERT = 0,
+ CK_CLIENT_CERT = 1,
+ CK_PRIV_KEY = 2
+} CertKeyType;
+
+static gboolean
+verify_cert_or_key (CertKeyType ck_type,
+ NMSetting8021x *s_compare,
+ const char *file,
+ const char *privkey_password,
+ const char *ifcfg,
+ const char *test_name,
+ const char *setting_key)
+{
+ NMSetting8021x *s_8021x;
+ GError *error = NULL;
+ gboolean success = FALSE;
+ const char *expected = NULL, *setting = NULL;
+ gboolean phase2 = FALSE;
+ NMSetting8021xCKScheme scheme = NM_SETTING_802_1X_CK_SCHEME_UNKNOWN;
+
+ if (strstr (setting_key, "phase2"))
+ phase2 = TRUE;
+
+ /* CA Cert */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ test_name, "failed to verify %s: could not create temp 802.1x setting",
+ ifcfg);
+
+ if (ck_type == CK_CA_CERT) {
+ if (phase2)
+ success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ else
+ success = nm_setting_802_1x_set_ca_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ } else if (ck_type == CK_CLIENT_CERT) {
+ if (phase2)
+ success = nm_setting_802_1x_set_phase2_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ else
+ success = nm_setting_802_1x_set_client_cert (s_8021x, file, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ } else if (ck_type == CK_PRIV_KEY) {
+ if (phase2)
+ success = nm_setting_802_1x_set_phase2_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ else
+ success = nm_setting_802_1x_set_private_key (s_8021x, file, privkey_password, NM_SETTING_802_1X_CK_SCHEME_PATH, NULL, &error);
+ }
+ ASSERT (success == TRUE,
+ test_name, "failed to verify %s: could not load item for %s / %s: %s",
+ ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key, error->message);
+
+ if (ck_type == CK_CA_CERT) {
+ if (phase2)
+ scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (s_8021x);
+ else
+ scheme = nm_setting_802_1x_get_ca_cert_scheme (s_8021x);
+ } else if (ck_type == CK_CLIENT_CERT) {
+ if (phase2)
+ scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (s_8021x);
+ else
+ scheme = nm_setting_802_1x_get_client_cert_scheme (s_8021x);
+ } else if (ck_type == CK_PRIV_KEY) {
+ if (phase2)
+ scheme = nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x);
+ else
+ scheme = nm_setting_802_1x_get_private_key_scheme (s_8021x);
+ }
+ ASSERT (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
+ test_name, "failed to verify %s: unexpected cert/key scheme for %s / %s",
+ ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key);
+
+ if (ck_type == CK_CA_CERT) {
+ if (phase2)
+ expected = nm_setting_802_1x_get_phase2_ca_cert_path (s_8021x);
+ else
+ expected = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ } else if (ck_type == CK_CLIENT_CERT) {
+ if (phase2)
+ expected = nm_setting_802_1x_get_phase2_client_cert_path (s_8021x);
+ else
+ expected = nm_setting_802_1x_get_client_cert_path (s_8021x);
+ } else if (ck_type == CK_PRIV_KEY) {
+ if (phase2)
+ expected = nm_setting_802_1x_get_phase2_private_key_path (s_8021x);
+ else
+ expected = nm_setting_802_1x_get_private_key_path (s_8021x);
+ }
+ ASSERT (expected != NULL,
+ test_name, "failed to verify %s: failed to get read item for %s / %s",
+ ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key);
+
+ if (ck_type == CK_CA_CERT) {
+ if (phase2)
+ setting = nm_setting_802_1x_get_phase2_ca_cert_path (s_compare);
+ else
+ setting = nm_setting_802_1x_get_ca_cert_path (s_compare);
+ } else if (ck_type == CK_CLIENT_CERT) {
+ if (phase2)
+ setting = nm_setting_802_1x_get_phase2_client_cert_path (s_compare);
+ else
+ setting = nm_setting_802_1x_get_client_cert_path (s_compare);
+ } else if (ck_type == CK_PRIV_KEY) {
+ if (phase2)
+ setting = nm_setting_802_1x_get_phase2_private_key_path (s_compare);
+ else
+ setting = nm_setting_802_1x_get_private_key_path (s_compare);
+ }
+ ASSERT (setting != NULL,
+ test_name, "failed to verify %s: missing %s / %s key",
+ ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key);
+
+ ASSERT (strlen (setting) == strlen (expected),
+ test_name, "failed to verify %s: unexpected %s / %s certificate length",
+ test_name, NM_SETTING_802_1X_SETTING_NAME, setting_key);
+
+ ASSERT (strcmp (setting, expected) == 0,
+ test_name, "failed to verify %s: %s / %s key certificate mismatch",
+ ifcfg, NM_SETTING_802_1X_SETTING_NAME, setting_key);
+
+ g_object_unref (s_8021x);
+ return TRUE;
+}
+
+
+#define TEST_IFCFG_MINIMAL TEST_IFCFG_DIR"/network-scripts/ifcfg-test-minimal"
+
+static void
+test_read_minimal (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 };
+ const char *expected_id = "System test-minimal";
+ guint64 expected_timestamp = 0;
+
+ connection = connection_from_file (TEST_IFCFG_MINIMAL,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "minimal-wired-read", "failed to read %s: %s", TEST_IFCFG_MINIMAL, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "minimal-wired-verify", "failed to verify %s: %s", TEST_IFCFG_MINIMAL, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "minimal-wired-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "minimal-wired-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "minimal-wired-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "minimal-wired-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "minimal-wired-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "minimal-wired-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "minimal-wired-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wired_get_mtu (s_wired) == 0,
+ "minimal-wired-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MTU);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "minimal-wired-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "minimal-wired-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE,
+ "minimal-wired-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_MINIMAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_UNMANAGED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-nm-controlled"
+
+static void
+test_read_unmanaged (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0xf8, 0x9f };
+ const char *expected_id = "System test-nm-controlled";
+ guint64 expected_timestamp = 0;
+
+ connection = connection_from_file (TEST_IFCFG_UNMANAGED,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "unmanaged-read", "failed to read %s: %s", TEST_IFCFG_UNMANAGED, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "unmanaged-verify", "failed to verify %s: %s", TEST_IFCFG_UNMANAGED, error->message);
+
+ ASSERT (unmanaged != NULL,
+ "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED);
+
+ ASSERT (strcmp (unmanaged, "mac:00:11:22:33:f8:9f") == 0,
+ "unmanaged-verify", "failed to verify %s: expected unmanaged", TEST_IFCFG_UNMANAGED);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "unmanaged-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "unmanaged-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "unmanaged-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "unmanaged-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ /* Since the unmanaged connections are not completely read, defaults will
+ * be used for many settings.
+ */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "unmanaged-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "unmanaged-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "unmanaged-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "unmanaged-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "unmanaged-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 == NULL,
+ "unmanaged-verify-ip4", "failed to verify %s: unexpected %s setting",
+ TEST_IFCFG_UNMANAGED,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ g_object_unref (connection);
+}
+
+static void
+test_read_wired_static (const char *file, const char *expected_id)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = FALSE;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee };
+ const char *tmp;
+ const char *expected_dns1 = "4.2.2.1";
+ const char *expected_dns2 = "4.2.2.2";
+ struct in_addr addr;
+ struct in6_addr addr6;
+ const char *expected_address1 = "192.168.1.5";
+ const char *expected_address1_gw = "192.168.1.1";
+ const char *expected6_address1 = "dead:beaf::1";
+ const char *expected6_address2 = "dead:beaf::2";
+ const char *expected6_dns1 = "1:2:3:4::a";
+ const char *expected6_dns2 = "1:2:3:4::b";
+ NMIP4Address *ip4_addr;
+ NMIP6Address *ip6_addr;
+
+ connection = connection_from_file (file,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-static-read", "failed to read %s: %s", file, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-static-verify", "failed to verify %s: %s", file, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-static-verify", "failed to verify %s: unexpected unmanaged value", file);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-static-verify-connection", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-static-verify-connection", "failed to verify %s: missing %s / %s key",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-static-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == 0,
+ "wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "wired-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-static-verify-wired", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "wired-static-verify-wired", "failed to verify %s: missing %s / %s key",
+ file,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ file,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wired_get_mtu (s_wired) == 1492,
+ "wired-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MTU);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-static-verify-ip4", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* Implicit may-fail */
+ ASSERT (nm_setting_ip4_config_get_may_fail (s_ip4) == FALSE,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_MAY_FAIL);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+ "wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+ "wired-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* Address #1 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+ ASSERT (ip4_addr,
+ "wired-static-verify-ip4", "failed to verify %s: missing IP4 address #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
+ "wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
+ "wired-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+ ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
+ "wired-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ if (!strcmp (expected_id, "System test-wired-static")) {
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-static-verify-ip6", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ /* Implicit may-fail */
+ ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_MAY_FAIL);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected6_dns1, &addr6) > 0,
+ "wired-static-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1",
+ file);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6),
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected6_dns2, &addr6) > 0,
+ "wired-static-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #2",
+ file);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6),
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value #2",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 2,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ /* Address #1 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+ ASSERT (ip6_addr,
+ "wired-static-verify-ip6", "failed to verify %s: missing IP6 address #1",
+ file);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix",
+ file);
+
+ ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0,
+ "wired-static-verify-ip6", "failed to verify %s: couldn't convert IP address #1",
+ file);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
+ "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #1",
+ file);
+
+ /* Address #2 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1);
+ ASSERT (ip6_addr,
+ "wired-static-verify-ip6", "failed to verify %s: missing IP6 address #2",
+ file);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 56,
+ "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #2 prefix",
+ file);
+
+ ASSERT (inet_pton (AF_INET6, expected6_address2, &addr6) > 0,
+ "wired-static-verify-ip6", "failed to verify %s: couldn't convert IP address #2",
+ file);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
+ "wired-static-verify-ip6", "failed to verify %s: unexpected IP6 address #2",
+ file);
+ }
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_STATIC_NO_PREFIX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-no-prefix"
+
+static void
+test_read_wired_static_no_prefix (guint32 expected_prefix)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = FALSE;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ NMIP4Address *ip4_addr;
+ char *file, *expected_id;
+ const char *tmp;
+
+ file = g_strdup_printf (TEST_IFCFG_STATIC_NO_PREFIX "-%u", expected_prefix);
+ ASSERT (file != NULL,
+ "wired-static-no-prefix-read", "failed to create path to file");
+
+ expected_id = g_strdup_printf ("System test-wired-static-no-prefix-%u", expected_prefix);
+ ASSERT (expected_id != NULL,
+ "wired-static-no-prefix-read", "failed to expected connection ID");
+
+ connection = connection_from_file (file,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-static-no-prefix-read", "failed to read %s: %s", file, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-static-no-prefix-verify", "failed to verify %s: %s", file, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-static-no-prefix-verify", "failed to verify %s: unexpected unmanaged value", file);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-static-no-prefix-verify-connection", "failed to verify %s: missing %s / %s key",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-static-no-prefix-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ g_free (expected_id);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing %s setting",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
+ "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* Address #1 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+ ASSERT (ip4_addr,
+ "wired-static-no-prefix-verify-ip4", "failed to verify %s: missing IP4 address #1",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == expected_prefix,
+ "wired-static-no-prefix-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
+ file,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ g_free (file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_DHCP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp"
+
+static void
+test_read_wired_dhcp (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0xee };
+ const char *tmp;
+ const char *expected_id = "System test-wired-dhcp";
+ const char *expected_dns1 = "4.2.2.1";
+ const char *expected_dns2 = "4.2.2.2";
+ struct in_addr addr;
+ const char *expected_dhcp_hostname = "foobar";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_DHCP,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-dhcp-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-dhcp-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-dhcp-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-dhcp-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == 0,
+ "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "wired-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-dhcp-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "wired-dhcp-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "wired-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-dhcp-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ tmp = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
+ ASSERT (tmp != NULL,
+ "wired-dhcp-verify-ip4", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME);
+ ASSERT (strcmp (tmp, expected_dhcp_hostname) == 0,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME);
+
+ ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+ "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+ "wired-dhcp-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+ "wired-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-global-gateway"
+#define TEST_NETWORK_WIRED_GLOBAL_GATEWAY TEST_IFCFG_DIR"/network-scripts/network-test-wired-global-gateway"
+
+static void
+test_read_wired_global_gateway (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-global-gateway";
+ struct in_addr addr;
+ const char *expected_address1 = "192.168.1.5";
+ const char *expected_address1_gw = "192.168.1.2";
+ NMIP4Address *ip4_addr;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ TEST_NETWORK_WIRED_GLOBAL_GATEWAY,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-global-gateway-read", "failed to read %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-global-gateway-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_GLOBAL_GATEWAY, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-global-gateway-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_GLOBAL_GATEWAY);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-global-gateway-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-global-gateway-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-global-gateway-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-global-gateway-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* Address #1 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+ ASSERT (ip4_addr,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: missing IP4 address #1",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+ ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
+ "wired-global-gateway-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway",
+ TEST_IFCFG_WIRED_GLOBAL_GATEWAY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-never-default"
+#define TEST_NETWORK_WIRED_NEVER_DEFAULT TEST_IFCFG_DIR"/network-scripts/network-test-wired-never-default"
+
+static void
+test_read_wired_never_default (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-never-default";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ TEST_NETWORK_WIRED_NEVER_DEFAULT,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-never-default-read", "failed to read %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-never-default-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_NEVER_DEFAULT, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-never-default-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_NEVER_DEFAULT);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-never-default-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-never-default-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-never-default-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-never-default-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-never-default-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE,
+ "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 0,
+ "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-never-default-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0,
+ "wired-never-default-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE,
+ "wired-never-default-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_NEVER_DEFAULT,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_DEFROUTE_NO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no"
+
+static void
+test_read_wired_defroute_no (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-defroute-no";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-defroute-no-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-defroute-no-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DEFROUTE_NO, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-defroute-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DEFROUTE_NO);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-defroute-no-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-defroute-no-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-defroute-no-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-defroute-no-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-defroute-no-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == TRUE,
+ "wired-defroute-no-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-defroute-no-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0,
+ "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == TRUE,
+ "wired-defroute-no-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-defroute-no-gatewaydev-yes"
+#define TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES TEST_IFCFG_DIR"/network-scripts/network-test-wired-defroute-no-gatewaydev-yes"
+
+static void
+test_read_wired_defroute_no_gatewaydev_yes (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-defroute-no-gatewaydev-yes";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ TEST_NETWORK_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-defroute-no-gatewaydev-yes-read",
+ "failed to read %s: %s",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-defroute-no-gatewaydev-yes-verify",
+ "failed to verify %s: %s",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-defroute-no-gatewaydev-yes-verify",
+ "failed to verify %s: unexpected unmanaged value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-defroute-no-gatewaydev-yes-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-defroute-no-gatewaydev-yes-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE,
+ "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-defroute-no-gatewaydev-yes-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE,
+ "wired-defroute-no-gatewaydev-yes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DEFROUTE_NO_GATEWAYDEV_YES,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_STATIC_ROUTES TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes"
+
+static void
+test_read_wired_static_routes (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ NMIP4Route *ip4_route;
+ struct in_addr addr;
+ const char *expected_id = "System test-wired-static-routes";
+ const char *expected_dst1 = "11.22.33.0";
+ const char *expected_dst2 = "44.55.66.77";
+ const char *expected_gw1 = "192.168.1.5";
+ const char *expected_gw2 = "192.168.1.7";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+
+ ASSERT (connection != NULL,
+ "wired-static-routes-read",
+ "failed to read %s: %s",
+ TEST_IFCFG_WIRED_STATIC_ROUTES, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-static-routes-verify", "failed to verify %s: %s",
+ TEST_IFCFG_WIRED_STATIC_ROUTES, error->message);
+
+ ASSERT (unmanaged == NULL,
+ "wired-static-routes-verify",
+ "failed to verify %s: unexpected unmanaged value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-static-routes-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-static-routes-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-static-routes-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-static-routes-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-static-routes-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* Routes */
+ ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 2,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0);
+ ASSERT (ip4_route,
+ "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0,
+ "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+ ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0,
+ "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+ ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1);
+ ASSERT (ip4_route,
+ "wired-static-routes-verify-ip4", "failed to verify %s: missing IP4 route #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0,
+ "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+ ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0,
+ "wired-static-routes-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+ ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+ ASSERT (nm_ip4_route_get_metric (ip4_route) == 3,
+ "wired-static-routes-verify-ip4", "failed to verify %s: unexpected route metric #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES);
+
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-routes-legacy"
+
+static void
+test_read_wired_static_routes_legacy (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ NMIP4Route *ip4_route;
+ struct in_addr addr;
+ const char *expected_id = "System test-wired-static-routes-legacy";
+ const char *expected_dst1 = "21.31.41.0";
+ const char *expected_dst2 = "32.42.52.62";
+ const char *expected_dst3 = "43.53.0.0";
+ const char *expected_gw1 = "9.9.9.9";
+ const char *expected_gw2 = "8.8.8.8";
+ const char *expected_gw3 = "7.7.7.7";
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+
+ ASSERT (connection != NULL,
+ "wired-static-routes-legacy-read",
+ "failed to read %s: %s",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-static-routes-legacy-verify", "failed to verify %s: %s",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY, error->message);
+
+ ASSERT (unmanaged == NULL,
+ "wired-static-routes-legacy-verify",
+ "failed to verify %s: unexpected unmanaged value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-static-routes-legacy-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-static-routes-legacy-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* Routes */
+ ASSERT (nm_setting_ip4_config_get_num_routes (s_ip4) == 3,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ /* Route #1 */
+ ip4_route = nm_setting_ip4_config_get_route (s_ip4, 0);
+ ASSERT (ip4_route,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_dst1, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_prefix (ip4_route) == 24,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 prefix",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_gw1, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_metric (ip4_route) == 1,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #1 metric",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ /* Route #2 */
+ ip4_route = nm_setting_ip4_config_get_route (s_ip4, 1);
+ ASSERT (ip4_route,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_dst2, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_prefix (ip4_route) == 32,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 prefix",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_gw2, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_metric (ip4_route) == 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #2 metric",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ /* Route #3 */
+ ip4_route = nm_setting_ip4_config_get_route (s_ip4, 2);
+ ASSERT (ip4_route,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: missing IP4 route #3",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_dst3, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert destination IP address #3",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_dest (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_prefix (ip4_route) == 16,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 prefix",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ ASSERT (inet_pton (AF_INET, expected_gw3, &addr) > 0,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: couldn't convert next hop IP address #3",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+ ASSERT (nm_ip4_route_get_next_hop (ip4_route) == addr.s_addr,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value #3",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES);
+
+ ASSERT (nm_ip4_route_get_metric (ip4_route) == 3,
+ "wired-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected destination route #3 metric",
+ TEST_IFCFG_WIRED_STATIC_ROUTES_LEGACY);
+
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_IPV6_MANUAL TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-manual"
+
+static void
+test_read_wired_ipv6_manual (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-ipv6-manual";
+ const char *expected_address1 = "1001:abba::1234";
+ const char *expected_address2 = "2001:abba::2234";
+ const char *expected_address3 = "3001:abba::3234";
+ guint32 expected_prefix1 = 56;
+ guint32 expected_prefix2 = 64;
+ guint32 expected_prefix3 = 96;
+ const char *expected_route1_dest = "9876::1234";
+ guint32 expected_route1_prefix = 96;
+ const char *expected_route1_nexthop = "9876::7777";
+ guint32 expected_route1_metric = 2;
+ const char *expected_dns1 = "1:2:3:4::a";
+ const char *expected_dns2 = "1:2:3:4::b";
+ NMIP6Address *ip6_addr;
+ NMIP6Route *ip6_route;
+ struct in6_addr addr;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-ipv6-manual-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_MANUAL, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-ipv6-manual-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_MANUAL, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-ipv6-manual-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-ipv6-manual-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-ipv6-manual-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-ipv6-manual-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* DNS search domains */
+ ASSERT (nm_setting_ip4_config_get_num_dns_searches (s_ip4) == 3,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 0);
+ ASSERT (tmp != NULL,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+ ASSERT (strcmp (tmp, "lorem.com") == 0,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+ tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 1);
+ ASSERT (tmp != NULL,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+ ASSERT (strcmp (tmp, "ipsum.org") == 0,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+ tmp = nm_setting_ip4_config_get_dns_search (s_ip4, 2);
+ ASSERT (tmp != NULL,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+ ASSERT (strcmp (tmp, "dolor.edu") == 0,
+ "wired-ipv6-manual-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS_SEARCH);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip6_config_get_never_default (s_ip6) == FALSE,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT);
+
+ ASSERT (nm_setting_ip6_config_get_may_fail (s_ip6) == TRUE,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_MAY_FAIL);
+
+ /* IP addresses */
+ ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 3,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ /* Address #1 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+ ASSERT (ip6_addr,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* Address #2 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1);
+ ASSERT (ip6_addr,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #2",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix2,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2 prefix",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_address2, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #2",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #2",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* Address #3 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 2);
+ ASSERT (ip6_addr,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 address #3",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix3,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3 prefix",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_address3, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP address #3",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 address #3",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* Routes */
+ ASSERT (nm_setting_ip6_config_get_num_routes (s_ip6) == 1,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ /* Route #1 */
+ ip6_route = nm_setting_ip6_config_get_route (s_ip6, 0);
+ ASSERT (ip6_route,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: missing IP6 route #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_route1_dest, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP route dest #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_dest (ip6_route), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route dest #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_route_get_prefix (ip6_route) == expected_route1_prefix,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route #1 prefix",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_route1_nexthop, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert IP route next_hop #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_next_hop (ip6_route), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route next hop #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_route_get_metric (ip6_route) == expected_route1_metric,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected IP6 route #1 metric",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected_dns2, &addr) > 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr),
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ /* DNS domains - none as domains are stuffed to 'ipv4' setting */
+ ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0,
+ "wired-ipv6-manual-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_IPV6_ONLY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-ipv6-only"
+
+static void
+test_read_wired_ipv6_only (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-ipv6-only";
+ const char *expected_address1 = "1001:abba::1234";
+ guint32 expected_prefix1 = 56;
+ const char *expected_dns1 = "1:2:3:4::a";
+ NMIP6Address *ip6_addr;
+ struct in6_addr addr;
+ const char *method;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-ipv6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-ipv6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_IPV6_ONLY, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-ipv6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-ipv6-only-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-ipv6-only-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-ipv6-only-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ method = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
+ "wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ /* IP addresses */
+ ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ /* Address #1 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+ ASSERT (ip6_addr,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: missing IP6 address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == expected_prefix1,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1 prefix",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ ASSERT (inet_pton (AF_INET6, expected_address1, &addr) > 0,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert IP address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr),
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected IP6 address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 1,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected_dns1, &addr) > 0,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr),
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ /* DNS domains - none as domains are stuffed to 'ipv4' setting */
+ ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 0,
+ "wired-ipv6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_IPV6_MANUAL,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_DHCP6_ONLY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-dhcp6-only"
+
+static void
+test_read_wired_dhcp6_only (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-dhcp6-only";
+ const char *method;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-dhcp6-only-read", "failed to read %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-dhcp6-only-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_DHCP6_ONLY, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-dhcp6-only-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_DHCP6_ONLY);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-dhcp6-only-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-dhcp6-only-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-dhcp6-only-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-dhcp6-only-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ method = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
+ "wired-dhcp6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "wired-dhcp6-only-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0,
+ "wired-dhcp6-only-verify-ip6", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_DHCP6_ONLY,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_ONBOOT_NO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-onboot-no"
+
+static void
+test_read_onboot_no (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ connection = connection_from_file (TEST_IFCFG_ONBOOT_NO,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "onboot-no-read", "failed to read %s: %s", TEST_IFCFG_ONBOOT_NO, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "onboot-no-verify", "failed to verify %s: %s", TEST_IFCFG_ONBOOT_NO, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "onboot-no-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_ONBOOT_NO);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "onboot-no-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_ONBOOT_NO,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE,
+ "onboot-no-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_ONBOOT_NO,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-peap-mschapv2"
+#define TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem"
+
+static void
+test_read_wired_8021x_peap_mschapv2 (void)
+{
+ NMConnection *connection;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSetting8021x *s_8021x;
+ NMSetting8021x *tmp_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_identity = "David Smith";
+ const char *expected_password = "foobar baz";
+ gboolean success = FALSE;
+ const char *expected_ca_cert_path;
+ const char *read_ca_cert_path;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-8021x-peap-mschapv2-read", "failed to read %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-8021x-peap-mschapv2-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-8021x-peap-mschapv2-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-8021x-peap-mschapv2-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wired-8021x-peap-mschapv2-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+ ASSERT (s_8021x != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ /* EAP methods */
+ ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ ASSERT (tmp != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ ASSERT (strcmp (tmp, "peap") == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+
+ /* Identity */
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ ASSERT (tmp != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+ ASSERT (strcmp (tmp, expected_identity) == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+
+ /* Password */
+ tmp = nm_setting_802_1x_get_password (s_8021x);
+ ASSERT (tmp != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PASSWORD);
+ ASSERT (strcmp (tmp, expected_password) == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PASSWORD);
+
+ /* PEAP version */
+ tmp = nm_setting_802_1x_get_phase1_peapver (s_8021x);
+ ASSERT (tmp != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE1_PEAPVER);
+ ASSERT (strcmp (tmp, "1") == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE1_PEAPVER);
+
+ /* PEAP Label */
+ tmp = nm_setting_802_1x_get_phase1_peaplabel (s_8021x);
+ ASSERT (tmp != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE1_PEAPLABEL);
+ ASSERT (strcmp (tmp, "1") == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE1_PEAPLABEL);
+
+ /* CA Cert */
+ tmp_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (tmp_8021x != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: could not create temp 802.1x setting",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ success = nm_setting_802_1x_set_ca_cert (tmp_8021x,
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: could not load CA certificate",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT);
+ expected_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (tmp_8021x);
+ ASSERT (expected_ca_cert_path != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: failed to get CA certificate",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT);
+
+ read_ca_cert_path = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ ASSERT (read_ca_cert_path != NULL,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT);
+
+ ASSERT (strcmp (read_ca_cert_path, expected_ca_cert_path) == 0,
+ "wired-8021x-peap-mschapv2-verify-8021x", "failed to verify %s: unexpected %s / %s certificate path",
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT);
+
+ g_object_unref (tmp_8021x);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_8021X_TLS_AGENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-tls-agent"
+#define TEST_IFCFG_WIRED_8021X_TLS_ALWAYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-8021x-tls-always"
+
+static void
+test_read_wired_8021x_tls_secret_flags (const char *ifcfg, NMSettingSecretFlags expected_flags)
+{
+ NMConnection *connection;
+ NMSettingWired *s_wired;
+ NMSetting8021x *s_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *expected_identity = "David Smith";
+ gboolean success = FALSE;
+ char *dirname, *tmp;
+
+ connection = connection_from_file (ifcfg,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ g_assert_no_error (error);
+ g_assert (connection);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* ===== WIRED SETTING ===== */
+ s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+ g_assert (s_wired);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x);
+ g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1);
+ g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "tls");
+ g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, expected_identity);
+ g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, expected_flags);
+
+ dirname = g_path_get_dirname (ifcfg);
+ tmp = g_build_path ("/", dirname, "test_ca_cert.pem", NULL);
+ g_assert_cmpstr (nm_setting_802_1x_get_ca_cert_path (s_8021x), ==, tmp);
+ g_free (tmp);
+
+ tmp = g_build_path ("/", dirname, "test1_key_and_cert.pem", NULL);
+ g_assert_cmpstr (nm_setting_802_1x_get_client_cert_path (s_8021x), ==, tmp);
+ g_assert_cmpstr (nm_setting_802_1x_get_private_key_path (s_8021x), ==, tmp);
+ g_free (tmp);
+
+ g_free (dirname);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_OPEN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open"
+
+static void
+test_read_wifi_open (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 };
+ const char *expected_id = "System blahblah (test-wifi-open)";
+ guint64 expected_timestamp = 0;
+ const char *expected_ssid = "blahblah";
+ const char *expected_mode = "infrastructure";
+ const guint32 expected_channel = 1;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_OPEN,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-open-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-open-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-open-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-open-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-open-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "wifi-open-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "wifi-open-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wireless_get_mac_address (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0,
+ "wifi-open-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MTU);
+
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ ASSERT (nm_setting_wireless_get_security (s_wireless) == NULL,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel,
+ "wifi-open-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CHANNEL);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-open-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-open-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_OPEN_AUTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-auto"
+
+static void
+test_read_wifi_open_auto (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System blahblah (test-wifi-open-auto)";
+ const char *expected_mode = "infrastructure";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_AUTO,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-open-auto-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_AUTO, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-open-auto-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_AUTO, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-open-auto-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-open-auto-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-open-auto-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-open-auto-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-open-auto-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_AUTO,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_OPEN_SSID_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-hex"
+
+static void
+test_read_wifi_open_ssid_hex (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ const char *expected_id = "System blahblah (test-wifi-open-ssid-hex)";
+ const char *expected_ssid = "blahblah";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-open-ssid-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_HEX, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-open-ssid-hex-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_HEX, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-open-ssid-hex-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-open-ssid-hex-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-open-ssid-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_SSID_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ g_object_unref (connection);
+}
+
+static void
+test_read_wifi_open_ssid_bad (const char *file, const char *test)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ connection = connection_from_file (file,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection == NULL, test, "unexpected success reading %s", file);
+ g_clear_error (&error);
+}
+
+#define TEST_IFCFG_WIFI_OPEN_SSID_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-quoted"
+
+static void
+test_read_wifi_open_ssid_quoted (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ const char *expected_id = "System foo\"bar\\ (test-wifi-open-ssid-quoted)";
+ const char *expected_ssid = "foo\"bar\\";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-open-ssid-quoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-open-ssid-quoted-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_OPEN_SSID_QUOTED, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-open-ssid-quoted-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-open-ssid-quoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_OPEN_SSID_QUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep"
+
+static void
+test_read_wifi_wep (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 };
+ const char *expected_id = "System blahblah (test-wifi-wep)";
+ guint64 expected_timestamp = 0;
+ const char *expected_ssid = "blahblah";
+ const char *expected_mode = "infrastructure";
+ const guint32 expected_channel = 1;
+ const char *expected_wep_key0 = "0123456789abcdef0123456789";
+ NMWepKeyType key_type;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wep-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wep-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "wifi-wep-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "wifi-wep-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wireless_get_mac_address (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+
+ /* MTU */
+ ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0,
+ "wifi-wep-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MTU);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ /* BSSID */
+ ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+
+ /* Mode */
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ /* Channel */
+ ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CHANNEL);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key type */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected WEP key type %d",
+ TEST_IFCFG_WIFI_WEP,
+ key_type);
+
+ /* WEP key index 0 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+ ASSERT (strcmp (tmp, expected_wep_key0) == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ /* WEP key index 1 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1);
+ ASSERT (tmp == NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+
+ /* WEP key index 2 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2);
+ ASSERT (tmp == NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+
+ /* WEP key index 3 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3);
+ ASSERT (tmp == NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+
+ /* WEP Authentication mode */
+ tmp = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+ ASSERT (strcmp (tmp, "shared") == 0,
+ "wifi-wep-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wep-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-adhoc"
+
+static void
+test_read_wifi_wep_adhoc (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ const char *expected_id = "System blahblah (test-wifi-wep-adhoc)";
+ const char *expected_ssid = "blahblah";
+ const char *expected_mode = "adhoc";
+ const char *expected_wep_key0 = "0123456789abcdef0123456789";
+ struct in_addr addr;
+ const char *expected_dns1 = "4.2.2.1";
+ const char *expected_dns2 = "4.2.2.2";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_ADHOC,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_ADHOC, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-adhoc-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_ADHOC, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wep-adhoc-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wep-adhoc-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE,
+ "wifi-wep-adhoc-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ /* BSSID */
+ ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+
+ /* Mode */
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ /* Channel */
+ ASSERT (nm_setting_wireless_get_channel (s_wireless) == 11,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CHANNEL);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key index 0 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+ ASSERT (strcmp (tmp, expected_wep_key0) == 0,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ /* WEP key index 1 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1);
+ ASSERT (tmp == NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+
+ /* WEP key index 2 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2);
+ ASSERT (tmp == NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+
+ /* WEP key index 3 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3);
+ ASSERT (tmp == NULL,
+ "wifi-wep-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+
+ /* WEP Authentication mode */
+ tmp = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ ASSERT (tmp == NULL,
+ "wifi-wep-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* Ignore auto DNS */
+ ASSERT (nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) == TRUE,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+ "wifi-wep-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_WIFI_WEP_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_PASSPHRASE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-passphrase"
+
+static void
+test_read_wifi_wep_passphrase (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_wep_key0 = "foobar222blahblah";
+ NMWepKeyType key_type;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-passphrase-read", "failed to read %s: %s",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-passphrase-verify", "failed to verify %s: %s",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-passphrase-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key type */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ ASSERT (key_type == NM_WEP_KEY_TYPE_PASSPHRASE,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected WEP key type %d",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ key_type);
+
+ /* WEP key index 0 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+ ASSERT (strcmp (tmp, expected_wep_key0) == 0,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ /* WEP key index 1 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1);
+ ASSERT (tmp == NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+
+ /* WEP key index 2 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2);
+ ASSERT (tmp == NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+
+ /* WEP key index 3 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3);
+ ASSERT (tmp == NULL,
+ "wifi-wep-passphrase-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_PASSPHRASE,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_40_ASCII TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-40-ascii"
+
+static void
+test_read_wifi_wep_40_ascii (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_wep_key0 = "Lorem";
+ NMWepKeyType key_type;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-40-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_40_ASCII, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-40-ascii-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_40_ASCII, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-40-ascii-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key type */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected WEP key type %d",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ key_type);
+
+ /* WEP key index 0 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+ ASSERT (strcmp (tmp, expected_wep_key0) == 0,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ /* WEP key index 1 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1);
+ ASSERT (tmp == NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+
+ /* WEP key index 2 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2);
+ ASSERT (tmp == NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+
+ /* WEP key index 3 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3);
+ ASSERT (tmp == NULL,
+ "wifi-wep-40-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_40_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_104_ASCII TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-104-ascii"
+
+static void
+test_read_wifi_wep_104_ascii (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_wep_key0 = "LoremIpsumSit";
+ NMWepKeyType key_type;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-104-ascii-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_104_ASCII, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-104-ascii-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_104_ASCII, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-104-ascii-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key type */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected WEP key type %d",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ key_type);
+
+ /* WEP key index 0 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+ ASSERT (strcmp (tmp, expected_wep_key0) == 0,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ /* WEP key index 1 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 1);
+ ASSERT (tmp == NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
+
+ /* WEP key index 2 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 2);
+ ASSERT (tmp == NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
+
+ /* WEP key index 3 */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 3);
+ ASSERT (tmp == NULL,
+ "wifi-wep-104-ascii-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WEP_104_ASCII,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_LEAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap"
+
+static void
+test_read_wifi_leap (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System blahblah (test-wifi-leap)";
+ const char *expected_identity = "Bill Smith";
+ const char *expected_password = "foobarblah";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_LEAP,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-leap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_LEAP, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-leap-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_LEAP, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-leap-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-leap-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-leap-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP Authentication mode */
+ tmp = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+ ASSERT (strcmp (tmp, "leap") == 0,
+ "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+
+ /* LEAP Username */
+ tmp = nm_setting_wireless_security_get_leap_username (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
+ ASSERT (strcmp (tmp, expected_identity) == 0,
+ "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
+
+ /* LEAP Password */
+ tmp = nm_setting_wireless_security_get_leap_password (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-leap-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
+ ASSERT (strcmp (tmp, expected_password) == 0,
+ "wifi-leap-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_LEAP,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_LEAP_AGENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-agent"
+#define TEST_IFCFG_WIFI_LEAP_ALWAYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-leap-always-ask"
+
+static void
+test_read_wifi_leap_secret_flags (const char *file, NMSettingSecretFlags expected_flags)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *expected_identity = "Bill Smith";
+ gboolean success;
+
+ connection = connection_from_file (file,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ g_assert_no_error (error);
+ g_assert (connection);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* ===== WIRELESS SETTING ===== */
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ g_assert (s_wifi);
+
+ g_assert (g_strcmp0 (nm_setting_wireless_get_security (s_wifi), NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ g_assert (s_wsec);
+
+ g_assert (g_strcmp0 (nm_setting_wireless_security_get_key_mgmt (s_wsec), "ieee8021x") == 0);
+ g_assert (g_strcmp0 (nm_setting_wireless_security_get_auth_alg (s_wsec), "leap") == 0);
+ g_assert (g_strcmp0 (nm_setting_wireless_security_get_leap_username (s_wsec), expected_identity) == 0);
+ /* password blank as it's not system-owned */
+ g_assert (nm_setting_wireless_security_get_leap_password_flags (s_wsec) == expected_flags);
+ g_assert (nm_setting_wireless_security_get_leap_password (s_wsec) == NULL);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_PSK TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk"
+
+static void
+test_read_wifi_wpa_psk (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 };
+ const char *expected_id = "System blahblah (test-wifi-wpa-psk)";
+ guint64 expected_timestamp = 0;
+ const char *expected_ssid = "blahblah";
+ const char *expected_mode = "infrastructure";
+ const guint32 expected_channel = 1;
+ const char *expected_key_mgmt = "wpa-psk";
+ const char *expected_psk = "I wonder what the king is doing tonight?";
+ guint32 n, i;
+ gboolean found_pair_tkip = FALSE;
+ gboolean found_pair_ccmp = FALSE;
+ gboolean found_group_tkip = FALSE;
+ gboolean found_group_ccmp = FALSE;
+ gboolean found_group_wep40 = FALSE;
+ gboolean found_group_wep104 = FALSE;
+ gboolean found_proto_wpa = FALSE;
+ gboolean found_proto_rsn = FALSE;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-psk-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-psk-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "wifi-wpa-psk-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wireless_get_mac_address (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS);
+
+ /* MTU */
+ ASSERT (nm_setting_wireless_get_mtu (s_wireless) == 0,
+ "wifi-wpa-psk-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MTU);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ /* BSSID */
+ ASSERT (nm_setting_wireless_get_bssid (s_wireless) == NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+
+ /* Mode */
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ /* Channel */
+ ASSERT (nm_setting_wireless_get_channel (s_wireless) == expected_channel,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CHANNEL);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+ ASSERT (strcmp (tmp, expected_key_mgmt) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* PSK */
+ tmp = nm_setting_wireless_security_get_psk (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+ ASSERT (strcmp (tmp, expected_psk) == 0,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+
+ /* WEP Authentication mode */
+ tmp = nm_setting_wireless_security_get_auth_alg (s_wsec);
+ ASSERT (tmp == NULL,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
+
+ /* Pairwise ciphers */
+ n = nm_setting_wireless_security_get_num_pairwise (s_wsec);
+ ASSERT (n == 2,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+ for (i = 0; i < n; i++) {
+ tmp = nm_setting_wireless_security_get_pairwise (s_wsec, i);
+ ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ if (strcmp (tmp, "tkip") == 0)
+ found_pair_tkip = TRUE;
+ else if (strcmp (tmp, "ccmp") == 0)
+ found_pair_ccmp = TRUE;
+ }
+ ASSERT (found_pair_tkip, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise TKIP cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ ASSERT (found_pair_ccmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing pairwise CCMP cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+
+ /* Group ciphers */
+ n = nm_setting_wireless_security_get_num_groups (s_wsec);
+ ASSERT (n == 4,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_GROUP);
+ for (i = 0; i < n; i++) {
+ tmp = nm_setting_wireless_security_get_group (s_wsec, i);
+ ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ if (strcmp (tmp, "tkip") == 0)
+ found_group_tkip = TRUE;
+ else if (strcmp (tmp, "ccmp") == 0)
+ found_group_ccmp = TRUE;
+ else if (strcmp (tmp, "wep40") == 0)
+ found_group_wep40 = TRUE;
+ else if (strcmp (tmp, "wep104") == 0)
+ found_group_wep104 = TRUE;
+ }
+ ASSERT (found_group_tkip, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group TKIP cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ ASSERT (found_group_ccmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group CCMP cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ ASSERT (found_group_wep40, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group WEP-40 cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ ASSERT (found_group_wep104, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing group WEP-104 cipher",
+ TEST_IFCFG_WIFI_WPA_PSK);
+
+ /* Protocols */
+ n = nm_setting_wireless_security_get_num_protos (s_wsec);
+ ASSERT (n == 2,
+ "wifi-wpa-psk-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PROTO);
+ for (i = 0; i < n; i++) {
+ tmp = nm_setting_wireless_security_get_proto (s_wsec, i);
+ ASSERT (tmp, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protocol",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ if (strcmp (tmp, "wpa") == 0)
+ found_proto_wpa = TRUE;
+ else if (strcmp (tmp, "rsn") == 0)
+ found_proto_rsn = TRUE;
+ }
+ ASSERT (found_proto_wpa, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protoocl WPA",
+ TEST_IFCFG_WIFI_WPA_PSK);
+ ASSERT (found_proto_rsn, "wifi-wpa-psk-verify-wireless", "failed to verify %s: missing protocol RSN",
+ TEST_IFCFG_WIFI_WPA_PSK);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-psk-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wpa-psk-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted"
+
+static void
+test_read_wifi_wpa_psk_unquoted (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System blahblah (test-wifi-wpa-psk-unquoted)";
+ const char *expected_psk = "54336845e2f3f321c4c7";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-psk-unquoted-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-psk-unquoted-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wpa-psk-unquoted-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* PSK */
+ tmp = nm_setting_wireless_security_get_psk (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+ ASSERT (strcmp (tmp, expected_psk) == 0,
+ "wifi-wpa-psk-unquoted-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2 TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-unquoted2"
+
+static void
+test_read_wifi_wpa_psk_unquoted2 (void)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ /* Ensure a quoted 64-character WPA passphrase will fail since passphrases
+ * must be between 8 and 63 ASCII characters inclusive per the WPA spec.
+ */
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection == NULL,
+ "wifi-wpa-psk-unquoted-read", "unexpected success reading %s", TEST_IFCFG_WIFI_WPA_PSK_UNQUOTED2);
+ g_clear_error (&error);
+}
+
+#define TEST_IFCFG_WIFI_WPA_PSK_ADHOC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-adhoc"
+
+static void
+test_read_wifi_wpa_psk_adhoc (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System blahblah (test-wifi-wpa-psk-adhoc)";
+ const char *expected_mode = "adhoc";
+ const char *expected_key_mgmt = "wpa-none";
+ const char *expected_psk = "I wonder what the king is doing tonight?";
+ const char *expected_group = "ccmp";
+ const char *expected_proto = "wpa";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-psk-adhoc-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-psk-adhoc-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_ADHOC, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wpa-psk-adhoc-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Mode */
+ tmp = nm_setting_wireless_get_mode (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+ ASSERT (strcmp (tmp, expected_mode) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+ ASSERT (strcmp (tmp, expected_key_mgmt) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* PSK */
+ tmp = nm_setting_wireless_security_get_psk (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+ ASSERT (strcmp (tmp, expected_psk) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+
+ /* Pairwise cipher: unused in adhoc mode */
+ ASSERT (nm_setting_wireless_security_get_num_pairwise (s_wsec) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
+
+ /* Group cipher */
+ ASSERT (nm_setting_wireless_security_get_num_groups (s_wsec) == 1,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_GROUP);
+
+ tmp = nm_setting_wireless_security_get_group (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing group cipher",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC);
+ ASSERT (strcmp (tmp, expected_group) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_GROUP);
+
+ /* Protocols */
+ ASSERT (nm_setting_wireless_security_get_num_protos (s_wsec) == 1,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PROTO);
+ tmp = nm_setting_wireless_security_get_proto (s_wsec, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: missing proto",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC);
+ ASSERT (strcmp (tmp, expected_proto) == 0,
+ "wifi-wpa-psk-adhoc-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PROTO);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wpa-psk-adhoc-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_ADHOC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_PSK_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-psk-hex"
+
+static void
+test_read_wifi_wpa_psk_hex (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ const char *expected_id = "System blahblah (test-wifi-wpa-psk-hex)";
+ const char *expected_ssid = "blahblah";
+ const char *expected_key_mgmt = "wpa-psk";
+ const char *expected_psk = "1da190379817bc360dda52e85c388c439a21ea5c7bf819c64e9da051807deae6";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-psk-hex-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_PSK_HEX, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-psk-hex-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_PSK_HEX, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wpa-psk-hex-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (array->len == strlen (expected_ssid),
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, strlen (expected_ssid)) == 0,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+ ASSERT (strcmp (tmp, expected_key_mgmt) == 0,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* PSK */
+ tmp = nm_setting_wireless_security_get_psk (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+ ASSERT (strcmp (tmp, expected_psk) == 0,
+ "wifi-wpa-psk-hex-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_PSK);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wpa-psk-hex-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK_HEX,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_EAP_TLS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-eap-tls"
+#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem"
+#define TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem"
+#define TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem"
+
+static void
+test_read_wifi_wpa_eap_tls (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ NMSetting8021x *s_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp, *password;
+ const char *expected_identity = "Bill Smith";
+ const char *expected_privkey_password = "test1";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-eap-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-eap-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TLS, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wifi-wpa-eap-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TLS);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-eap-tls-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wpa-eap-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+ ASSERT (s_8021x != NULL,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ /* EAP methods */
+ ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ ASSERT (strcmp (tmp, "tls") == 0,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+
+ /* Identity */
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+ ASSERT (strcmp (tmp, expected_identity) == 0,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+
+ /* CA Cert */
+ verify_cert_or_key (CK_CA_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ "wifi-wpa-eap-tls-verify-8021x",
+ NM_SETTING_802_1X_CA_CERT);
+
+ /* Client Cert */
+ verify_cert_or_key (CK_CLIENT_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ "wifi-wpa-eap-tls-verify-8021x",
+ NM_SETTING_802_1X_CLIENT_CERT);
+
+ /* Private Key Password */
+ password = nm_setting_802_1x_get_private_key_password (s_8021x);
+ ASSERT (password != NULL,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
+
+ ASSERT (strcmp (password, expected_privkey_password) == 0,
+ "wifi-wpa-eap-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
+
+ /* Private key */
+ verify_cert_or_key (CK_PRIV_KEY,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY,
+ expected_privkey_password,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS,
+ "wifi-wpa-eap-tls-verify-8021x",
+ NM_SETTING_802_1X_PRIVATE_KEY);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wpa-eap-ttls-tls"
+#define TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem"
+/* Also use TLS defines from the previous test */
+
+static void
+test_read_wifi_wpa_eap_ttls_tls (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ NMSetting8021x *s_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp, *password;
+ const char *expected_identity = "Chuck Shumer";
+ const char *expected_privkey_password = "test1";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wpa-eap-ttls-tls-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wifi-wpa-eap-ttls-tls-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wpa-eap-ttls-tls-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+ ASSERT (s_8021x != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ /* EAP methods */
+ ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ ASSERT (strcmp (tmp, "ttls") == 0,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+
+ /* CA Cert */
+ verify_cert_or_key (CK_CA_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS_CA_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ "wifi-wpa-eap-ttls-tls-verify-8021x",
+ NM_SETTING_802_1X_CA_CERT);
+
+ /* Inner auth method */
+ tmp = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_AUTHEAP);
+ ASSERT (strcmp (tmp, "tls") == 0,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_AUTHEAP);
+
+ /* Inner CA Cert */
+ verify_cert_or_key (CK_CA_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ "wifi-wpa-eap-ttls-tls-verify-8021x",
+ NM_SETTING_802_1X_PHASE2_CA_CERT);
+
+ /* Inner Client Cert */
+ verify_cert_or_key (CK_CLIENT_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ "wifi-wpa-eap-ttls-tls-verify-8021x",
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
+
+ /* Inner Private Key Password */
+ password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x);
+ ASSERT (password != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
+
+ ASSERT (strcmp (password, expected_privkey_password) == 0,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
+
+ /* Inner private key */
+ verify_cert_or_key (CK_PRIV_KEY,
+ s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY,
+ expected_privkey_password,
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ "wifi-wpa-eap-ttls-tls-verify-8021x",
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
+
+ /* Identity */
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+ ASSERT (strcmp (tmp, expected_identity) == 0,
+ "wifi-wpa-eap-ttls-tls-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_EAP_TTLS_TLS,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-dynamic-wep-leap"
+
+static void
+test_read_wifi_dynamic_wep_leap (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE, success;
+ GError *error = NULL;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_DYNAMIC_WEP_LEAP,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ g_assert_no_error (error);
+ g_assert (connection);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ g_assert (s_wifi);
+
+ g_assert_cmpstr (nm_setting_wireless_get_security (s_wifi), ==, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* ===== WiFi SECURITY SETTING ===== */
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ g_assert (s_wsec);
+
+ /* Key management */
+ g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "ieee8021x");
+
+ /* Auth alg should be NULL (open) for dynamic WEP with LEAP as the EAP method;
+ * only "old-school" LEAP uses 'leap' for the auth alg.
+ */
+ g_assert_cmpstr (nm_setting_wireless_security_get_auth_alg (s_wsec), ==, NULL);
+
+ /* Expect no old-school LEAP username/password, that'll be in the 802.1x setting */
+ g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, NULL);
+ g_assert_cmpstr (nm_setting_wireless_security_get_leap_password (s_wsec), ==, NULL);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x);
+
+ /* EAP method should be "leap" */
+ g_assert_cmpint (nm_setting_802_1x_get_num_eap_methods (s_8021x), ==, 1);
+ g_assert_cmpstr (nm_setting_802_1x_get_eap_method (s_8021x, 0), ==, "leap");
+
+ /* username & password */
+ g_assert_cmpstr (nm_setting_802_1x_get_identity (s_8021x), ==, "bill smith");
+ g_assert_cmpstr (nm_setting_802_1x_get_password (s_8021x), ==, "foobar baz");
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-eap-ttls-chap"
+#define TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem"
+
+static void
+test_read_wifi_wep_eap_ttls_chap (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSetting8021x *s_8021x;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_password = "foobar baz";
+ const char *expected_identity = "David Smith";
+ const char *expected_key_mgmt = "ieee8021x";
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-eap-ttls-chap-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wifi-wep-eap-ttls-chap-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-eap-ttls-chap-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "wifi-wep-eap-ttls-chap-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* ===== 802.1x SETTING ===== */
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ /* Key management */
+ tmp = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ ASSERT (tmp != NULL,
+ "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+ ASSERT (strcmp (tmp, expected_key_mgmt) == 0,
+ "wifi-wep-eap-ttls-chap-verify-wireless-security", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WPA_PSK,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* ===== 802.1x SETTING ===== */
+ s_8021x = NM_SETTING_802_1X (nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X));
+ ASSERT (s_8021x != NULL,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME);
+
+ /* EAP methods */
+ ASSERT (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ ASSERT (tmp != NULL,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+ ASSERT (strcmp (tmp, "ttls") == 0,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_EAP);
+
+ /* CA Cert */
+ verify_cert_or_key (CK_CA_CERT,
+ s_8021x,
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP_CA_CERT,
+ NULL,
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ "wifi-wep-eap-ttls-chap-verify-8021x",
+ NM_SETTING_802_1X_CA_CERT);
+
+ /* Inner auth method */
+ tmp = nm_setting_802_1x_get_phase2_auth (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s eap method",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_AUTH);
+ ASSERT (strcmp (tmp, "chap") == 0,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_AUTH);
+
+ /* Password */
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+ ASSERT (strcmp (tmp, expected_identity) == 0,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_IDENTITY);
+
+ /* Password */
+ tmp = nm_setting_802_1x_get_password (s_8021x);
+ ASSERT (tmp != NULL,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PASSWORD);
+ ASSERT (strcmp (tmp, expected_password) == 0,
+ "wifi-wep-eap-ttls-chap-verify-8021x", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_EAP_TTLS_CHAP,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PASSWORD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIRED_QETH_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-qeth-static"
+
+static void
+test_read_wired_qeth_static (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System test-wired-qeth-static";
+ const GByteArray *array;
+ const char *expected_channel0 = "0.0.0600";
+ const char *expected_channel1 = "0.0.0601";
+ const char *expected_channel2 = "0.0.0602";
+ const GPtrArray *subchannels;
+
+ connection = connection_from_file (TEST_IFCFG_WIRED_QETH_STATIC,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wired-qeth-static-read", "failed to read %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wired-qeth-static-verify", "failed to verify %s: %s", TEST_IFCFG_WIRED_QETH_STATIC, error->message);
+
+ ASSERT (unmanaged == FALSE,
+ "wired-qeth-static-verify", "failed to verify %s: unexpected unmanaged value", TEST_IFCFG_WIRED_QETH_STATIC);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wired-qeth-static-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wired-qeth-static-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wired-qeth-static-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array == NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ /* Subchannels */
+ subchannels = nm_setting_wired_get_s390_subchannels (s_wired);
+ ASSERT (subchannels != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_SUBCHANNELS);
+ ASSERT (subchannels->len == 3,
+ "wired-qeth-static-verify-wired", "failed to verify %s: invalid %s / %s key (not 3 elements)",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_SUBCHANNELS);
+
+ tmp = (const char *) g_ptr_array_index (subchannels, 0);
+ ASSERT (strcmp (tmp, expected_channel0) == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #0",
+ TEST_IFCFG_WIRED_QETH_STATIC);
+
+ tmp = (const char *) g_ptr_array_index (subchannels, 1);
+ ASSERT (strcmp (tmp, expected_channel1) == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #1",
+ TEST_IFCFG_WIRED_QETH_STATIC);
+
+ tmp = (const char *) g_ptr_array_index (subchannels, 2);
+ ASSERT (strcmp (tmp, expected_channel2) == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected subchannel #2",
+ TEST_IFCFG_WIRED_QETH_STATIC);
+
+ /* Nettype */
+ tmp = nm_setting_wired_get_s390_nettype (s_wired);
+ ASSERT (tmp != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_NETTYPE);
+ ASSERT (strcmp (tmp, "qeth") == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_S390_NETTYPE);
+
+ /* port name */
+ tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portname");
+ ASSERT (tmp != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portname'",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+ ASSERT (strcmp (tmp, "OSAPORT") == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portname' value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* port number */
+ tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "portno");
+ ASSERT (tmp != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'portno'",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+ ASSERT (strcmp (tmp, "0") == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'portno' value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* layer */
+ tmp = nm_setting_wired_get_s390_option_by_key (s_wired, "layer2");
+ ASSERT (tmp != NULL,
+ "wired-qeth-static-verify-wired", "failed to verify %s: missing %s s390 option 'layer2'",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+ ASSERT (strcmp (tmp, "1") == 0,
+ "wired-qeth-static-verify-wired", "failed to verify %s: unexpected %s s390 option 'layer2' value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "wired-qeth-static-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "wired-qeth-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIRED_QETH_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_NO_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-no-keys"
+
+static void
+test_read_wifi_wep_no_keys (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "System foobar (test-wifi-wep-no-keys)";
+ NMWepKeyType key_type;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "wifi-wep-no-keys-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "wifi-wep-no-keys-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "wifi-wep-no-keys-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* Security */
+ tmp = nm_setting_wireless_get_security (s_wireless);
+ ASSERT (tmp != NULL,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+ ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SEC);
+
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+
+ s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+
+ /* Key management */
+ ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
+
+ /* WEP key index */
+ ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
+
+ /* WEP key type */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected WEP key type %d",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ key_type);
+
+ /* WEP key index 0; we don't expect it to be filled */
+ tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
+ ASSERT (tmp == NULL,
+ "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_WIFI_WEP_NO_KEYS,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_PERMISSIONS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-permissions"
+
+static void
+test_read_permissions (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE, success;
+ GError *error = NULL;
+ guint32 num;
+ const char *tmp;
+
+ connection = connection_from_file (TEST_IFCFG_PERMISSIONS,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "permissions-read", "failed to read %s: %s", TEST_IFCFG_PERMISSIONS, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "permissions-verify", "failed to verify %s: %s", TEST_IFCFG_PERMISSIONS, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "permissions-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_PERMISSIONS,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ num = nm_setting_connection_get_num_permissions (s_con);
+ ASSERT (num == 3,
+ "permissions-verify-permissions", "unexpected number of permissions (%d, expected 3)",
+ num);
+
+ /* verify each permission */
+ tmp = NULL;
+ success = nm_setting_connection_get_permission (s_con, 0, NULL, &tmp, NULL);
+ ASSERT (success == TRUE,
+ "permissions-verify-permissions", "unexpected failure getting permission #1");
+ ASSERT (strcmp (tmp, "dcbw") == 0,
+ "permissions-verify-permissions", "unexpected permission #1");
+
+ tmp = NULL;
+ success = nm_setting_connection_get_permission (s_con, 1, NULL, &tmp, NULL);
+ ASSERT (success == TRUE,
+ "permissions-verify-permissions", "unexpected failure getting permission #2");
+ ASSERT (strcmp (tmp, "ssmith") == 0,
+ "permissions-verify-permissions", "unexpected permission #2");
+
+ tmp = NULL;
+ success = nm_setting_connection_get_permission (s_con, 2, NULL, &tmp, NULL);
+ ASSERT (success == TRUE,
+ "permissions-verify-permissions", "unexpected failure getting permission #3");
+ ASSERT (strcmp (tmp, "johnny5") == 0,
+ "permissions-verify-permissions", "unexpected permission #3");
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_WIFI_WEP_AGENT_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-agent-keys"
+
+static void
+test_read_wifi_wep_agent_keys (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ NMWepKeyType key_type;
+ gboolean success;
+ NMSettingSecretFlags flags;
+
+ connection = connection_from_file (TEST_IFCFG_WIFI_WEP_AGENT_KEYS,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ g_assert (connection != NULL);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Ensure the connection is still marked for wifi security even though
+ * we don't have any WEP keys because they are agent owned.
+ */
+
+ /* ===== WIRELESS SETTING ===== */
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ g_assert (s_wifi);
+ tmp = nm_setting_wireless_get_security (s_wifi);
+ g_assert (g_strcmp0 (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0);
+
+ /* ===== WIRELESS SECURITY SETTING ===== */
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ g_assert (s_wsec);
+
+ g_assert (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0);
+ g_assert (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0);
+
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ g_assert (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY);
+
+ /* We don't expect WEP key0 to be filled */
+ g_assert (nm_setting_wireless_security_get_wep_key (s_wsec, 0) == NULL);
+
+ flags = nm_setting_wireless_security_get_wep_key_flags (s_wsec);
+ g_assert (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_wired_static (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4, *reread_s_ip4;
+ NMSettingIP6Config *s_ip6, *reread_s_ip6;
+ static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
+ GByteArray *mac;
+ guint32 mtu = 1492;
+ char *uuid;
+ const guint32 ip1 = htonl (0x01010103);
+ const guint32 ip2 = htonl (0x01010105);
+ const guint32 gw = htonl (0x01010101);
+ const guint32 dns1 = htonl (0x04020201);
+ const guint32 dns2 = htonl (0x04020202);
+ const guint32 prefix = 24;
+ const char *dns_search1 = "foobar.com";
+ const char *dns_search2 = "lab.foobar.com";
+ const char *dns_search3 = "foobar6.com";
+ const char *dns_search4 = "lab6.foobar.com";
+ struct in6_addr ip6, ip6_1, ip6_2;
+ struct in6_addr route1_dest, route2_dest, route1_nexthop, route2_nexthop;
+ struct in6_addr dns6_1, dns6_2;
+ const guint32 route1_prefix = 64, route2_prefix = 0;
+ const guint32 route1_metric = 99, route2_metric = 1;
+ NMIP4Address *addr;
+ NMIP6Address *addr6;
+ NMIP6Route *route6;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6);
+ inet_pton (AF_INET6, "2003:1234:abcd::2", &ip6_1);
+ inet_pton (AF_INET6, "3003:1234:abcd::3", &ip6_2);
+ inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc::", &route1_dest);
+ inet_pton (AF_INET6, "2222:aaaa:bbbb:cccc:dddd:eeee:5555:6666", &route1_nexthop);
+ inet_pton (AF_INET6, "::", &route2_dest);
+ inet_pton (AF_INET6, "2222:aaaa::9999", &route2_nexthop);
+ inet_pton (AF_INET6, "fade:0102:0103::face", &dns6_1);
+ inet_pton (AF_INET6, "cafe:ffff:eeee:dddd:cccc:bbbb:aaaa:feed", &dns6_2);
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-static-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-static-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired Static",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-static-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ mac = g_byte_array_sized_new (sizeof (tmpmac));
+ g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_MAC_ADDRESS, mac,
+ NM_SETTING_WIRED_MTU, mtu,
+ NULL);
+ g_byte_array_free (mac, TRUE);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-static-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP4_CONFIG_MAY_FAIL, TRUE,
+ NULL);
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip1);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip2);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ nm_setting_ip4_config_add_dns (s_ip4, dns1);
+ nm_setting_ip4_config_add_dns (s_ip4, dns2);
+
+ nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1);
+ nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-static-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
+ NULL);
+
+ /* Add addresses */
+ addr6 = nm_ip6_address_new ();
+ nm_ip6_address_set_address (addr6, &ip6);
+ nm_ip6_address_set_prefix (addr6, 11);
+ nm_setting_ip6_config_add_address (s_ip6, addr6);
+ nm_ip6_address_unref (addr6);
+
+ addr6 = nm_ip6_address_new ();
+ nm_ip6_address_set_address (addr6, &ip6_1);
+ nm_ip6_address_set_prefix (addr6, 22);
+ nm_setting_ip6_config_add_address (s_ip6, addr6);
+ nm_ip6_address_unref (addr6);
+
+ addr6 = nm_ip6_address_new ();
+ nm_ip6_address_set_address (addr6, &ip6_2);
+ nm_ip6_address_set_prefix (addr6, 33);
+ nm_setting_ip6_config_add_address (s_ip6, addr6);
+ nm_ip6_address_unref (addr6);
+
+ /* Add routes */
+ route6 = nm_ip6_route_new ();
+ nm_ip6_route_set_dest (route6, &route1_dest);
+ nm_ip6_route_set_prefix (route6, route1_prefix);
+ nm_ip6_route_set_next_hop (route6, &route1_nexthop);
+ nm_ip6_route_set_metric (route6, route1_metric);
+ nm_setting_ip6_config_add_route (s_ip6, route6);
+ nm_ip6_route_unref (route6);
+
+ route6 = nm_ip6_route_new ();
+ nm_ip6_route_set_dest (route6, &route2_dest);
+ nm_ip6_route_set_prefix (route6, route2_prefix);
+ nm_ip6_route_set_next_hop (route6, &route2_nexthop);
+ nm_ip6_route_set_metric (route6, route2_metric);
+ nm_setting_ip6_config_add_route (s_ip6, route6);
+ nm_ip6_route_unref (route6);
+
+ /* DNS servers */
+ nm_setting_ip6_config_add_dns (s_ip6, &dns6_1);
+ nm_setting_ip6_config_add_dns (s_ip6, &dns6_2);
+
+ /* DNS domains */
+ nm_setting_ip6_config_add_dns_search (s_ip6, dns_search3);
+ nm_setting_ip6_config_add_dns_search (s_ip6, dns_search4);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-static-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-static-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-static-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-static-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-static-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ /* FIXME: currently DNS domains from IPv6 setting are stored in 'DOMAIN' key in ifcfg-file
+ * However after re-reading they are dropped into IPv4 setting.
+ * So, in order to comparison succeeded, move DNS domains back to IPv6 setting.
+ */
+ reread_s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG));
+ reread_s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP6_CONFIG));
+ nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 2));
+ nm_setting_ip6_config_add_dns_search (reread_s_ip6, nm_setting_ip4_config_get_dns_search (reread_s_ip4, 3));
+ nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 3);
+ nm_setting_ip4_config_remove_dns_search (reread_s_ip4, 2);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-static-write", "written and re-read connection weren't the same.");
+
+ if (route6file)
+ unlink (route6file);
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wired_dhcp (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-dhcp-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, "random-client-id-00:22:33",
+ NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, "awesome-hostname",
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, TRUE,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, TRUE,
+ NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-dhcp-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-dhcp-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-dhcp-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-dhcp-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-dhcp-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-dhcp-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wired_static_ip6_only (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
+ GByteArray *mac;
+ char *uuid;
+ struct in6_addr ip6;
+ struct in6_addr dns6;
+ NMIP6Address *addr6;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ inet_pton (AF_INET6, "1003:1234:abcd::1", &ip6);
+ inet_pton (AF_INET6, "fade:0102:0103::face", &dns6);
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-static-ip6-only-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-static-ip6-only-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired Static IP6 Only",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-static-ip6-only-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ mac = g_byte_array_sized_new (sizeof (tmpmac));
+ g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
+ g_byte_array_free (mac, TRUE);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-static-ip6-only-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
+ NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-static-ip6-only-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ /* Add addresses */
+ addr6 = nm_ip6_address_new ();
+ nm_ip6_address_set_address (addr6, &ip6);
+ nm_ip6_address_set_prefix (addr6, 11);
+ nm_setting_ip6_config_add_address (s_ip6, addr6);
+ nm_ip6_address_unref (addr6);
+
+ /* DNS server */
+ nm_setting_ip6_config_add_dns (s_ip6, &dns6);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-static-ip6-only-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-static-ip6-only-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-static-ip6-only-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-static-ip6-only-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-static-ip6-only-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-static-ip6-only-write", "written and re-read connection weren't the same.");
+
+ if (route6file)
+ unlink (route6file);
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+
+#define TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY TEST_IFCFG_DIR"/network-scripts/ifcfg-test-static-routes-legacy"
+
+static void
+test_read_write_static_routes_legacy (void)
+{
+ NMConnection *connection, *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *testfile = NULL;
+ char *keyfile = NULL;
+ char *keyfile2 = NULL;
+ char *routefile = NULL;
+ char *routefile2 = NULL;
+ char *route6file = NULL;
+ char *route6file2 = NULL;
+ gboolean ignore_error = FALSE;
+ gboolean success;
+ GError *error = NULL;
+ const char *tmp;
+
+ connection = connection_from_file (TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "read-write-static-routes-legacy-read", "failed to read %s: %s",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "read-write-static-routes-legacy-verify", "failed to verify %s: %s",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "read-write-static-routes-legacy-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "read_write-static-routes-legacy-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "read-write-static-routes-legacy-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_never_default (s_ip4) == FALSE,
+ "read-write-static-routes-legacy-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_READ_WRITE_STATIC_ROUTES_LEGACY,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT);
+
+ /* Save the ifcfg; use a special different scratch dir to ensure that
+ * we can clean up after the written connection in both the original
+ * source tree and for 'make distcheck'.
+ */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/tmp",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "read-write-static-routes-legacy-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "read-write-static-routes-legacy-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile2,
+ &routefile2,
+ &route6file2,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+ unlink (routefile2);
+ unlink (route6file2);
+
+ ASSERT (reread != NULL,
+ "read-write-static-routes-legacy-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (routefile2 != NULL,
+ "read-write-static-routes-legacy-reread", "expected routefile for '%s'", testfile);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "read-write-static-routes-legacy-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "read-write-static-routes-legacy-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (keyfile2);
+ g_free (routefile);
+ g_free (routefile2);
+ g_free (route6file);
+ g_free (route6file2);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wired_static_routes (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
+ GByteArray *mac;
+ guint32 mtu = 1492;
+ char *uuid;
+ const guint32 ip1 = htonl (0x01010103);
+ const guint32 ip2 = htonl (0x01010105);
+ const guint32 gw = htonl (0x01010101);
+ const guint32 dns1 = htonl (0x04020201);
+ const guint32 dns2 = htonl (0x04020202);
+ const guint32 route_dst1 = htonl (0x01020300);
+ const guint32 route_dst2= htonl (0x03020100);
+ const guint32 route_gw1 = htonl (0xdeadbeef);
+ const guint32 route_gw2 = htonl (0xcafeabbe);
+ const guint32 prefix = 24;
+ const char *dns_search1 = "foobar.com";
+ const char *dns_search2 = "lab.foobar.com";
+ NMIP4Address *addr;
+ NMIP4Route *route;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-static-routes-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-static-routes-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired Static Routes",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-static-routes-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ mac = g_byte_array_sized_new (sizeof (tmpmac));
+ g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_MAC_ADDRESS, mac,
+ NM_SETTING_WIRED_MTU, mtu,
+ NULL);
+ g_byte_array_free (mac, TRUE);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-static-routes-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip1);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip2);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ /* Write out routes */
+ route = nm_ip4_route_new ();
+ nm_ip4_route_set_dest (route, route_dst1);
+ nm_ip4_route_set_prefix (route, prefix);
+ nm_ip4_route_set_next_hop (route, route_gw1);
+ nm_setting_ip4_config_add_route (s_ip4, route);
+ nm_ip4_route_unref (route);
+
+ route = nm_ip4_route_new ();
+ nm_ip4_route_set_dest (route, route_dst2);
+ nm_ip4_route_set_prefix (route, prefix);
+ nm_ip4_route_set_next_hop (route, route_gw2);
+ nm_ip4_route_set_metric (route, 77);
+ nm_setting_ip4_config_add_route (s_ip4, route);
+ nm_ip4_route_unref (route);
+
+ nm_setting_ip4_config_add_dns (s_ip4, dns1);
+ nm_setting_ip4_config_add_dns (s_ip4, dns2);
+
+ nm_setting_ip4_config_add_dns_search (s_ip4, dns_search1);
+ nm_setting_ip4_config_add_dns_search (s_ip4, dns_search2);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-static-routes-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-static-routes-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-static-routes-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-static-routes-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (routefile != NULL,
+ "wired-static-routes-write-reread", "expected routefile for '%s'", testfile);
+ unlink (routefile);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-static-routes-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-static-routes-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wired_dhcp_8021x_peap_mschapv2 (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ NMSetting8021x *s_8021x;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired DHCP 802.1x PEAP MSCHAPv2",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ /* 802.1x setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ g_object_set (s_8021x,
+ NM_SETTING_802_1X_IDENTITY, "Bob Saget",
+ NM_SETTING_802_1X_PASSWORD, "Kids, it was back in October 2008...",
+ NM_SETTING_802_1X_PHASE1_PEAPVER, "1",
+ NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1",
+ NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2",
+ NULL);
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "peap");
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_IFCFG_WIRED_8021x_PEAP_MSCHAPV2_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-dhcp-8021x-peap-mschapv2write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (keyfile != NULL,
+ "wired-dhcp-8021x-peap-mschapv2write-reread", "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-dhcp-8021x-peap-mschapv2write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-dhcp-8021x-peap-mschapv2write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+#if 0
+static GByteArray *
+file_to_byte_array (const char *filename)
+{
+ char *contents;
+ GByteArray *array = NULL;
+ gsize length = 0;
+
+ if (g_file_get_contents (filename, &contents, &length, NULL)) {
+ array = g_byte_array_sized_new (length);
+ if (array) {
+ g_byte_array_append (array, (guint8 *) contents, length);
+ g_assert (array->len == length);
+ }
+ g_free (contents);
+ }
+ return array;
+}
+#endif
+
+#define TEST_IFCFG_WIRED_TLS_CA_CERT TEST_IFCFG_DIR"/network-scripts/test_ca_cert.pem"
+#define TEST_IFCFG_WIRED_TLS_CLIENT_CERT TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem"
+#define TEST_IFCFG_WIRED_TLS_PRIVATE_KEY TEST_IFCFG_DIR"/network-scripts/test1_key_and_cert.pem"
+
+static void
+test_write_wired_8021x_tls (NMSetting8021xCKScheme scheme,
+ NMSettingSecretFlags flags)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ NMSetting8021x *s_8021x;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ const char *pw;
+ char *tmp;
+
+ connection = nm_connection_new ();
+ g_assert (connection != NULL);
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired 802.1x TLS Blobs",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ g_assert (s_wired);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ g_assert (s_ip4);
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ g_assert (s_ip6);
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ /* 802.1x setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ g_assert (s_8021x);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
+ nm_setting_802_1x_add_eap_method (s_8021x, "tls");
+
+ /* CA cert */
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_IFCFG_WIRED_TLS_CA_CERT,
+ scheme,
+ &format,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509);
+
+ /* Client cert */
+ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ success = nm_setting_802_1x_set_client_cert (s_8021x,
+ TEST_IFCFG_WIRED_TLS_CLIENT_CERT,
+ scheme,
+ &format,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (format == NM_SETTING_802_1X_CK_FORMAT_X509);
+
+ /* Private key */
+ format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+ success = nm_setting_802_1x_set_private_key (s_8021x,
+ TEST_IFCFG_WIRED_TLS_PRIVATE_KEY,
+ "test1",
+ scheme,
+ &format,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY);
+
+ /* Set secret flags */
+ g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, flags, NULL);
+
+ /* Verify finished connection */
+ success = nm_connection_verify (connection, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to verify connection: %s", error->message);
+ }
+ g_assert (success);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to write connection: %s", error->message);
+ }
+ g_assert (success);
+ g_assert (testfile != NULL);
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+ g_assert (keyfile != NULL);
+ unlink (keyfile);
+
+ g_assert (reread != NULL);
+
+ success = nm_connection_verify (reread, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to verify %s: %s", testfile, error->message);
+ }
+ g_assert (success);
+
+ /* Ensure the reread connection's certificates and private key are paths; no
+ * matter what scheme was used in the original connection they will be read
+ * back in as paths.
+ */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x);
+ g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH);
+ g_assert_cmpint (nm_setting_802_1x_get_client_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH);
+ g_assert_cmpint (nm_setting_802_1x_get_private_key_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_PATH);
+
+ g_assert_cmpint (nm_setting_802_1x_get_private_key_password_flags (s_8021x), ==, flags);
+ pw = nm_setting_802_1x_get_private_key_password (s_8021x);
+ if (flags == NM_SETTING_SECRET_FLAG_NONE) {
+ /* Ensure the private key password is still set */
+ g_assert (pw != NULL);
+ g_assert_cmpstr (pw, ==, "test1");
+ } else {
+ /* If the secret isn't owned by system settings, make sure its no longer there */
+ g_assert (pw == NULL);
+ }
+
+ if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+ /* Do a direct compare if using the path scheme since then the
+ * certificate and key properties should be the same. If using blob
+ * scheme the original connection cert/key properties will be blobs
+ * but the re-read connection is always path scheme, so we wouldn't
+ * expect it to compare successfully.
+ */
+ if (flags != NM_SETTING_SECRET_FLAG_NONE) {
+ /* Clear original connection's private key password because flags
+ * say it's not system-owned, and therefore it should not show up
+ * in the re-read connection.
+ */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ g_object_set (s_8021x, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL);
+ }
+
+ g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
+ }
+
+ /* Clean up created certs and keys */
+ tmp = utils_cert_path (testfile, "ca-cert.der");
+ unlink (tmp);
+ g_free (tmp);
+
+ tmp = utils_cert_path (testfile, "client-cert.der");
+ unlink (tmp);
+ g_free (tmp);
+
+ tmp = utils_cert_path (testfile, "private-key.pem");
+ unlink (tmp);
+ g_free (tmp);
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_open (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = { 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44 };
+ GByteArray *bssid;
+ const unsigned char bssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
+ guint32 channel = 9, mtu = 1345;
+ GByteArray *mac;
+ const unsigned char mac_data[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
+ shvarFile *ifcfg;
+ char *tmp;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-open-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-open-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi Open",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-open-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+ bssid = g_byte_array_sized_new (sizeof (bssid_data));
+ g_byte_array_append (bssid, bssid_data, sizeof (bssid_data));
+ mac = g_byte_array_sized_new (sizeof (mac_data));
+ g_byte_array_append (mac, mac_data, sizeof (mac_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_BSSID, bssid,
+ NM_SETTING_WIRELESS_MAC_ADDRESS, mac,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_BAND, "bg",
+ NM_SETTING_WIRELESS_CHANNEL, channel,
+ NM_SETTING_WIRELESS_MTU, mtu,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+ g_byte_array_free (bssid, TRUE);
+ g_byte_array_free (mac, TRUE);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-open-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-open-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-open-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-open-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-open-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+
+ /* Now make sure that the ESSID item isn't double-quoted (rh #606518) */
+ ifcfg = svNewFile (testfile);
+ ASSERT (ifcfg != NULL,
+ "wifi-open-write-reread", "failed to load %s as shvarfile", testfile);
+
+ tmp = svGetValue (ifcfg, "ESSID", TRUE);
+ ASSERT (tmp != NULL,
+ "wifi-open-write-reread", "failed to read ESSID key from %s", testfile);
+
+ ASSERT (strncmp (tmp, "\"\"", 2) != 0,
+ "wifi-open-write-reread", "unexpected ESSID double-quote in %s", testfile);
+
+ svCloseFile (ifcfg);
+
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wifi-open-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-open-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-open-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_open_hex_ssid (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd };
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-open-hex-ssid-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-open-hex-ssid-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi Open Hex SSID",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-open-hex-ssid-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-open-hex-ssid-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-open-hex-ssid-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-open-hex-ssid-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-open-hex-ssid-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-open-hex-ssid-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wifi-open-hex-ssid-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-open-hex-ssid-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-open-hex-ssid-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wep-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wep-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wep-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared",
+ NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 1, "11111111111111111111111111");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 2, "aaaaaaaaaaaaaaaaaaaaaaaaaa");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 3, "BBBBBBBBBBBBBBBBBBBBBBBBBB");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wep-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wep-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wep-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wep-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wep-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-wep-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-wep-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-wep-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wep-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wep-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wep-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep_adhoc (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ struct stat statbuf;
+ NMIP4Address *addr;
+ const guint32 ip1 = htonl (0x01010103);
+ const guint32 gw = htonl (0x01010101);
+ const guint32 dns1 = htonl (0x04020201);
+ const guint32 prefix = 24;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP AdHoc",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "adhoc",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "0123456789abcdef0123456789");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
+
+ /* IP Address */
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip1);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ nm_setting_ip4_config_add_dns (s_ip4, dns1);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wep-adhoc-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wep-adhoc-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wep-adhoc-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wep-adhoc-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-wep-adhoc-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-wep-adhoc-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wep-adhoc-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wep-adhoc-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wep-adhoc-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep_passphrase (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wep-passphrase-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wep-passphrase-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Passphrase",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wep-passphrase-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-passphrase-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared",
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, NM_WEP_KEY_TYPE_PASSPHRASE,
+ NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-passphrase-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wep-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wep-passphrase-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wep-passphrase-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wep-passphrase-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wep-passphrase-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-wep-passphrase-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-wep-passphrase-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wep-passphrase-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wep-passphrase-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wep-passphrase-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep_40_ascii (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah40";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 40 ASCII",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 2,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared",
+ NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "lorem");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 1, "ipsum");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 2, "dolor");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 3, "donec");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wep-40-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wep-40-ascii-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wep-40-ascii-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wep-40-ascii-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wep-40-ascii-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-wep-40-ascii-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-wep-40-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wep-40-ascii-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wep-40-ascii-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wep-40-ascii-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep_104_ascii (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah104";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP 104 ASCII",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open",
+ NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "LoremIpsumSit");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 1, "AlfaBetaGamma");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 2, "WEP-104 ASCII");
+ nm_setting_wireless_security_set_wep_key (s_wsec, 3, "thisismyascii");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wep-104-ascii-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wep-104-ascii-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wep-104-ascii-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wep-104-ascii-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wep-104-ascii-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-wep-104-ascii-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-wep-104-ascii-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wep-104-ascii-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wep-104-ascii-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wep-104-ascii-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_leap (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ struct stat statbuf;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-leap-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
+ NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith",
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22",
+ NULL);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-leap-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-leap-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-leap-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-leap-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-leap-write-reread", "expected keyfile for '%s'", testfile);
+
+ ASSERT (stat (keyfile, &statbuf) == 0,
+ "wifi-leap-write-reread", "couldn't stat() '%s'", keyfile);
+ ASSERT (S_ISREG (statbuf.st_mode),
+ "wifi-leap-write-reread", "keyfile '%s' wasn't a normal file", keyfile);
+ ASSERT ((statbuf.st_mode & 0077) == 0,
+ "wifi-leap-write-reread", "keyfile '%s' wasn't readable only by its owner", keyfile);
+
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-leap-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-leap-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-leap-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_leap_secret_flags (NMSettingSecretFlags flags)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+
+ connection = nm_connection_new ();
+ g_assert (connection);
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi LEAP Secret Flags",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ g_assert (s_wifi);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ g_assert (s_wsec);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap",
+ NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith",
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "foobar22",
+ NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags,
+ NULL);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ g_assert (s_ip4);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ g_assert (s_ip6);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (testfile);
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ g_assert_no_error (error);
+
+ /* No key should be written out since the secret is not system owned */
+ g_assert (keyfile);
+ g_assert (g_file_test (keyfile, G_FILE_TEST_EXISTS) == FALSE);
+
+ g_assert (reread);
+
+ success = nm_connection_verify (reread, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Remove the LEAP password from the original connection since it wont' be
+ * in the reread connection, as the password is not system owned.
+ */
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, NULL, NULL);
+ g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wpa_psk (const char *name,
+ const char *test_name,
+ gboolean wep_group,
+ gboolean wpa,
+ gboolean wpa2,
+ const char *psk)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid, *tmp;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+
+ g_return_if_fail (psk != NULL);
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ test_name, "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ test_name, "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, name,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ test_name, "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ test_name, "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
+ NM_SETTING_WIRELESS_SECURITY_PSK, psk,
+ NULL);
+
+ if (wep_group) {
+ nm_setting_wireless_security_add_group (s_wsec, "wep40");
+ nm_setting_wireless_security_add_group (s_wsec, "wep104");
+ }
+ if (wpa) {
+ nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
+ nm_setting_wireless_security_add_group (s_wsec, "tkip");
+ }
+ if (wpa2) {
+ nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+ nm_setting_wireless_security_add_group (s_wsec, "ccmp");
+ }
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ test_name, "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ test_name, "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ test_name, "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ test_name, "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ test_name, "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ tmp = g_strdup_printf ("%s-reread", test_name);
+ ASSERT (keyfile != NULL,
+ tmp, "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ tmp, "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ tmp, "failed to verify %s: %s", testfile, error->message);
+ g_free (tmp);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ test_name, "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wpa_psk_adhoc (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const unsigned char ssid_data[] = "blahblah";
+ NMIP4Address *addr;
+ const guint32 ip1 = htonl (0x01010103);
+ const guint32 gw = htonl (0x01010101);
+ const guint32 dns1 = htonl (0x04020201);
+ const guint32 prefix = 24;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA PSK",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (sizeof (ssid_data));
+ g_byte_array_append (ssid, ssid_data, sizeof (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "adhoc",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_CHANNEL, 11,
+ NM_SETTING_WIRELESS_BAND, "bg",
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none",
+ NM_SETTING_WIRELESS_SECURITY_PSK, "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0",
+ NULL);
+
+ nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+ nm_setting_wireless_security_add_group (s_wsec, "tkip");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL);
+
+ /* IP Address */
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, ip1);
+ nm_ip4_address_set_prefix (addr, prefix);
+ nm_ip4_address_set_gateway (addr, gw);
+ nm_setting_ip4_config_add_address (s_ip4, addr);
+ nm_ip4_address_unref (addr);
+
+ nm_setting_ip4_config_add_dns (s_ip4, dns1);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wpa-psk-adhoc-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wpa-psk-adhoc-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-psk-adhoc-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wpa-psk-adhoc-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wpa-psk-adhoc-write-reread", "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wpa-psk-adhoc-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wpa-psk-adhoc-write-reread", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wpa-psk-adhoc-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wpa_eap_tls (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const char *ssid_data = "blahblah";
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TLS",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (strlen (ssid_data));
+ g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+ nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
+ nm_setting_wireless_security_add_group (s_wsec, "tkip");
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "tls");
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-tls-write", "failed to set CA certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message);
+
+ success = nm_setting_802_1x_set_client_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-tls-write", "failed to set client certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, error->message);
+
+ success = nm_setting_802_1x_set_private_key (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY,
+ "test1",
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-tls-write", "failed to set private key '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wpa-eap-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wpa-eap-tls-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-tls-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wpa-eap-tls-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wpa-eap-tls-write-reread", "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wpa-eap-tls-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wpa-eap-tls-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wpa-eap-tls-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wpa_eap_ttls_tls (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const char *ssid_data = "blahblah";
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (TLS)",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (strlen (ssid_data));
+ g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+ nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+ nm_setting_wireless_security_add_group (s_wsec, "ccmp");
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
+
+ g_object_set (s_8021x,
+ NM_SETTING_802_1X_IDENTITY, "Bill Smith",
+ NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22",
+ NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls",
+ NULL);
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to set CA certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message);
+
+ /* Phase 2 TLS stuff */
+
+ /* phase2 CA cert */
+ success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to set inner CA certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message);
+
+ /* phase2 client cert */
+ success = nm_setting_802_1x_set_phase2_client_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to set inner client certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CLIENT_CERT, error->message);
+
+ /* phase2 private key */
+ success = nm_setting_802_1x_set_phase2_private_key (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY,
+ "test1",
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to set private key '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_PRIVATE_KEY, error->message);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wpa-eap-ttls-tls-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wpa-eap-ttls-tls-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wpa-eap-ttls-tls-write-reread", "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wpa-eap-ttls-tls-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wpa-eap-ttls-tls-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wpa_eap_ttls_mschapv2 (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const char *ssid_data = "blahblah";
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WPA EAP-TTLS (MSCHAPv2)",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ ASSERT (s_wifi != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (strlen (ssid_data));
+ g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ ASSERT (s_wsec != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+ nm_setting_wireless_security_add_proto (s_wsec, "wpa");
+ nm_setting_wireless_security_add_proto (s_wsec, "rsn");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
+ nm_setting_wireless_security_add_pairwise (s_wsec, "ccmp");
+ nm_setting_wireless_security_add_group (s_wsec, "tkip");
+ nm_setting_wireless_security_add_group (s_wsec, "ccmp");
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ ASSERT (s_8021x != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_802_1X_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
+
+ g_object_set (s_8021x,
+ NM_SETTING_802_1X_IDENTITY, "Bill Smith",
+ NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf",
+ NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "foobar22",
+ NM_SETTING_802_1X_PHASE2_AUTHEAP, "mschapv2",
+ NULL);
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to set CA certificate '%s': %s",
+ TEST_IFCFG_WIFI_WPA_EAP_TLS_CA_CERT, error->message);
+
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wifi-wpa-eap-ttls-mschapv2-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (keyfile != NULL,
+ "wifi-wpa-eap-ttls-mschapv2-write-reread", "expected keyfile for '%s'", testfile);
+ unlink (keyfile);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wifi-wpa-eap-ttls-mschapv2-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wifi-wpa-eap-ttls-mschapv2-write", "written and re-read connection weren't the same.");
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_dynamic_wep_leap (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSetting8021x *s_8021x;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GByteArray *ssid;
+ const char *ssid_data = "blahblah";
+ shvarFile *ifcfg;
+ char *tmp;
+
+ connection = nm_connection_new ();
+ g_assert (connection);
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi Dynamic WEP LEAP",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ g_assert (s_wifi);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (strlen (ssid_data));
+ g_byte_array_append (ssid, (const unsigned char *) ssid_data, strlen (ssid_data));
+
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wireless security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ g_assert (s_wsec);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL);
+
+ /* Wireless security setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ g_assert (s_8021x);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "leap");
+
+ g_object_set (s_8021x,
+ NM_SETTING_802_1X_IDENTITY, "Bill Smith",
+ NM_SETTING_802_1X_PASSWORD, ";alkdfja;dslkfjsad;lkfjsadf",
+ NULL);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ g_assert (s_ip4);
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ g_assert (s_ip6);
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (testfile);
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ g_assert_no_error (error);
+ g_assert (reread);
+ g_assert (keyfile);
+ unlink (keyfile);
+
+ success = nm_connection_verify (reread, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+ g_assert (success);
+
+ /* Check and make sure that an "old-school" LEAP (Network EAP) connection
+ * did not get written. Check first that the auth alg is not set to "LEAP"
+ * and next that the only IEEE 802.1x EAP method is "LEAP".
+ */
+ ifcfg = svNewFile (testfile);
+ g_assert (ifcfg);
+ tmp = svGetValue (ifcfg, "SECURITYMODE", FALSE);
+ g_assert_cmpstr (tmp, ==, NULL);
+ g_free (tmp);
+
+ tmp = svGetValue (ifcfg, "IEEE_8021X_EAP_METHODS", FALSE);
+ g_assert_cmpstr (tmp, ==, "LEAP");
+
+ svCloseFile (ifcfg);
+ unlink (testfile);
+
+ g_free (testfile);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+#define TEST_IFCFG_IBFT_DHCP TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-dhcp"
+
+static void
+test_read_ibft_dhcp (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf1 };
+ const char *expected_id = "System test-ibft-dhcp";
+ guint64 expected_timestamp = 0;
+
+ connection = connection_from_file (TEST_IFCFG_IBFT_DHCP,
+ NULL,
+ TYPE_ETHERNET,
+ TEST_IFCFG_DIR "/iscsiadm-test-dhcp",
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "ibft-dhcp-read", "failed to read %s: %s", TEST_IFCFG_IBFT_DHCP, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "ibft-dhcp-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_DHCP, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "ibft-dhcp-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "ibft-dhcp-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* Read-only */
+ ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE,
+ "ibft-dhcp-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_READ_ONLY);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "ibft-dhcp-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "ibft-dhcp-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wired_get_mtu (s_wired) == 0,
+ "ibft-dhcp-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MTU);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "ibft-dhcp-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "ibft-dhcp-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_DHCP,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_IBFT_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-ibft-static"
+
+static void
+test_read_ibft_static (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+ const char *tmp;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x33, 0x21, 0x98, 0xb9, 0xf0 };
+ const char *expected_id = "System test-ibft-static";
+ guint64 expected_timestamp = 0;
+ const char *expected_dns1 = "10.16.255.2";
+ const char *expected_dns2 = "10.16.255.3";
+ struct in_addr addr;
+ const char *expected_address1 = "192.168.32.72";
+ const char *expected_address1_gw = "192.168.35.254";
+ NMIP4Address *ip4_addr;
+
+ connection = connection_from_file (TEST_IFCFG_IBFT_STATIC,
+ NULL,
+ TYPE_ETHERNET,
+ TEST_IFCFG_DIR "/iscsiadm-test-static",
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "ibft-static-read", "failed to read %s: %s", TEST_IFCFG_IBFT_STATIC, error->message);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "ibft-static-verify", "failed to verify %s: %s", TEST_IFCFG_IBFT_STATIC, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "ibft-static-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "ibft-static-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "ibft-static-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID can't be tested if the ifcfg does not contain the UUID key, because
+ * the UUID is generated on the full path of the ifcfg file, which can change
+ * depending on where the tests are run.
+ */
+
+ /* Timestamp */
+ ASSERT (nm_setting_connection_get_timestamp (s_con) == expected_timestamp,
+ "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* Read-only */
+ ASSERT (nm_setting_connection_get_read_only (s_con) == TRUE,
+ "ibft-static-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_READ_ONLY);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "ibft-static-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "ibft-static-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wired_get_mtu (s_wired) == 0,
+ "ibft-static-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MTU);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "ibft-static-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+ "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+ "ibft-static-verify-ip4", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 1,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* Address #1 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+ ASSERT (ip4_addr,
+ "ibft-static-verify-ip4", "failed to verify %s: missing IP4 address #1",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 22,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 prefix",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
+ "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
+ "ibft-static-verify-ip4", "failed to verify %s: couldn't convert IP address #1 gateway",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+ ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
+ "ibft-static-verify-ip4", "failed to verify %s: unexpected IP4 address #1 gateway",
+ TEST_IFCFG_IBFT_STATIC,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ g_object_unref (connection);
+}
+
+static void
+test_read_ibft_malformed (const char *name, const char *iscsiadm_path)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ g_assert (g_file_test (iscsiadm_path, G_FILE_TEST_EXISTS));
+
+ connection = connection_from_file (TEST_IFCFG_IBFT_STATIC,
+ NULL,
+ TYPE_ETHERNET,
+ iscsiadm_path,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection == NULL,
+ name, "unexpectedly able to read %s", TEST_IFCFG_IBFT_STATIC);
+}
+
+static void
+test_write_wired_qeth_dhcp (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ GPtrArray *subchans;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired qeth Static",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ subchans = g_ptr_array_sized_new (3);
+ g_ptr_array_add (subchans, "0.0.600");
+ g_ptr_array_add (subchans, "0.0.601");
+ g_ptr_array_add (subchans, "0.0.602");
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_S390_SUBCHANNELS, subchans,
+ NM_SETTING_WIRED_S390_NETTYPE, "qeth",
+ NULL);
+ g_ptr_array_free (subchans, TRUE);
+
+ nm_setting_wired_add_s390_option (s_wired, "portname", "FOOBAR");
+ nm_setting_wired_add_s390_option (s_wired, "portno", "1");
+ nm_setting_wired_add_s390_option (s_wired, "layer2", "0");
+ nm_setting_wired_add_s390_option (s_wired, "protocol", "blahbalh");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+
+ /* Verify */
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-qeth-dhcp-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "wired-qeth-dhcp-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "wired-qeth-dhcp-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "wired-qeth-dhcp-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "wired-qeth-dhcp-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "wired-qeth-dhcp-write", "written and re-read connection weren't the same.");
+
+ if (route6file)
+ unlink (route6file);
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_permissions (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "permissions-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "permissions-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Permissions",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ nm_setting_connection_add_permission (s_con, "user", "blahblah", NULL);
+ nm_setting_connection_add_permission (s_con, "user", "foobar", NULL);
+ nm_setting_connection_add_permission (s_con, "user", "asdfasdf", NULL);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "permissions-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "permissions-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ ASSERT (s_ip6 != NULL,
+ "wired-qeth-dhcp-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+
+ /* Verify */
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "permissions-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == TRUE,
+ "permissions-write", "failed to write connection to disk: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ ASSERT (testfile != NULL,
+ "permissions-write", "didn't get ifcfg file path back after writing connection");
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ ASSERT (reread != NULL,
+ "permissions-write-reread", "failed to read %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_verify (reread, &error),
+ "permissions-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "permissions-write", "written and re-read connection weren't the same.");
+
+ if (route6file)
+ unlink (route6file);
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wifi_wep_agent_keys (void)
+{
+ NMConnection *connection;
+ NMConnection *reread;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ const char *str_ssid = "foobarbaz";
+ GByteArray *ssid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+
+ connection = nm_connection_new ();
+ g_assert (connection != NULL);
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wifi WEP Agent Owned",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ g_assert (s_ip4);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+ /* IP6 setting */
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ g_assert (s_ip6);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+
+ /* Wifi setting */
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ g_assert (s_wifi);
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ ssid = g_byte_array_sized_new (strlen (str_ssid));
+ g_byte_array_append (ssid, (guint8 *) str_ssid, strlen (str_ssid));
+ g_object_set (s_wifi,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NM_SETTING_WIRELESS_MODE, "infrastructure",
+ NULL);
+ g_byte_array_free (ssid, TRUE);
+
+ /* Wifi security setting */
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ g_assert (s_wsec);
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+
+ g_object_set (s_wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
+ NULL);
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, "asdfdjaslfjasd;flasjdfl;aksdf");
+
+ /* Verify */
+ success = nm_connection_verify (connection, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert (testfile != NULL);
+
+ /* re-read the connection for comparison */
+ reread = connection_from_file (testfile,
+ NULL,
+ TYPE_WIRELESS,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ unlink (testfile);
+
+ g_assert_no_error (error);
+ g_assert (reread);
+
+ success = nm_connection_verify (reread, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+
+ /* Remove the WEP key from the original, because it should not have been
+ * written out to disk as it was agent-owned. The new connection should
+ * not have any WEP keys set.
+ */
+ nm_setting_wireless_security_set_wep_key (s_wsec, 0, NULL);
+
+ /* Compare original and reread */
+ success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+ g_assert (success);
+
+ if (route6file)
+ unlink (route6file);
+
+ g_free (testfile);
+ g_free (keyfile);
+ g_free (routefile);
+ g_free (route6file);
+ g_object_unref (connection);
+ g_object_unref (reread);
+}
+
+static void
+test_write_wired_pppoe (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingPPPOE *s_pppoe;
+ NMSettingPPP *s_ppp;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "wired-pppoe-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "wired-pppoe-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write Wired PPPoE",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+ s_wired = (NMSettingWired *) nm_setting_wired_new ();
+ ASSERT (s_wired != NULL,
+ "wired-pppoe-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "wired-pppoe-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* PPPoE setting */
+ s_pppoe = (NMSettingPPPOE *) nm_setting_pppoe_new ();
+ ASSERT (s_pppoe != NULL,
+ "wired-pppoe-write", "failed to allocate new %s setting",
+ NM_SETTING_PPPOE_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_pppoe));
+
+ g_object_set (G_OBJECT (s_pppoe),
+ NM_SETTING_PPPOE_SERVICE, "stupid-service",
+ NM_SETTING_PPPOE_USERNAME, "Bill Smith",
+ NM_SETTING_PPPOE_PASSWORD, "test1",
+ NULL);
+
+ /* PPP setting */
+ s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
+ ASSERT (s_ppp != NULL,
+ "wired-pppoe-write", "failed to allocate new %s setting",
+ NM_SETTING_PPP_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ppp));
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "wired-pppoe-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == FALSE,
+ "wired-pppoe-write", "unexpected success writing connection to disk");
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_vpn (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ NMSettingVPN *s_vpn;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "vpn-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "vpn-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Test Write VPN",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* VPN setting */
+ s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
+ ASSERT (s_vpn != NULL,
+ "vpn-write", "failed to allocate new %s setting",
+ NM_SETTING_VPN_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_vpn));
+
+ g_object_set (s_vpn,
+ NM_SETTING_VPN_SERVICE_TYPE, "awesomevpn",
+ NM_SETTING_VPN_USER_NAME, "Bill Smith",
+ NULL);
+
+ nm_setting_vpn_add_data_item (s_vpn, "server", "vpn.somewhere.com");
+ nm_setting_vpn_add_secret (s_vpn, "password", "sup3rs3cr3t");
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "vpn-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "vpn-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == FALSE,
+ "vpn-write", "unexpected success writing connection to disk");
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_mobile_broadband (gboolean gsm)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ NMSettingGsm *s_gsm;
+ NMSettingCdma *s_cdma;
+ NMSettingPPP *s_ppp;
+ NMSettingSerial *s_serial;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+ char *testfile = NULL;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "mobile-broadband-write", "failed to allocate new connection");
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ ASSERT (s_con != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, gsm ? "Test Write GSM" : "Test Write CDMA",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+ NM_SETTING_CONNECTION_TYPE, gsm ? NM_SETTING_GSM_SETTING_NAME : NM_SETTING_CDMA_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ if (gsm) {
+ /* GSM setting */
+ s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
+ ASSERT (s_gsm != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_GSM_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_gsm));
+
+ g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
+ } else {
+ /* CDMA setting */
+ s_cdma = (NMSettingCdma *) nm_setting_cdma_new ();
+ ASSERT (s_cdma != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_CDMA_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_cdma));
+
+ g_object_set (s_cdma, NM_SETTING_CDMA_NUMBER, "#777", NULL);
+ }
+
+ /* Serial setting */
+ s_serial = (NMSettingSerial *) nm_setting_serial_new ();
+ ASSERT (s_serial != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_SERIAL_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_serial));
+
+ g_object_set (s_serial,
+ NM_SETTING_SERIAL_BAUD, 115200,
+ NM_SETTING_SERIAL_BITS, 8,
+ NM_SETTING_SERIAL_PARITY, 'n',
+ NM_SETTING_SERIAL_STOPBITS, 1,
+ NULL);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ ASSERT (s_ip4 != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* PPP setting */
+ s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
+ ASSERT (s_ppp != NULL,
+ "mobile-broadband-write", "failed to allocate new %s setting",
+ NM_SETTING_PPP_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ppp));
+
+ ASSERT (nm_connection_verify (connection, &error) == TRUE,
+ "mobile-broadband-write", "failed to verify connection: %s",
+ (error && error->message) ? error->message : "(unknown)");
+
+ /* Save the ifcfg */
+ success = writer_new_connection (connection,
+ TEST_SCRATCH_DIR "/network-scripts/",
+ &testfile,
+ &error);
+ ASSERT (success == FALSE,
+ "mobile-broadband-write", "unexpected success writing connection to disk");
+
+ g_object_unref (connection);
+}
+
+#define TEST_IFCFG_BRIDGE_MAIN TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-main"
+
+static void
+test_read_bridge_main (void)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ connection = connection_from_file (TEST_IFCFG_BRIDGE_MAIN,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection == NULL,
+ "bridge-main-read", "unexpected success reading %s", TEST_IFCFG_BRIDGE_MAIN);
+}
+
+#define TEST_IFCFG_BRIDGE_COMPONENT TEST_IFCFG_DIR"/network-scripts/ifcfg-test-bridge-component"
+
+static void
+test_read_bridge_component (void)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ connection = connection_from_file (TEST_IFCFG_BRIDGE_COMPONENT,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection != NULL,
+ "bridge-component-read", "unexpected failure reading %s", TEST_IFCFG_BRIDGE_COMPONENT);
+
+ ASSERT (unmanaged != NULL,
+ "bridge-component-read", "missing unmanaged spec from %s", TEST_IFCFG_BRIDGE_COMPONENT);
+
+ ASSERT (g_strcmp0 (unmanaged, "mac:00:22:15:59:62:97") == 0,
+ "bridge-component-read", "unexpected unmanaged spec from %s", TEST_IFCFG_BRIDGE_COMPONENT);
+
+ g_object_unref (connection);
+ g_free (unmanaged);
+}
+
+#define TEST_IFCFG_VLAN_INTERFACE TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-interface"
+
+static void
+test_read_vlan_interface (void)
+{
+ NMConnection *connection;
+ char *unmanaged = NULL;
+ char *keyfile = NULL;
+ char *routefile = NULL;
+ char *route6file = NULL;
+ gboolean ignore_error = FALSE;
+ GError *error = NULL;
+
+ connection = connection_from_file (TEST_IFCFG_VLAN_INTERFACE,
+ NULL,
+ TYPE_ETHERNET,
+ NULL,
+ &unmanaged,
+ &keyfile,
+ &routefile,
+ &route6file,
+ &error,
+ &ignore_error);
+ ASSERT (connection == NULL,
+ "vlan-interface-read", "unexpected success reading %s", TEST_IFCFG_VLAN_INTERFACE);
+}
+
+#define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex"
+#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted"
+#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-hex"
+
+
+#define TEST_IFCFG_WIRED_STATIC TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static"
+#define TEST_IFCFG_WIRED_STATIC_BOOTPROTO TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wired-static-bootproto"
+
+#define DEFAULT_HEX_PSK "7d308b11df1b4243b0f78e5f3fc68cdbb9a264ed0edf4c188edf329ff5b467f0"
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ char *base;
+
+ g_type_init ();
+
+ if (!nm_utils_init (&error))
+ FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
+
+ /* The tests */
+ test_read_unmanaged ();
+ test_read_minimal ();
+ test_read_wired_static (TEST_IFCFG_WIRED_STATIC, "System test-wired-static");
+ test_read_wired_static (TEST_IFCFG_WIRED_STATIC_BOOTPROTO, "System test-wired-static-bootproto");
+ test_read_wired_static_no_prefix (8);
+ test_read_wired_static_no_prefix (16);
+ test_read_wired_static_no_prefix (24);
+ test_read_wired_dhcp ();
+ test_read_wired_global_gateway ();
+ test_read_wired_never_default ();
+ test_read_wired_defroute_no ();
+ test_read_wired_defroute_no_gatewaydev_yes ();
+ test_read_wired_static_routes ();
+ test_read_wired_static_routes_legacy ();
+ test_read_wired_ipv6_manual ();
+ test_read_wired_ipv6_only ();
+ test_read_wired_dhcp6_only ();
+ test_read_onboot_no ();
+ test_read_wired_8021x_peap_mschapv2 ();
+ test_read_wired_8021x_tls_secret_flags (TEST_IFCFG_WIRED_8021X_TLS_AGENT, NM_SETTING_SECRET_FLAG_AGENT_OWNED);
+ test_read_wired_8021x_tls_secret_flags (TEST_IFCFG_WIRED_8021X_TLS_ALWAYS,
+ NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_read_wifi_open ();
+ test_read_wifi_open_auto ();
+ test_read_wifi_open_ssid_hex ();
+ test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX, "wifi-open-ssid-bad-hex-read");
+ test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX, "wifi-open-ssid-long-hex-read");
+ test_read_wifi_open_ssid_bad (TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED, "wifi-open-ssid-long-quoted-read");
+ test_read_wifi_open_ssid_quoted ();
+ test_read_wifi_wep ();
+ test_read_wifi_wep_adhoc ();
+ test_read_wifi_wep_passphrase ();
+ test_read_wifi_wep_40_ascii ();
+ test_read_wifi_wep_104_ascii ();
+ test_read_wifi_leap ();
+ test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_AGENT, NM_SETTING_SECRET_FLAG_AGENT_OWNED);
+ test_read_wifi_leap_secret_flags (TEST_IFCFG_WIFI_LEAP_ALWAYS,
+ NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_read_wifi_wpa_psk ();
+ test_read_wifi_wpa_psk_unquoted ();
+ test_read_wifi_wpa_psk_unquoted2 ();
+ test_read_wifi_wpa_psk_adhoc ();
+ test_read_wifi_wpa_psk_hex ();
+ test_read_wifi_dynamic_wep_leap ();
+ test_read_wifi_wpa_eap_tls ();
+ test_read_wifi_wpa_eap_ttls_tls ();
+ test_read_wifi_wep_eap_ttls_chap ();
+ test_read_wired_qeth_static ();
+ test_read_wifi_wep_no_keys ();
+ test_read_permissions ();
+ test_read_wifi_wep_agent_keys ();
+
+ test_write_wired_static ();
+ test_write_wired_static_ip6_only ();
+ test_write_wired_static_routes ();
+ test_read_write_static_routes_legacy ();
+ test_write_wired_dhcp ();
+ test_write_wired_dhcp_8021x_peap_mschapv2 ();
+ test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED);
+ test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_PATH, NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_write_wired_8021x_tls (NM_SETTING_802_1X_CK_SCHEME_BLOB, NM_SETTING_SECRET_FLAG_NONE);
+ test_write_wifi_open ();
+ test_write_wifi_open_hex_ssid ();
+ test_write_wifi_wep ();
+ test_write_wifi_wep_adhoc ();
+ test_write_wifi_wep_passphrase ();
+ test_write_wifi_wep_40_ascii ();
+ test_write_wifi_wep_104_ascii ();
+ test_write_wifi_leap ();
+ test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED);
+ test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_write_wifi_leap_secret_flags (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
+ test_write_wifi_wpa_psk ("Test Write Wifi WPA PSK",
+ "wifi-wpa-psk-write",
+ FALSE,
+ TRUE,
+ FALSE,
+ DEFAULT_HEX_PSK);
+ test_write_wifi_wpa_psk ("Test Write Wifi WPA2 PSK",
+ "wifi-wpa2-psk-write",
+ FALSE,
+ FALSE,
+ TRUE,
+ DEFAULT_HEX_PSK);
+ test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK",
+ "wifi-wpa-wpa2-psk-write",
+ FALSE,
+ TRUE,
+ TRUE,
+ DEFAULT_HEX_PSK);
+ test_write_wifi_wpa_psk ("Test Write Wifi WEP WPA WPA2 PSK",
+ "wifi-wep-wpa-wpa2-psk-write",
+ TRUE,
+ TRUE,
+ TRUE,
+ DEFAULT_HEX_PSK);
+ test_write_wifi_wpa_psk ("Test Write Wifi WPA WPA2 PSK Passphrase",
+ "wifi-wpa-wpa2-psk-passphrase-write",
+ FALSE,
+ TRUE,
+ TRUE,
+ "really insecure passphrase04!");
+ test_write_wifi_wpa_psk_adhoc ();
+ test_write_wifi_wpa_eap_tls ();
+ test_write_wifi_wpa_eap_ttls_tls ();
+ test_write_wifi_wpa_eap_ttls_mschapv2 ();
+ test_write_wifi_dynamic_wep_leap ();
+ test_write_wired_qeth_dhcp ();
+ test_write_permissions ();
+ test_write_wifi_wep_agent_keys ();
+
+ /* iSCSI / ibft */
+ test_read_ibft_dhcp ();
+ test_read_ibft_static ();
+ test_read_ibft_malformed ("ibft-bad-record-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-record");
+ test_read_ibft_malformed ("ibft-bad-entry-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-entry");
+ test_read_ibft_malformed ("ibft-bad-ipaddr-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-ipaddr");
+ test_read_ibft_malformed ("ibft-bad-gateway-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-gateway");
+ test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1");
+ test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2");
+
+ /* Stuff we expect to fail for now */
+ test_write_wired_pppoe ();
+ test_write_vpn ();
+ test_write_mobile_broadband (TRUE);
+ test_write_mobile_broadband (FALSE);
+ test_read_bridge_main ();
+ test_read_bridge_component ();
+ test_read_vlan_interface ();
+
+ base = g_path_get_basename (argv[0]);
+ fprintf (stdout, "%s: SUCCESS\n", base);
+ g_free (base);
+ return 0;
+}
+
diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c
new file mode 100644
index 000000000..92a0b802f
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/utils.c
@@ -0,0 +1,362 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include "utils.h"
+#include "shvar.h"
+
+/*
+ * utils_bin2hexstr
+ *
+ * Convert a byte-array into a hexadecimal string.
+ *
+ * Code originally by Alex Larsson <alexl@redhat.com> and
+ * copyright Red Hat, Inc. under terms of the LGPL.
+ *
+ */
+char *
+utils_bin2hexstr (const char *bytes, int len, int final_len)
+{
+ static char hex_digits[] = "0123456789abcdef";
+ char *result;
+ int i;
+ gsize buflen = (len * 2) + 1;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */
+ if (final_len > -1)
+ g_return_val_if_fail (final_len < buflen, NULL);
+
+ result = g_malloc0 (buflen);
+ for (i = 0; i < len; i++)
+ {
+ result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
+ result[2*i+1] = hex_digits[bytes[i] & 0xf];
+ }
+ /* Cut converted key off at the correct length for this cipher type */
+ if (final_len > -1)
+ result[final_len] = '\0';
+ else
+ result[buflen - 1] = '\0';
+
+ return result;
+}
+
+/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
+
+static int hex2num (char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
+}
+
+static int hex2byte (const char *hex)
+{
+ int a, b;
+ a = hex2num(*hex++);
+ if (a < 0)
+ return -1;
+ b = hex2num(*hex++);
+ if (b < 0)
+ return -1;
+ return (a << 4) | b;
+}
+
+char *
+utils_hexstr2bin (const char *hex, size_t len)
+{
+ size_t i;
+ int a;
+ const char * ipos = hex;
+ char * buf = NULL;
+ char * opos;
+
+ /* Length must be a multiple of 2 */
+ if ((len % 2) != 0)
+ return NULL;
+
+ opos = buf = g_malloc0 ((len / 2) + 1);
+ for (i = 0; i < len; i += 2) {
+ a = hex2byte (ipos);
+ if (a < 0) {
+ g_free (buf);
+ return NULL;
+ }
+ *opos++ = a;
+ ipos += 2;
+ }
+ return buf;
+}
+
+/* End from hostap */
+
+/*
+ * Check ';[a-fA-F0-9]{8}' file suffix used for temporary files by rpm when
+ * installing packages.
+ *
+ * Implementation taken from upstart.
+ */
+static gboolean
+check_rpm_temp_suffix (const char *path)
+{
+ const char *ptr;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ /* Matches *;[a-fA-F0-9]{8}; used by rpm */
+ ptr = strrchr (path, ';');
+ if (ptr && (strspn (ptr + 1, "abcdefABCDEF0123456789") == 8)
+ && (! ptr[9]))
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+check_suffix (const char *base, const char *tag)
+{
+ int len, tag_len;
+
+ g_return_val_if_fail (base != NULL, TRUE);
+ g_return_val_if_fail (tag != NULL, TRUE);
+
+ len = strlen (base);
+ tag_len = strlen (tag);
+ if ((len > tag_len) && !strcasecmp (base + len - tag_len, tag))
+ return TRUE;
+ return FALSE;
+}
+
+gboolean
+utils_should_ignore_file (const char *filename, gboolean only_ifcfg)
+{
+ char *base;
+ gboolean ignore = TRUE;
+ gboolean is_ifcfg = FALSE;
+ gboolean is_other = FALSE;
+
+ g_return_val_if_fail (filename != NULL, TRUE);
+
+ base = g_path_get_basename (filename);
+ g_return_val_if_fail (base != NULL, TRUE);
+
+ /* Only handle ifcfg, keys, and routes files */
+ if (!strncmp (base, IFCFG_TAG, strlen (IFCFG_TAG)))
+ is_ifcfg = TRUE;
+
+ if (only_ifcfg == FALSE) {
+ if ( !strncmp (base, KEYS_TAG, strlen (KEYS_TAG))
+ || !strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG))
+ || !strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG)))
+ is_other = TRUE;
+ }
+
+ /* But not those that have certain suffixes */
+ if ( (is_ifcfg || is_other)
+ && !check_suffix (base, BAK_TAG)
+ && !check_suffix (base, TILDE_TAG)
+ && !check_suffix (base, ORIG_TAG)
+ && !check_suffix (base, REJ_TAG)
+ && !check_suffix (base, RPMNEW_TAG)
+ && !check_suffix (base, AUGNEW_TAG)
+ && !check_suffix (base, AUGTMP_TAG)
+ && !check_rpm_temp_suffix (base))
+ ignore = FALSE;
+
+ g_free (base);
+ return ignore;
+}
+
+char *
+utils_cert_path (const char *parent, const char *suffix)
+{
+ const char *name;
+ char *dir, *path;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (suffix != NULL, NULL);
+
+ name = utils_get_ifcfg_name (parent, FALSE);
+ dir = g_path_get_dirname (parent);
+ path = g_strdup_printf ("%s/%s-%s", dir, name, suffix);
+ g_free (dir);
+ return path;
+}
+
+const char *
+utils_get_ifcfg_name (const char *file, gboolean only_ifcfg)
+{
+ const char *name = NULL, *start = NULL;
+ char *base;
+
+ g_return_val_if_fail (file != NULL, NULL);
+
+ base = g_path_get_basename (file);
+ if (!base)
+ return NULL;
+
+ /* Find the point in 'file' where 'base' starts. We use 'file' since it's
+ * const and thus will survive after we free 'base'.
+ */
+ start = file + strlen (file) - strlen (base);
+ g_assert (strcmp (start, base) == 0);
+ g_free (base);
+
+ if (!strncmp (start, IFCFG_TAG, strlen (IFCFG_TAG)))
+ name = start + strlen (IFCFG_TAG);
+ else if (only_ifcfg == FALSE) {
+ if (!strncmp (start, KEYS_TAG, strlen (KEYS_TAG)))
+ name = start + strlen (KEYS_TAG);
+ else if (!strncmp (start, ROUTE_TAG, strlen (ROUTE_TAG)))
+ name = start + strlen (ROUTE_TAG);
+ else if (!strncmp (start, ROUTE6_TAG, strlen (ROUTE6_TAG)))
+ name = start + strlen (ROUTE6_TAG);
+ }
+
+ return name;
+}
+
+/* Used to get any ifcfg/extra file path from any other ifcfg/extra path
+ * in the form <tag><name>.
+ */
+static char *
+utils_get_extra_path (const char *parent, const char *tag)
+{
+ char *item_path = NULL, *dirname;
+ const char *name;
+
+ g_return_val_if_fail (parent != NULL, NULL);
+ g_return_val_if_fail (tag != NULL, NULL);
+
+ dirname = g_path_get_dirname (parent);
+ if (!dirname)
+ return NULL;
+
+ name = utils_get_ifcfg_name (parent, FALSE);
+ if (name) {
+ if (!strcmp (dirname, "."))
+ item_path = g_strdup_printf ("%s%s", tag, name);
+ else
+ item_path = g_strdup_printf ("%s/%s%s", dirname, tag, name);
+ }
+ g_free (dirname);
+
+ return item_path;
+}
+
+char *
+utils_get_ifcfg_path (const char *parent)
+{
+ return utils_get_extra_path (parent, IFCFG_TAG);
+}
+
+char *
+utils_get_keys_path (const char *parent)
+{
+ return utils_get_extra_path (parent, KEYS_TAG);
+}
+
+char *
+utils_get_route_path (const char *parent)
+{
+ return utils_get_extra_path (parent, ROUTE_TAG);
+}
+
+char *
+utils_get_route6_path (const char *parent)
+{
+ return utils_get_extra_path (parent, ROUTE6_TAG);
+}
+
+shvarFile *
+utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create)
+{
+ shvarFile *ifcfg = NULL;
+ char *path;
+
+ path = utils_get_extra_path (parent, tag);
+ if (!path)
+ return NULL;
+
+ if (should_create && !g_file_test (path, G_FILE_TEST_EXISTS))
+ ifcfg = svCreateFile (path);
+
+ if (!ifcfg)
+ ifcfg = svNewFile (path);
+
+ g_free (path);
+ return ifcfg;
+}
+
+shvarFile *
+utils_get_keys_ifcfg (const char *parent, gboolean should_create)
+{
+ return utils_get_extra_ifcfg (parent, KEYS_TAG, should_create);
+}
+
+shvarFile *
+utils_get_route_ifcfg (const char *parent, gboolean should_create)
+{
+ return utils_get_extra_ifcfg (parent, ROUTE_TAG, should_create);
+}
+
+shvarFile *
+utils_get_route6_ifcfg (const char *parent, gboolean should_create)
+{
+ return utils_get_extra_ifcfg (parent, ROUTE6_TAG, should_create);
+}
+
+/* Finds out if route file has new or older format
+ * Returns TRUE - new syntax (ADDRESS<n>=a.b.c.d ...), error opening file or empty
+ * FALSE - older syntax, i.e. argument to 'ip route add' (1.2.3.0/24 via 11.22.33.44)
+ */
+gboolean
+utils_has_route_file_new_syntax (const char *filename)
+{
+ char *contents = NULL;
+ gsize len = 0;
+ gboolean ret = FALSE;
+ const char *pattern = "^[[:space:]]*ADDRESS[0-9]+=";
+
+ g_return_val_if_fail (filename != NULL, TRUE);
+
+ if (!g_file_get_contents (filename, &contents, &len, NULL))
+ return TRUE;
+
+ if (len <= 0) {
+ ret = TRUE;
+ goto gone;
+ }
+
+ if (g_regex_match_simple (pattern, contents, G_REGEX_MULTILINE, 0))
+ ret = TRUE;
+
+gone:
+ g_free (contents);
+ return ret;
+}
+
diff --git a/src/settings/plugins/ifcfg-rh/utils.h b/src/settings/plugins/ifcfg-rh/utils.h
new file mode 100644
index 000000000..d5e3a1335
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/utils.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include <glib.h>
+#include "shvar.h"
+#include "common.h"
+
+char *utils_bin2hexstr (const char *bytes, int len, int final_len);
+
+char *utils_hexstr2bin (const char *hex, size_t len);
+
+char *utils_cert_path (const char *parent, const char *suffix);
+
+const char *utils_get_ifcfg_name (const char *file, gboolean only_ifcfg);
+
+gboolean utils_should_ignore_file (const char *filename, gboolean only_ifcfg);
+
+char *utils_get_ifcfg_path (const char *parent);
+char *utils_get_keys_path (const char *parent);
+char *utils_get_route_path (const char *parent);
+char *utils_get_route6_path (const char *parent);
+
+shvarFile *utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create);
+shvarFile *utils_get_keys_ifcfg (const char *parent, gboolean should_create);
+shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create);
+shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create);
+
+gboolean utils_has_route_file_new_syntax (const char *filename);
+
+#endif /* _UTILS_H_ */
+
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
new file mode 100644
index 000000000..6924262f5
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -0,0 +1,1746 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 - 2011 Red Hat, Inc.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-pppoe.h>
+#include <nm-utils.h>
+
+#include "common.h"
+#include "shvar.h"
+#include "reader.h"
+#include "writer.h"
+#include "utils.h"
+#include "crypto.h"
+
+#define PLUGIN_WARN(pname, fmt, args...) \
+ { g_warning (" " pname ": " fmt, ##args); }
+
+static void
+save_secret_flags (shvarFile *ifcfg,
+ const char *key,
+ NMSettingSecretFlags flags)
+{
+ GString *str;
+
+ g_return_if_fail (ifcfg != NULL);
+ g_return_if_fail (key != NULL);
+
+ if (flags == NM_SETTING_SECRET_FLAG_NONE) {
+ svSetValue (ifcfg, key, NULL, FALSE);
+ return;
+ }
+
+ /* Convert flags bitfield into string representation */
+ str = g_string_sized_new (20);
+ if (flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)
+ g_string_append (str, SECRET_FLAG_AGENT);
+
+ if (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED) {
+ if (str->len)
+ g_string_append_c (str, ' ');
+ g_string_append (str, SECRET_FLAG_NOT_SAVED);
+ }
+
+ if (flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED) {
+ if (str->len)
+ g_string_append_c (str, ' ');
+ g_string_append (str, SECRET_FLAG_NOT_REQUIRED);
+ }
+
+ svSetValue (ifcfg, key, str->len ? str->str : NULL, FALSE);
+ g_string_free (str, TRUE);
+}
+
+static void
+set_secret (shvarFile *ifcfg,
+ const char *key,
+ const char *value,
+ const char *flags_key,
+ NMSettingSecretFlags flags,
+ gboolean verbatim)
+{
+ shvarFile *keyfile;
+
+ /* Clear the secret from the ifcfg and the associated "keys" file */
+ svSetValue (ifcfg, key, NULL, FALSE);
+
+ /* Save secret flags */
+ save_secret_flags (ifcfg, flags_key, flags);
+
+ keyfile = utils_get_keys_ifcfg (ifcfg->fileName, TRUE);
+ if (!keyfile) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not create key file for '%s'",
+ ifcfg->fileName);
+ goto error;
+ }
+
+ /* Clear the secret from the associated "keys" file */
+ svSetValue (keyfile, key, NULL, FALSE);
+
+ /* Only write the secret if it's system owned and supposed to be saved */
+ if (flags == NM_SETTING_SECRET_FLAG_NONE)
+ svSetValue (keyfile, key, value, verbatim);
+
+ if (svWriteFile (keyfile, 0600)) {
+ PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not update key file '%s'",
+ keyfile->fileName);
+ svCloseFile (keyfile);
+ goto error;
+ }
+ svCloseFile (keyfile);
+ return;
+
+error:
+ /* Try setting the secret in the actual ifcfg */
+ svSetValue (ifcfg, key, value, FALSE);
+}
+
+static gboolean
+write_secret_file (const char *path,
+ const char *data,
+ gsize len,
+ GError **error)
+{
+ char *tmppath;
+ int fd = -1, written;
+ gboolean success = FALSE;
+
+ tmppath = g_malloc0 (strlen (path) + 10);
+ if (!tmppath) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not allocate memory for temporary file for '%s'",
+ path);
+ return FALSE;
+ }
+
+ memcpy (tmppath, path, strlen (path));
+ strcat (tmppath, ".XXXXXX");
+
+ errno = 0;
+ fd = mkstemp (tmppath);
+ if (fd < 0) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not create temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ /* Only readable by root */
+ errno = 0;
+ if (fchmod (fd, S_IRUSR | S_IWUSR)) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not set permissions for temporary file '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ errno = 0;
+ written = write (fd, data, len);
+ if (written != len) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not write temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+ close (fd);
+
+ /* Try to rename */
+ errno = 0;
+ if (rename (tmppath, path)) {
+ unlink (tmppath);
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not rename temporary file to '%s': %d",
+ path, errno);
+ goto out;
+ }
+ success = TRUE;
+
+out:
+ g_free (tmppath);
+ return success;
+}
+
+typedef struct ObjectType {
+ const char *setting_key;
+ NMSetting8021xCKScheme (*scheme_func)(NMSetting8021x *setting);
+ const char * (*path_func) (NMSetting8021x *setting);
+ const GByteArray * (*blob_func) (NMSetting8021x *setting);
+ const char *ifcfg_key;
+ const char *suffix;
+} ObjectType;
+
+static const ObjectType ca_type = {
+ NM_SETTING_802_1X_CA_CERT,
+ nm_setting_802_1x_get_ca_cert_scheme,
+ nm_setting_802_1x_get_ca_cert_path,
+ nm_setting_802_1x_get_ca_cert_blob,
+ "IEEE_8021X_CA_CERT",
+ "ca-cert.der"
+};
+
+static const ObjectType phase2_ca_type = {
+ NM_SETTING_802_1X_PHASE2_CA_CERT,
+ nm_setting_802_1x_get_phase2_ca_cert_scheme,
+ nm_setting_802_1x_get_phase2_ca_cert_path,
+ nm_setting_802_1x_get_phase2_ca_cert_blob,
+ "IEEE_8021X_INNER_CA_CERT",
+ "inner-ca-cert.der"
+};
+
+static const ObjectType client_type = {
+ NM_SETTING_802_1X_CLIENT_CERT,
+ nm_setting_802_1x_get_client_cert_scheme,
+ nm_setting_802_1x_get_client_cert_path,
+ nm_setting_802_1x_get_client_cert_blob,
+ "IEEE_8021X_CLIENT_CERT",
+ "client-cert.der"
+};
+
+static const ObjectType phase2_client_type = {
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ nm_setting_802_1x_get_phase2_client_cert_scheme,
+ nm_setting_802_1x_get_phase2_client_cert_path,
+ nm_setting_802_1x_get_phase2_client_cert_blob,
+ "IEEE_8021X_INNER_CLIENT_CERT",
+ "inner-client-cert.der"
+};
+
+static const ObjectType pk_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ "IEEE_8021X_PRIVATE_KEY",
+ "private-key.pem"
+};
+
+static const ObjectType phase2_pk_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ "IEEE_8021X_INNER_PRIVATE_KEY",
+ "inner-private-key.pem"
+};
+
+static const ObjectType p12_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ "IEEE_8021X_PRIVATE_KEY",
+ "private-key.p12"
+};
+
+static const ObjectType phase2_p12_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ "IEEE_8021X_INNER_PRIVATE_KEY",
+ "inner-private-key.p12"
+};
+
+static gboolean
+write_object (NMSetting8021x *s_8021x,
+ shvarFile *ifcfg,
+ const ObjectType *objtype,
+ GError **error)
+{
+ NMSetting8021xCKScheme scheme;
+ const char *path = NULL;
+ const GByteArray *blob = NULL;
+
+ g_return_val_if_fail (ifcfg != NULL, FALSE);
+ g_return_val_if_fail (objtype != NULL, FALSE);
+
+ scheme = (*(objtype->scheme_func))(s_8021x);
+ switch (scheme) {
+ case NM_SETTING_802_1X_CK_SCHEME_BLOB:
+ blob = (*(objtype->blob_func))(s_8021x);
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_PATH:
+ path = (*(objtype->path_func))(s_8021x);
+ break;
+ default:
+ break;
+ }
+
+ /* If certificate/private key wasn't sent, the connection may no longer be
+ * 802.1x and thus we clear out the paths and certs.
+ */
+ if (!path && !blob) {
+ char *standard_file;
+ int ignored;
+
+ /* Since no cert/private key is now being used, delete any standard file
+ * that was created for this connection, but leave other files alone.
+ * Thus, for example,
+ * /etc/sysconfig/network-scripts/ca-cert-Test_Write_Wifi_WPA_EAP-TLS.der
+ * will be deleted, but /etc/pki/tls/cert.pem will not.
+ */
+ standard_file = utils_cert_path (ifcfg->fileName, objtype->suffix);
+ if (g_file_test (standard_file, G_FILE_TEST_EXISTS))
+ ignored = unlink (standard_file);
+ g_free (standard_file);
+
+ svSetValue (ifcfg, objtype->ifcfg_key, NULL, FALSE);
+ return TRUE;
+ }
+
+ /* If the object path was specified, prefer that over any raw cert data that
+ * may have been sent.
+ */
+ if (path) {
+ svSetValue (ifcfg, objtype->ifcfg_key, path, FALSE);
+ return TRUE;
+ }
+
+ /* If it's raw certificate data, write the data out to the standard file */
+ if (blob) {
+ gboolean success;
+ char *new_file;
+ GError *write_error = NULL;
+
+ new_file = utils_cert_path (ifcfg->fileName, objtype->suffix);
+ if (!new_file) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not create file path for %s / %s",
+ NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key);
+ return FALSE;
+ }
+
+ /* Write the raw certificate data out to the standard file so that we
+ * can use paths from now on instead of pushing around the certificate
+ * data itself.
+ */
+ success = write_secret_file (new_file, (const char *) blob->data, blob->len, &write_error);
+ if (success) {
+ svSetValue (ifcfg, objtype->ifcfg_key, new_file, FALSE);
+ return TRUE;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not write certificate/key for %s / %s: %s",
+ NM_SETTING_802_1X_SETTING_NAME, objtype->setting_key,
+ (write_error && write_error->message) ? write_error->message : "(unknown)");
+ g_clear_error (&write_error);
+ }
+ g_free (new_file);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+write_8021x_certs (NMSetting8021x *s_8021x,
+ gboolean phase2,
+ shvarFile *ifcfg,
+ GError **error)
+{
+ const char *password = NULL;
+ gboolean success = FALSE, is_pkcs12 = FALSE;
+ const ObjectType *otype = NULL;
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* CA certificate */
+ if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_ca_type : &ca_type, error))
+ return FALSE;
+
+ /* Private key */
+ if (phase2) {
+ otype = &phase2_pk_type;
+ if (nm_setting_802_1x_get_phase2_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+ otype = &phase2_p12_type;
+ is_pkcs12 = TRUE;
+ }
+ password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x);
+ flags = nm_setting_802_1x_get_phase2_private_key_password_flags (s_8021x);
+ } else {
+ otype = &pk_type;
+ if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
+ otype = &p12_type;
+ is_pkcs12 = TRUE;
+ }
+ password = nm_setting_802_1x_get_private_key_password (s_8021x);
+ flags = nm_setting_802_1x_get_private_key_password_flags (s_8021x);
+ }
+
+ /* Save the private key */
+ if (!write_object (s_8021x, ifcfg, otype, error))
+ goto out;
+
+ /* Private key password */
+ if (phase2) {
+ set_secret (ifcfg,
+ "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD",
+ password,
+ "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS",
+ flags,
+ FALSE);
+ } else {
+ set_secret (ifcfg,
+ "IEEE_8021X_PRIVATE_KEY_PASSWORD",
+ password,
+ "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS",
+ flags,
+ FALSE);
+ }
+
+ /* Client certificate */
+ if (is_pkcs12) {
+ /* Don't need a client certificate with PKCS#12 since the file is both
+ * the client certificate and the private key in one file.
+ */
+ svSetValue (ifcfg,
+ phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT",
+ NULL, FALSE);
+ } else {
+ /* Save the client certificate */
+ if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_client_type : &client_type, error))
+ goto out;
+ }
+
+ success = TRUE;
+
+out:
+ return success;
+}
+
+static gboolean
+write_8021x_setting (NMConnection *connection,
+ shvarFile *ifcfg,
+ gboolean wired,
+ GError **error)
+{
+ NMSetting8021x *s_8021x;
+ const char *value;
+ char *tmp = NULL;
+ gboolean success = FALSE;
+ GString *phase2_auth;
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ if (!s_8021x) {
+ /* If wired, clear KEY_MGMT */
+ if (wired)
+ svSetValue (ifcfg, "KEY_MGMT", NULL, FALSE);
+ return TRUE;
+ }
+
+ /* If wired, write KEY_MGMT */
+ if (wired)
+ svSetValue (ifcfg, "KEY_MGMT", "IEEE8021X", FALSE);
+
+ /* EAP method */
+ if (nm_setting_802_1x_get_num_eap_methods (s_8021x)) {
+ value = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ if (value)
+ tmp = g_ascii_strup (value, -1);
+ }
+ svSetValue (ifcfg, "IEEE_8021X_EAP_METHODS", tmp ? tmp : NULL, FALSE);
+ g_free (tmp);
+
+ svSetValue (ifcfg, "IEEE_8021X_IDENTITY",
+ nm_setting_802_1x_get_identity (s_8021x),
+ FALSE);
+
+ svSetValue (ifcfg, "IEEE_8021X_ANON_IDENTITY",
+ nm_setting_802_1x_get_anonymous_identity (s_8021x),
+ FALSE);
+
+ set_secret (ifcfg,
+ "IEEE_8021X_PASSWORD",
+ nm_setting_802_1x_get_password (s_8021x),
+ "IEEE_8021X_PASSWORD_FLAGS",
+ nm_setting_802_1x_get_password_flags (s_8021x),
+ FALSE);
+
+ /* PEAP version */
+ value = nm_setting_802_1x_get_phase1_peapver (s_8021x);
+ svSetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", NULL, FALSE);
+ if (value && (!strcmp (value, "0") || !strcmp (value, "1")))
+ svSetValue (ifcfg, "IEEE_8021X_PEAP_VERSION", value, FALSE);
+
+ /* Force new PEAP label */
+ value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x);
+ svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", NULL, FALSE);
+ if (value && !strcmp (value, "1"))
+ svSetValue (ifcfg, "IEEE_8021X_PEAP_FORCE_NEW_LABEL", "yes", FALSE);
+
+ /* Phase2 auth methods */
+ svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS", NULL, FALSE);
+ phase2_auth = g_string_new (NULL);
+
+ value = nm_setting_802_1x_get_phase2_auth (s_8021x);
+ if (value) {
+ tmp = g_ascii_strup (value, -1);
+ g_string_append (phase2_auth, tmp);
+ g_free (tmp);
+ }
+
+ value = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+ if (value) {
+ if (phase2_auth->len)
+ g_string_append_c (phase2_auth, ' ');
+
+ tmp = g_ascii_strup (value, -1);
+ g_string_append_printf (phase2_auth, "EAP-%s", tmp);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "IEEE_8021X_INNER_AUTH_METHODS",
+ phase2_auth->len ? phase2_auth->str : NULL,
+ FALSE);
+
+ g_string_free (phase2_auth, TRUE);
+
+ success = write_8021x_certs (s_8021x, FALSE, ifcfg, error);
+ if (success) {
+ /* phase2/inner certs */
+ success = write_8021x_certs (s_8021x, TRUE, ifcfg, error);
+ }
+
+ return success;
+}
+
+static gboolean
+write_wireless_security_setting (NMConnection *connection,
+ shvarFile *ifcfg,
+ gboolean adhoc,
+ gboolean *no_8021x,
+ GError **error)
+{
+ NMSettingWirelessSecurity *s_wsec;
+ const char *key_mgmt, *auth_alg, *key, *proto, *cipher, *psk;
+ gboolean wep = FALSE, wpa = FALSE, dynamic_wep = FALSE;
+ char *tmp;
+ guint32 i, num;
+ GString *str;
+
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ if (!s_wsec) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing '%s' setting", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ return FALSE;
+ }
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ g_assert (key_mgmt);
+
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+
+ svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE);
+
+ if (!strcmp (key_mgmt, "none")) {
+ wep = TRUE;
+ *no_8021x = TRUE;
+ } else if (!strcmp (key_mgmt, "wpa-none") || !strcmp (key_mgmt, "wpa-psk")) {
+ svSetValue (ifcfg, "KEY_MGMT", "WPA-PSK", FALSE);
+ wpa = TRUE;
+ *no_8021x = TRUE;
+ } else if (!strcmp (key_mgmt, "ieee8021x")) {
+ svSetValue (ifcfg, "KEY_MGMT", "IEEE8021X", FALSE);
+ dynamic_wep = TRUE;
+ } else if (!strcmp (key_mgmt, "wpa-eap")) {
+ svSetValue (ifcfg, "KEY_MGMT", "WPA-EAP", FALSE);
+ wpa = TRUE;
+ }
+
+ svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE);
+ if (auth_alg) {
+ if (!strcmp (auth_alg, "shared"))
+ svSetValue (ifcfg, "SECURITYMODE", "restricted", FALSE);
+ else if (!strcmp (auth_alg, "open"))
+ svSetValue (ifcfg, "SECURITYMODE", "open", FALSE);
+ else if (!strcmp (auth_alg, "leap")) {
+ svSetValue (ifcfg, "SECURITYMODE", "leap", FALSE);
+ svSetValue (ifcfg, "IEEE_8021X_IDENTITY",
+ nm_setting_wireless_security_get_leap_username (s_wsec),
+ FALSE);
+ set_secret (ifcfg,
+ "IEEE_8021X_PASSWORD",
+ nm_setting_wireless_security_get_leap_password (s_wsec),
+ "IEEE_8021X_PASSWORD_FLAGS",
+ nm_setting_wireless_security_get_leap_password_flags (s_wsec),
+ FALSE);
+ *no_8021x = TRUE;
+ }
+ }
+
+ /* WEP keys */
+
+ /* Clear any default key */
+ set_secret (ifcfg, "KEY", NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+
+ /* Clear existing keys */
+ for (i = 0; i < 4; i++) {
+ tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1);
+ set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+ g_free (tmp);
+
+ tmp = g_strdup_printf ("KEY%d", i + 1);
+ set_secret (ifcfg, tmp, NULL, "WEP_KEY_FLAGS", NM_SETTING_SECRET_FLAG_NONE, FALSE);
+ g_free (tmp);
+ }
+
+ /* And write the new ones out */
+ if (wep) {
+ /* Default WEP TX key index */
+ tmp = g_strdup_printf ("%d", nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) + 1);
+ svSetValue (ifcfg, "DEFAULTKEY", tmp, FALSE);
+ g_free (tmp);
+
+ for (i = 0; i < 4; i++) {
+ NMWepKeyType key_type;
+
+ key = nm_setting_wireless_security_get_wep_key (s_wsec, i);
+ if (key) {
+ char *ascii_key = NULL;
+
+ /* Passphrase needs a different ifcfg key since with WEP, there
+ * are some passphrases that are indistinguishable from WEP hex
+ * keys.
+ */
+ key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec);
+ if (key_type == NM_WEP_KEY_TYPE_PASSPHRASE)
+ tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1);
+ else {
+ tmp = g_strdup_printf ("KEY%d", i + 1);
+
+ /* Add 's:' prefix for ASCII keys */
+ if (strlen (key) == 5 || strlen (key) == 13) {
+ ascii_key = g_strdup_printf ("s:%s", key);
+ key = ascii_key;
+ }
+ }
+
+ set_secret (ifcfg,
+ tmp,
+ key,
+ "WEP_KEY_FLAGS",
+ nm_setting_wireless_security_get_wep_key_flags (s_wsec),
+ FALSE);
+ g_free (tmp);
+ g_free (ascii_key);
+ }
+ }
+ }
+
+ /* WPA protos */
+ svSetValue (ifcfg, "WPA_ALLOW_WPA", NULL, FALSE);
+ svSetValue (ifcfg, "WPA_ALLOW_WPA2", NULL, FALSE);
+ num = nm_setting_wireless_security_get_num_protos (s_wsec);
+ for (i = 0; i < num; i++) {
+ proto = nm_setting_wireless_security_get_proto (s_wsec, i);
+ if (proto && !strcmp (proto, "wpa"))
+ svSetValue (ifcfg, "WPA_ALLOW_WPA", "yes", FALSE);
+ else if (proto && !strcmp (proto, "rsn"))
+ svSetValue (ifcfg, "WPA_ALLOW_WPA2", "yes", FALSE);
+ }
+
+ /* WPA Pairwise ciphers */
+ svSetValue (ifcfg, "CIPHER_PAIRWISE", NULL, FALSE);
+ str = g_string_new (NULL);
+ num = nm_setting_wireless_security_get_num_pairwise (s_wsec);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (str, ' ');
+ cipher = nm_setting_wireless_security_get_pairwise (s_wsec, i);
+
+ /* Don't write out WEP40 or WEP104 if for some reason they are set; they
+ * are not valid pairwise ciphers.
+ */
+ if (strcmp (cipher, "wep40") && strcmp (cipher, "wep104")) {
+ tmp = g_ascii_strup (cipher, -1);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+ }
+ if (strlen (str->str) && (dynamic_wep == FALSE))
+ svSetValue (ifcfg, "CIPHER_PAIRWISE", str->str, FALSE);
+ g_string_free (str, TRUE);
+
+ /* WPA Group ciphers */
+ svSetValue (ifcfg, "CIPHER_GROUP", NULL, FALSE);
+ str = g_string_new (NULL);
+ num = nm_setting_wireless_security_get_num_groups (s_wsec);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (str, ' ');
+ cipher = nm_setting_wireless_security_get_group (s_wsec, i);
+ tmp = g_ascii_strup (cipher, -1);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+ if (strlen (str->str) && (dynamic_wep == FALSE))
+ svSetValue (ifcfg, "CIPHER_GROUP", str->str, FALSE);
+ g_string_free (str, TRUE);
+
+ /* WPA Passphrase */
+ if (wpa) {
+ GString *quoted = NULL;
+
+ psk = nm_setting_wireless_security_get_psk (s_wsec);
+ if (psk && (strlen (psk) != 64)) {
+ /* Quote the PSK since it's a passphrase */
+ quoted = g_string_sized_new (strlen (psk) + 2); /* 2 for quotes */
+ g_string_append_c (quoted, '"');
+ g_string_append (quoted, psk);
+ g_string_append_c (quoted, '"');
+ }
+ set_secret (ifcfg,
+ "WPA_PSK",
+ quoted ? quoted->str : psk,
+ "WPA_PSK_FLAGS",
+ nm_setting_wireless_security_get_psk_flags (s_wsec),
+ TRUE);
+ if (quoted)
+ g_string_free (quoted, TRUE);
+ } else {
+ set_secret (ifcfg,
+ "WPA_PSK",
+ NULL,
+ "WPA_PSK_FLAGS",
+ NM_SETTING_SECRET_FLAG_NONE,
+ FALSE);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+write_wireless_setting (NMConnection *connection,
+ shvarFile *ifcfg,
+ gboolean *no_8021x,
+ GError **error)
+{
+ NMSettingWireless *s_wireless;
+ char *tmp, *tmp2;
+ const GByteArray *ssid, *device_mac, *cloned_mac, *bssid;
+ const char *mode;
+ char buf[33];
+ guint32 mtu, chan, i;
+ gboolean adhoc = FALSE, hex_ssid = FALSE;
+
+ s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ if (!s_wireless) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ svSetValue (ifcfg, "HWADDR", NULL, FALSE);
+ device_mac = nm_setting_wireless_get_mac_address (s_wireless);
+ if (device_mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ device_mac->data[0], device_mac->data[1], device_mac->data[2],
+ device_mac->data[3], device_mac->data[4], device_mac->data[5]);
+ svSetValue (ifcfg, "HWADDR", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "MACADDR", NULL, FALSE);
+ cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
+ if (cloned_mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
+ cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
+ svSetValue (ifcfg, "MACADDR", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "MTU", NULL, FALSE);
+ mtu = nm_setting_wireless_get_mtu (s_wireless);
+ if (mtu) {
+ tmp = g_strdup_printf ("%u", mtu);
+ svSetValue (ifcfg, "MTU", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ ssid = nm_setting_wireless_get_ssid (s_wireless);
+ if (!ssid) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+ if (!ssid->len || ssid->len > 32) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid SSID in '%s' setting", NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ /* If the SSID contains any non-printable characters, we need to use the
+ * hex notation of the SSID instead.
+ */
+ for (i = 0; i < ssid->len; i++) {
+ if (!isprint (ssid->data[i])) {
+ hex_ssid = TRUE;
+ break;
+ }
+ }
+
+ if (hex_ssid) {
+ GString *str;
+
+ /* Hex SSIDs don't get quoted */
+ str = g_string_sized_new (ssid->len * 2 + 3);
+ g_string_append (str, "0x");
+ for (i = 0; i < ssid->len; i++)
+ g_string_append_printf (str, "%02X", ssid->data[i]);
+ svSetValue (ifcfg, "ESSID", str->str, TRUE);
+ g_string_free (str, TRUE);
+ } else {
+ /* Printable SSIDs always get quoted */
+ memset (buf, 0, sizeof (buf));
+ memcpy (buf, ssid->data, ssid->len);
+ tmp = svEscape (buf);
+
+ /* svEscape will usually quote the string, but just for consistency,
+ * if svEscape doesn't quote the ESSID, we quote it ourselves.
+ */
+ if (tmp[0] != '"' && tmp[strlen (tmp) - 1] != '"') {
+ tmp2 = g_strdup_printf ("\"%s\"", tmp);
+ svSetValue (ifcfg, "ESSID", tmp2, TRUE);
+ g_free (tmp2);
+ } else
+ svSetValue (ifcfg, "ESSID", tmp, TRUE);
+ g_free (tmp);
+ }
+
+ mode = nm_setting_wireless_get_mode (s_wireless);
+ if (!mode || !strcmp (mode, "infrastructure")) {
+ svSetValue (ifcfg, "MODE", "Managed", FALSE);
+ } else if (!strcmp (mode, "adhoc")) {
+ svSetValue (ifcfg, "MODE", "Ad-Hoc", FALSE);
+ adhoc = TRUE;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Invalid mode '%s' in '%s' setting",
+ mode, NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ svSetValue (ifcfg, "CHANNEL", NULL, FALSE);
+ chan = nm_setting_wireless_get_channel (s_wireless);
+ if (chan) {
+ tmp = g_strdup_printf ("%u", chan);
+ svSetValue (ifcfg, "CHANNEL", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "BSSID", NULL, FALSE);
+ bssid = nm_setting_wireless_get_bssid (s_wireless);
+ if (bssid) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ bssid->data[0], bssid->data[1], bssid->data[2],
+ bssid->data[3], bssid->data[4], bssid->data[5]);
+ svSetValue (ifcfg, "BSSID", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security;
+ * otherwise there's no way to detect WEP vs. open when WEP keys aren't
+ * saved.
+ */
+ svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE);
+ svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE);
+
+ if (nm_setting_wireless_get_security (s_wireless)) {
+ if (!write_wireless_security_setting (connection, ifcfg, adhoc, no_8021x, error))
+ return FALSE;
+ }
+
+ svSetValue (ifcfg, "TYPE", TYPE_WIRELESS, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+ NMSettingWired *s_wired;
+ const GByteArray *device_mac, *cloned_mac;
+ char *tmp;
+ const char *nettype, *portname, *s390_key, *s390_val;
+ guint32 mtu, num_opts, i;
+ const GPtrArray *s390_subchannels;
+ GString *str;
+
+ s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+ if (!s_wired) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing '%s' setting", NM_SETTING_WIRED_SETTING_NAME);
+ return FALSE;
+ }
+
+ svSetValue (ifcfg, "HWADDR", NULL, FALSE);
+ device_mac = nm_setting_wired_get_mac_address (s_wired);
+ if (device_mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ device_mac->data[0], device_mac->data[1], device_mac->data[2],
+ device_mac->data[3], device_mac->data[4], device_mac->data[5]);
+ svSetValue (ifcfg, "HWADDR", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
+ if (cloned_mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
+ cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
+ svSetValue (ifcfg, "MACADDR", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "MTU", NULL, FALSE);
+ mtu = nm_setting_wired_get_mtu (s_wired);
+ if (mtu) {
+ tmp = g_strdup_printf ("%u", mtu);
+ svSetValue (ifcfg, "MTU", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "SUBCHANNELS", NULL, FALSE);
+ s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired);
+ if (s390_subchannels) {
+ tmp = NULL;
+ if (s390_subchannels->len == 2) {
+ tmp = g_strdup_printf ("%s,%s",
+ (const char *) g_ptr_array_index (s390_subchannels, 0),
+ (const char *) g_ptr_array_index (s390_subchannels, 1));
+ } else if (s390_subchannels->len == 3) {
+ tmp = g_strdup_printf ("%s,%s,%s",
+ (const char *) g_ptr_array_index (s390_subchannels, 0),
+ (const char *) g_ptr_array_index (s390_subchannels, 1),
+ (const char *) g_ptr_array_index (s390_subchannels, 2));
+ }
+ svSetValue (ifcfg, "SUBCHANNELS", tmp, FALSE);
+ g_free (tmp);
+ }
+
+ svSetValue (ifcfg, "NETTYPE", NULL, FALSE);
+ nettype = nm_setting_wired_get_s390_nettype (s_wired);
+ if (nettype)
+ svSetValue (ifcfg, "NETTYPE", nettype, FALSE);
+
+ svSetValue (ifcfg, "PORTNAME", NULL, FALSE);
+ portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname");
+ if (portname)
+ svSetValue (ifcfg, "PORTNAME", portname, FALSE);
+
+ svSetValue (ifcfg, "OPTIONS", NULL, FALSE);
+ num_opts = nm_setting_wired_get_num_s390_options (s_wired);
+ if (s390_subchannels && num_opts) {
+ str = g_string_sized_new (30);
+ for (i = 0; i < num_opts; i++) {
+ nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val);
+
+ /* portname is handled separately */
+ if (!strcmp (s390_key, "portname"))
+ continue;
+
+ if (str->len)
+ g_string_append_c (str, ' ');
+ g_string_append_printf (str, "%s=%s", s390_key, s390_val);
+ }
+ if (str->len)
+ svSetValue (ifcfg, "OPTIONS", str->str, FALSE);
+ g_string_free (str, TRUE);
+ }
+
+ svSetValue (ifcfg, "TYPE", TYPE_ETHERNET, FALSE);
+
+ return TRUE;
+}
+
+static void
+write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
+{
+ guint32 n, i;
+ GString *str;
+
+ svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE);
+ svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE);
+ svSetValue (ifcfg, "ONBOOT",
+ nm_setting_connection_get_autoconnect (s_con) ? "yes" : "no",
+ FALSE);
+
+ /* Permissions */
+ svSetValue (ifcfg, "USERS", NULL, FALSE);
+ n = nm_setting_connection_get_num_permissions (s_con);
+ if (n > 0) {
+ str = g_string_sized_new (n * 20);
+
+ for (i = 0; i < n; i++) {
+ const char *puser = NULL;
+
+ /* Items separated by space for consistency with eg
+ * IPV6ADDR_SECONDARIES and DOMAIN.
+ */
+ if (str->len)
+ g_string_append_c (str, ' ');
+
+ if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL))
+ g_string_append (str, puser);
+ }
+ svSetValue (ifcfg, "USERS", str->str, FALSE);
+ g_string_free (str, TRUE);
+ }
+}
+
+static gboolean
+write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError **error)
+{
+ char dest[INET_ADDRSTRLEN];
+ char next_hop[INET_ADDRSTRLEN];
+ char **route_items;
+ char *route_contents;
+ NMIP4Route *route;
+ guint32 ip, prefix, metric;
+ guint32 i, num;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (s_ip4 != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ num = nm_setting_ip4_config_get_num_routes (s_ip4);
+ if (num == 0) {
+ unlink (filename);
+ return TRUE;
+ }
+
+ route_items = g_malloc0 (sizeof (char*) * (num + 1));
+ for (i = 0; i < num; i++) {
+ route = nm_setting_ip4_config_get_route (s_ip4, i);
+
+ memset (dest, 0, sizeof (dest));
+ ip = nm_ip4_route_get_dest (route);
+ inet_ntop (AF_INET, (const void *) &ip, &dest[0], sizeof (dest));
+
+ prefix = nm_ip4_route_get_prefix (route);
+
+ memset (next_hop, 0, sizeof (next_hop));
+ ip = nm_ip4_route_get_next_hop (route);
+ inet_ntop (AF_INET, (const void *) &ip, &next_hop[0], sizeof (next_hop));
+
+ metric = nm_ip4_route_get_metric (route);
+
+ route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric);
+ }
+ route_items[num] = NULL;
+ route_contents = g_strjoinv (NULL, route_items);
+ g_strfreev (route_items);
+
+ if (!g_file_set_contents (filename, route_contents, -1, NULL)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Writing route file '%s' failed", filename);
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ g_free (route_contents);
+
+ return success;
+}
+
+static gboolean
+write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+ NMSettingIP4Config *s_ip4;
+ const char *value;
+ char *addr_key, *prefix_key, *netmask_key, *gw_key, *metric_key, *tmp;
+ char *route_path = NULL;
+ guint32 i, num;
+ GString *searches;
+ gboolean success = FALSE;
+ gboolean fake_ip4 = FALSE;
+ const char *method = NULL;
+
+ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+ if (s_ip4)
+ method = nm_setting_ip4_config_get_method (s_ip4);
+
+ /* Missing IP4 setting is assumed to be DHCP */
+ if (!method)
+ method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
+
+ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
+ int result;
+
+ /* IPv4 disabled, clear IPv4 related parameters */
+ svSetValue (ifcfg, "BOOTPROTO", NULL, FALSE);
+ for (i = 0; i < 254; i++) {
+ if (i == 0) {
+ addr_key = g_strdup ("IPADDR");
+ prefix_key = g_strdup ("PREFIX");
+ gw_key = g_strdup ("GATEWAY");
+ } else {
+ addr_key = g_strdup_printf ("IPADDR%d", i + 1);
+ prefix_key = g_strdup_printf ("PREFIX%d", i + 1);
+ gw_key = g_strdup_printf ("GATEWAY%d", i + 1);
+ }
+
+ svSetValue (ifcfg, addr_key, NULL, FALSE);
+ svSetValue (ifcfg, prefix_key, NULL, FALSE);
+ svSetValue (ifcfg, gw_key, NULL, FALSE);
+ }
+
+ route_path = utils_get_route_path (ifcfg->fileName);
+ result = unlink (route_path);
+ g_free (route_path);
+ return TRUE;
+ }
+
+ /* Temporarily create fake IP4 setting if missing; method set to DHCP above */
+ if (!s_ip4) {
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ fake_ip4 = TRUE;
+ }
+
+ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO))
+ svSetValue (ifcfg, "BOOTPROTO", "dhcp", FALSE);
+ else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
+ svSetValue (ifcfg, "BOOTPROTO", "none", FALSE);
+ else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
+ svSetValue (ifcfg, "BOOTPROTO", "autoip", FALSE);
+ else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
+ svSetValue (ifcfg, "BOOTPROTO", "shared", FALSE);
+
+ num = nm_setting_ip4_config_get_num_addresses (s_ip4);
+ for (i = 0; i < 254; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ NMIP4Address *addr;
+ guint32 ip;
+
+ if (i == 0) {
+ addr_key = g_strdup ("IPADDR");
+ prefix_key = g_strdup ("PREFIX");
+ gw_key = g_strdup ("GATEWAY");
+ } else {
+ addr_key = g_strdup_printf ("IPADDR%d", i + 1);
+ prefix_key = g_strdup_printf ("PREFIX%d", i + 1);
+ gw_key = g_strdup_printf ("GATEWAY%d", i + 1);
+ }
+
+ if (i >= num) {
+ svSetValue (ifcfg, addr_key, NULL, FALSE);
+ svSetValue (ifcfg, prefix_key, NULL, FALSE);
+ svSetValue (ifcfg, gw_key, NULL, FALSE);
+ } else {
+ addr = nm_setting_ip4_config_get_address (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_address_get_address (addr);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (ifcfg, addr_key, &buf[0], FALSE);
+
+ tmp = g_strdup_printf ("%u", nm_ip4_address_get_prefix (addr));
+ svSetValue (ifcfg, prefix_key, tmp, FALSE);
+ g_free (tmp);
+
+ if (nm_ip4_address_get_gateway (addr)) {
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_address_get_gateway (addr);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (ifcfg, gw_key, &buf[0], FALSE);
+ } else
+ svSetValue (ifcfg, gw_key, NULL, FALSE);
+ }
+
+ g_free (addr_key);
+ g_free (prefix_key);
+ g_free (gw_key);
+ }
+
+ num = nm_setting_ip4_config_get_num_dns (s_ip4);
+ for (i = 0; i < 254; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ guint32 ip;
+
+ addr_key = g_strdup_printf ("DNS%d", i + 1);
+
+ if (i >= num)
+ svSetValue (ifcfg, addr_key, NULL, FALSE);
+ else {
+ ip = nm_setting_ip4_config_get_dns (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (ifcfg, addr_key, &buf[0], FALSE);
+ }
+ g_free (addr_key);
+ }
+
+ num = nm_setting_ip4_config_get_num_dns_searches (s_ip4);
+ if (num > 0) {
+ searches = g_string_new (NULL);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (searches, ' ');
+ g_string_append (searches, nm_setting_ip4_config_get_dns_search (s_ip4, i));
+ }
+ svSetValue (ifcfg, "DOMAIN", searches->str, FALSE);
+ g_string_free (searches, TRUE);
+ } else
+ svSetValue (ifcfg, "DOMAIN", NULL, FALSE);
+
+ /* DEFROUTE; remember that it has the opposite meaning from never-default */
+ svSetValue (ifcfg, "DEFROUTE",
+ nm_setting_ip4_config_get_never_default (s_ip4) ? "no" : "yes",
+ FALSE);
+
+ svSetValue (ifcfg, "PEERDNS", NULL, FALSE);
+ svSetValue (ifcfg, "PEERROUTES", NULL, FALSE);
+ svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE);
+ svSetValue (ifcfg, "DHCP_CLIENT_ID", NULL, FALSE);
+ if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
+ svSetValue (ifcfg, "PEERDNS",
+ nm_setting_ip4_config_get_ignore_auto_dns (s_ip4) ? "no" : "yes",
+ FALSE);
+
+ svSetValue (ifcfg, "PEERROUTES",
+ nm_setting_ip4_config_get_ignore_auto_routes (s_ip4) ? "no" : "yes",
+ FALSE);
+
+ value = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
+ if (value)
+ svSetValue (ifcfg, "DHCP_HOSTNAME", value, FALSE);
+
+ value = nm_setting_ip4_config_get_dhcp_client_id (s_ip4);
+ if (value)
+ svSetValue (ifcfg, "DHCP_CLIENT_ID", value, FALSE);
+ }
+
+ svSetValue (ifcfg, "IPV4_FAILURE_FATAL",
+ nm_setting_ip4_config_get_may_fail (s_ip4) ? "no" : "yes",
+ FALSE);
+
+ /* Static routes - route-<name> file */
+ route_path = utils_get_route_path (ifcfg->fileName);
+ if (!route_path) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not get route file path for '%s'", ifcfg->fileName);
+ goto out;
+ }
+
+ if (utils_has_route_file_new_syntax (route_path)) {
+ shvarFile *routefile;
+
+ g_free (route_path);
+ routefile = utils_get_route_ifcfg (ifcfg->fileName, TRUE);
+ if (!routefile) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not create route file '%s'", routefile->fileName);
+ goto out;
+ }
+
+ num = nm_setting_ip4_config_get_num_routes (s_ip4);
+ for (i = 0; i < 256; i++) {
+ char buf[INET_ADDRSTRLEN];
+ NMIP4Route *route;
+ guint32 ip, metric;
+
+ addr_key = g_strdup_printf ("ADDRESS%d", i);
+ netmask_key = g_strdup_printf ("NETMASK%d", i);
+ gw_key = g_strdup_printf ("GATEWAY%d", i);
+ metric_key = g_strdup_printf ("METRIC%d", i);
+
+ if (i >= num) {
+ svSetValue (routefile, addr_key, NULL, FALSE);
+ svSetValue (routefile, netmask_key, NULL, FALSE);
+ svSetValue (routefile, gw_key, NULL, FALSE);
+ svSetValue (routefile, metric_key, NULL, FALSE);
+ } else {
+ route = nm_setting_ip4_config_get_route (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_route_get_dest (route);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (routefile, addr_key, &buf[0], FALSE);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route));
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (routefile, netmask_key, &buf[0], FALSE);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_route_get_next_hop (route);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0], sizeof (buf));
+ svSetValue (routefile, gw_key, &buf[0], FALSE);
+
+ memset (buf, 0, sizeof (buf));
+ metric = nm_ip4_route_get_metric (route);
+ if (metric == 0)
+ svSetValue (routefile, metric_key, NULL, FALSE);
+ else {
+ tmp = g_strdup_printf ("%u", metric);
+ svSetValue (routefile, metric_key, tmp, FALSE);
+ g_free (tmp);
+ }
+ }
+
+ g_free (addr_key);
+ g_free (netmask_key);
+ g_free (gw_key);
+ g_free (metric_key);
+ }
+ if (svWriteFile (routefile, 0644)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not update route file '%s'", routefile->fileName);
+ svCloseFile (routefile);
+ goto out;
+ }
+ svCloseFile (routefile);
+ } else {
+ write_route_file_legacy (route_path, s_ip4, error);
+ g_free (route_path);
+ if (error && *error)
+ goto out;
+ }
+
+ success = TRUE;
+
+out:
+ if (fake_ip4)
+ g_object_unref (s_ip4);
+
+ return success;
+}
+
+static gboolean
+write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error)
+{
+ char dest[INET6_ADDRSTRLEN];
+ char next_hop[INET6_ADDRSTRLEN];
+ char **route_items;
+ char *route_contents;
+ NMIP6Route *route;
+ const struct in6_addr *ip;
+ guint32 prefix, metric;
+ guint32 i, num;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (s_ip6 != NULL, FALSE);
+ g_return_val_if_fail (error != NULL, FALSE);
+ g_return_val_if_fail (*error == NULL, FALSE);
+
+ num = nm_setting_ip6_config_get_num_routes (s_ip6);
+ if (num == 0) {
+ unlink (filename);
+ return TRUE;
+ }
+
+ route_items = g_malloc0 (sizeof (char*) * (num + 1));
+ for (i = 0; i < num; i++) {
+ route = nm_setting_ip6_config_get_route (s_ip6, i);
+
+ memset (dest, 0, sizeof (dest));
+ ip = nm_ip6_route_get_dest (route);
+ inet_ntop (AF_INET6, (const void *) ip, &dest[0], sizeof (dest));
+
+ prefix = nm_ip6_route_get_prefix (route);
+
+ memset (next_hop, 0, sizeof (next_hop));
+ ip = nm_ip6_route_get_next_hop (route);
+ inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], sizeof (next_hop));
+
+ metric = nm_ip6_route_get_metric (route);
+
+ route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric);
+ }
+ route_items[num] = NULL;
+ route_contents = g_strjoinv (NULL, route_items);
+ g_strfreev (route_items);
+
+ if (!g_file_set_contents (filename, route_contents, -1, NULL)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Writing route6 file '%s' failed", filename);
+ goto error;
+ }
+
+ success = TRUE;
+
+error:
+ g_free (route_contents);
+ return success;
+}
+
+static gboolean
+write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+ NMSettingIP6Config *s_ip6;
+ NMSettingIP4Config *s_ip4;
+ const char *value;
+ char *addr_key, *prefix;
+ guint32 i, num, num4;
+ GString *searches;
+ char buf[INET6_ADDRSTRLEN];
+ NMIP6Address *addr;
+ const struct in6_addr *ip;
+ GString *ip_str1, *ip_str2, *ip_ptr;
+ char *route6_path;
+
+ s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+ if (!s_ip6) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ return FALSE;
+ }
+
+ value = nm_setting_ip6_config_get_method (s_ip6);
+ g_assert (value);
+ if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
+ svSetValue (ifcfg, "IPV6INIT", "no", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
+ return TRUE;
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
+ svSetValue (ifcfg, "IPV6_AUTOCONF", "yes", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
+ svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
+ svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", "yes", FALSE);
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
+ svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
+ svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
+ svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
+ svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
+ svSetValue (ifcfg, "DHCPV6C", NULL, FALSE);
+ /* TODO */
+ }
+
+ if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ /* Write out IP addresses */
+ num = nm_setting_ip6_config_get_num_addresses (s_ip6);
+
+ ip_str1 = g_string_new (NULL);
+ ip_str2 = g_string_new (NULL);
+ for (i = 0; i < num; i++) {
+ if (i == 0)
+ ip_ptr = ip_str1;
+ else
+ ip_ptr = ip_str2;
+
+ addr = nm_setting_ip6_config_get_address (s_ip6, i);
+ ip = nm_ip6_address_get_address (addr);
+ prefix = g_strdup_printf ("%u", nm_ip6_address_get_prefix (addr));
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+ if (i > 1)
+ g_string_append_c (ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */
+ g_string_append (ip_ptr, buf);
+ g_string_append_c (ip_ptr, '/');
+ g_string_append (ip_ptr, prefix);
+ g_free (prefix);
+
+ /* We only support gateway for the first IP address for now */
+ if (i == 0) {
+ ip = nm_ip6_address_get_gateway (addr);
+ inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+ svSetValue (ifcfg, "IPV6_DEFAULTGW", buf, FALSE);
+ }
+ }
+
+ svSetValue (ifcfg, "IPV6ADDR", ip_str1->str, FALSE);
+ svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str, FALSE);
+ g_string_free (ip_str1, TRUE);
+ g_string_free (ip_str2, TRUE);
+ } else {
+ svSetValue (ifcfg, "IPV6ADDR", NULL, FALSE);
+ svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", NULL, FALSE);
+ svSetValue (ifcfg, "IPV6_DEFAULTGW", NULL, FALSE);
+ }
+
+ /* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */
+ s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+ num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */
+ num = nm_setting_ip6_config_get_num_dns (s_ip6);
+ for (i = 0; i < 254; i++) {
+ addr_key = g_strdup_printf ("DNS%d", i + num4 + 1);
+
+ if (i >= num)
+ svSetValue (ifcfg, addr_key, NULL, FALSE);
+ else {
+ ip = nm_setting_ip6_config_get_dns (s_ip6, i);
+
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
+ svSetValue (ifcfg, addr_key, buf, FALSE);
+ }
+ g_free (addr_key);
+ }
+
+ /* Write out DNS domains - 'DOMAIN' key is shared for both IPv4 and IPv6 domains */
+ num = nm_setting_ip6_config_get_num_dns_searches (s_ip6);
+ if (num > 0) {
+ char *ip4_domains;
+ ip4_domains = svGetValue (ifcfg, "DOMAIN", FALSE);
+ searches = g_string_new (ip4_domains);
+ for (i = 0; i < num; i++) {
+ if (searches->len > 0)
+ g_string_append_c (searches, ' ');
+ g_string_append (searches, nm_setting_ip6_config_get_dns_search (s_ip6, i));
+ }
+ svSetValue (ifcfg, "DOMAIN", searches->str, FALSE);
+ g_string_free (searches, TRUE);
+ g_free (ip4_domains);
+ }
+
+ /* handle IPV6_DEFROUTE */
+ /* IPV6_DEFROUTE has the opposite meaning from 'never-default' */
+ if (nm_setting_ip6_config_get_never_default(s_ip6))
+ svSetValue (ifcfg, "IPV6_DEFROUTE", "no", FALSE);
+ else
+ svSetValue (ifcfg, "IPV6_DEFROUTE", "yes", FALSE);
+
+ svSetValue (ifcfg, "IPV6_PEERDNS", NULL, FALSE);
+ svSetValue (ifcfg, "IPV6_PEERROUTES", NULL, FALSE);
+ if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ svSetValue (ifcfg, "IPV6_PEERDNS",
+ nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? "no" : "yes",
+ FALSE);
+
+ svSetValue (ifcfg, "IPV6_PEERROUTES",
+ nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? "no" : "yes",
+ FALSE);
+ }
+
+ svSetValue (ifcfg, "IPV6_FAILURE_FATAL",
+ nm_setting_ip6_config_get_may_fail (s_ip6) ? "no" : "yes",
+ FALSE);
+
+ /* Static routes go to route6-<dev> file */
+ route6_path = utils_get_route6_path (ifcfg->fileName);
+ if (!route6_path) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Could not get route6 file path for '%s'", ifcfg->fileName);
+ goto error;
+ }
+ write_route6_file (route6_path, s_ip6, error);
+ g_free (route6_path);
+ if (error && *error)
+ goto error;
+
+ return TRUE;
+
+error:
+ return FALSE;
+}
+
+static char *
+escape_id (const char *id)
+{
+ char *escaped = g_strdup (id);
+ char *p = escaped;
+
+ /* Escape random stuff */
+ while (*p) {
+ if (*p == ' ')
+ *p = '_';
+ else if (*p == '/')
+ *p = '-';
+ else if (*p == '\\')
+ *p = '-';
+ p++;
+ }
+
+ return escaped;
+}
+
+static gboolean
+write_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ const char *filename,
+ const char *keyfile,
+ char **out_filename,
+ GError **error)
+{
+ NMSettingConnection *s_con;
+ NMSettingIP6Config *s_ip6;
+ gboolean success = FALSE;
+ shvarFile *ifcfg = NULL;
+ char *ifcfg_name = NULL;
+ const char *type;
+ gboolean no_8021x = FALSE;
+ gboolean wired = FALSE;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ if (!s_con) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing '%s' setting", NM_SETTING_CONNECTION_SETTING_NAME);
+ return FALSE;
+ }
+
+ if (filename) {
+ /* For existing connections, 'filename' should be full path to ifcfg file */
+ ifcfg = svNewFile (filename);
+ ifcfg_name = g_strdup (filename);
+ } else {
+ char *escaped;
+
+ escaped = escape_id (nm_setting_connection_get_id (s_con));
+ ifcfg_name = g_strdup_printf ("%s/ifcfg-%s", ifcfg_dir, escaped);
+
+ /* If a file with this path already exists then we need another name.
+ * Multiple connections can have the same ID (ie if two connections with
+ * the same ID are visible to different users) but of course can't have
+ * the same path.
+ */
+ if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS)) {
+ guint32 idx = 0;
+
+ g_free (ifcfg_name);
+ while (idx++ < 500) {
+ ifcfg_name = g_strdup_printf ("%s/ifcfg-%s %u", ifcfg_dir, escaped, idx);
+ if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS) == FALSE)
+ break;
+ g_free (ifcfg_name);
+ ifcfg_name = NULL;
+ }
+ }
+ g_free (escaped);
+
+ if (ifcfg_name == NULL) {
+ g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to find usable ifcfg file name");
+ return FALSE;
+ }
+
+ ifcfg = svCreateFile (ifcfg_name);
+ }
+
+ if (!ifcfg) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Failed to open/create ifcfg file '%s'", ifcfg_name);
+ goto out;
+ }
+
+ type = nm_setting_connection_get_connection_type (s_con);
+ if (!type) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Missing connection type!");
+ goto out;
+ }
+
+ if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
+ // FIXME: can't write PPPoE at this time
+ if (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Can't write connection type '%s'",
+ NM_SETTING_PPPOE_SETTING_NAME);
+ goto out;
+ }
+
+ if (!write_wired_setting (connection, ifcfg, error))
+ goto out;
+ wired = TRUE;
+ } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) {
+ if (!write_wireless_setting (connection, ifcfg, &no_8021x, error))
+ goto out;
+ } else {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Can't write connection type '%s'", type);
+ goto out;
+ }
+
+ if (!no_8021x) {
+ if (!write_8021x_setting (connection, ifcfg, wired, error))
+ goto out;
+ }
+
+ if (!write_ip4_setting (connection, ifcfg, error))
+ goto out;
+
+ s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+ if (s_ip6) {
+ if (!write_ip6_setting (connection, ifcfg, error))
+ goto out;
+ }
+
+ write_connection_setting (s_con, ifcfg);
+
+ if (svWriteFile (ifcfg, 0644)) {
+ g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
+ "Can't write connection '%s'", ifcfg->fileName);
+ goto out;
+ }
+
+ /* Only return the filename if this was a newly written ifcfg */
+ if (out_filename && !filename)
+ *out_filename = g_strdup (ifcfg_name);
+
+ success = TRUE;
+
+out:
+ if (ifcfg)
+ svCloseFile (ifcfg);
+ g_free (ifcfg_name);
+ return success;
+}
+
+gboolean
+writer_new_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ char **out_filename,
+ GError **error)
+{
+ return write_connection (connection, ifcfg_dir, NULL, NULL, out_filename, error);
+}
+
+gboolean
+writer_update_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ const char *filename,
+ const char *keyfile,
+ GError **error)
+{
+ return write_connection (connection, ifcfg_dir, filename, keyfile, NULL, error);
+}
+
diff --git a/src/settings/plugins/ifcfg-rh/writer.h b/src/settings/plugins/ifcfg-rh/writer.h
new file mode 100644
index 000000000..edeac0ccc
--- /dev/null
+++ b/src/settings/plugins/ifcfg-rh/writer.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifndef _WRITER_H_
+#define _WRITER_H_
+
+#include <sys/types.h>
+#include <glib.h>
+#include <nm-connection.h>
+
+gboolean writer_new_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ char **out_filename,
+ GError **error);
+
+gboolean writer_update_connection (NMConnection *connection,
+ const char *ifcfg_dir,
+ const char *filename,
+ const char *keyfile,
+ GError **error);
+
+#endif /* _WRITER_H_ */
diff --git a/src/settings/plugins/ifcfg-suse/Makefile.am b/src/settings/plugins/ifcfg-suse/Makefile.am
new file mode 100644
index 000000000..3db8ed31d
--- /dev/null
+++ b/src/settings/plugins/ifcfg-suse/Makefile.am
@@ -0,0 +1,26 @@
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la
+
+libnm_settings_plugin_ifcfg_suse_la_SOURCES = \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -I${top_srcdir}/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifcfg_suse_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GIO_LIBS)
+
diff --git a/src/settings/plugins/ifcfg-suse/Makefile.in b/src/settings/plugins/ifcfg-suse/Makefile.in
new file mode 100644
index 000000000..2a8a16397
--- /dev/null
+++ b/src/settings/plugins/ifcfg-suse/Makefile.in
@@ -0,0 +1,672 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/ifcfg-suse
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(pkglib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libnm_settings_plugin_ifcfg_suse_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS = \
+ libnm_settings_plugin_ifcfg_suse_la-plugin.lo
+libnm_settings_plugin_ifcfg_suse_la_OBJECTS = \
+ $(am_libnm_settings_plugin_ifcfg_suse_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnm_settings_plugin_ifcfg_suse_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libnm_settings_plugin_ifcfg_suse_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libnm_settings_plugin_ifcfg_suse_la_SOURCES)
+DIST_SOURCES = $(libnm_settings_plugin_ifcfg_suse_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-suse.la
+libnm_settings_plugin_ifcfg_suse_la_SOURCES = \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -I${top_srcdir}/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifcfg_suse_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifcfg_suse_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GIO_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifcfg-suse/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+ }
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libnm-settings-plugin-ifcfg-suse.la: $(libnm_settings_plugin_ifcfg_suse_la_OBJECTS) $(libnm_settings_plugin_ifcfg_suse_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnm_settings_plugin_ifcfg_suse_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifcfg_suse_la_OBJECTS) $(libnm_settings_plugin_ifcfg_suse_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libnm_settings_plugin_ifcfg_suse_la-plugin.lo: plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifcfg_suse_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Tpo -c -o libnm_settings_plugin_ifcfg_suse_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifcfg_suse_la-plugin.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifcfg_suse_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifcfg_suse_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pkglibLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pkglibLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-pkglibLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifcfg-suse/plugin.c b/src/settings/plugins/ifcfg-suse/plugin.c
new file mode 100644
index 000000000..78db56e50
--- /dev/null
+++ b/src/settings/plugins/ifcfg-suse/plugin.c
@@ -0,0 +1,322 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service
+ *
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2009 Red Hat, Inc.
+ * (C) Copyright 2007 - 2008 Novell, Inc.
+ */
+
+#include <config.h>
+#include <string.h>
+
+#include <gmodule.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include "plugin.h"
+#include "nm-system-config-interface.h"
+
+#define IFCFG_PLUGIN_NAME "ifcfg-suse"
+#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc. To report bugs please use the NetworkManager mailing list."
+#define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
+#define CONF_DHCP IFCFG_DIR "/dhcp"
+#define HOSTNAME_FILE "/etc/HOSTNAME"
+
+static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+ system_config_interface_init))
+
+#define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate))
+
+
+#define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
+
+typedef struct {
+ GFileMonitor *hostname_monitor;
+ GFileMonitor *dhcp_monitor;
+ char *hostname;
+} SCPluginIfcfgPrivate;
+
+GQuark
+ifcfg_plugin_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (G_UNLIKELY (error_quark == 0))
+ error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark");
+
+ return error_quark;
+}
+
+typedef void (*FileChangedFn) (gpointer user_data);
+
+typedef struct {
+ FileChangedFn callback;
+ gpointer user_data;
+} FileMonitorInfo;
+
+static void
+file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ FileMonitorInfo *info;
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ case G_FILE_MONITOR_EVENT_DELETED:
+ info = (FileMonitorInfo *) user_data;
+ info->callback (info->user_data);
+ break;
+ default:
+ break;
+ }
+}
+
+static GFileMonitor *
+monitor_file_changes (const char *filename,
+ FileChangedFn callback,
+ gpointer user_data)
+{
+ GFile *file;
+ GFileMonitor *monitor;
+ FileMonitorInfo *info;
+
+ file = g_file_new_for_path (filename);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ info = g_new0 (FileMonitorInfo, 1);
+ info->callback = callback;
+ info->user_data = user_data;
+ g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, info);
+ g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), info);
+ }
+
+ return monitor;
+}
+
+static gboolean
+hostname_is_dynamic (void)
+{
+ GIOChannel *channel;
+ const char *pattern = "DHCLIENT_SET_HOSTNAME=";
+ char *str = NULL;
+ int pattern_len;
+ gboolean dynamic = FALSE;
+
+ channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
+ if (!channel)
+ return dynamic;
+
+ pattern_len = strlen (pattern);
+
+ while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
+ if (!strncmp (str, pattern, pattern_len)) {
+ if (!strncmp (str + pattern_len, "\"yes\"", 5))
+ dynamic = TRUE;
+ break;
+ }
+ g_free (str);
+ }
+
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+
+ return dynamic;
+}
+
+static char *
+hostname_read ()
+{
+ GIOChannel *channel;
+ char *hostname = NULL;
+
+ channel = g_io_channel_new_file (HOSTNAME_FILE, "r", NULL);
+ if (channel) {
+ g_io_channel_read_line (channel, &hostname, NULL, NULL, NULL);
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+
+ if (hostname)
+ hostname = g_strchomp (hostname);
+ }
+
+ return hostname;
+}
+
+static void
+hostname_changed (gpointer data)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (data);
+
+ g_free (priv->hostname);
+ if (hostname_is_dynamic ())
+ priv->hostname = NULL;
+ else
+ priv->hostname = hostname_read ();
+
+ g_object_notify (G_OBJECT (data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+plugin_set_hostname (SCPluginIfcfg *plugin, const char *hostname)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+ GIOChannel *channel;
+
+ channel = g_io_channel_new_file (HOSTNAME_FILE, "w", NULL);
+ if (channel) {
+ g_io_channel_write_chars (channel, hostname, -1, NULL, NULL);
+ g_io_channel_write_chars (channel, "\n", -1, NULL, NULL);
+ g_io_channel_shutdown (channel, TRUE, NULL);
+ g_io_channel_unref (channel);
+ }
+
+ g_free (priv->hostname);
+ priv->hostname = g_strdup (hostname);
+}
+
+static void
+init (NMSystemConfigInterface *config)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
+
+ priv->hostname_monitor = monitor_file_changes (HOSTNAME_FILE, hostname_changed, config);
+ priv->dhcp_monitor = monitor_file_changes (CONF_DHCP, hostname_changed, config);
+
+ if (!hostname_is_dynamic ())
+ priv->hostname = hostname_read ();
+}
+
+static void
+sc_plugin_ifcfg_init (SCPluginIfcfg *self)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+ SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
+
+ if (priv->dhcp_monitor)
+ g_object_unref (priv->dhcp_monitor);
+
+ if (priv->hostname_monitor)
+ g_object_unref (priv->hostname_monitor);
+
+ g_free (priv->hostname);
+
+ G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, IFCFG_PLUGIN_NAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, IFCFG_PLUGIN_INFO);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+ g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ g_value_set_string (value, SC_PLUGIN_IFCFG_GET_PRIVATE (object)->hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ const char *hostname;
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ hostname = g_value_get_string (value);
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ plugin_set_hostname (SC_PLUGIN_IFCFG (object), hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
+
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+ object_class->dispose = dispose;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+ NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+ /* interface implementation */
+ system_config_interface_class->init = init;
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+ static SCPluginIfcfg *singleton = NULL;
+
+ if (!singleton)
+ singleton = SC_PLUGIN_IFCFG (g_object_new (SC_TYPE_PLUGIN_IFCFG, NULL));
+ else
+ g_object_ref (singleton);
+
+ return G_OBJECT (singleton);
+}
diff --git a/src/settings/plugins/ifcfg-suse/plugin.h b/src/settings/plugins/ifcfg-suse/plugin.h
new file mode 100644
index 000000000..97840595c
--- /dev/null
+++ b/src/settings/plugins/ifcfg-suse/plugin.h
@@ -0,0 +1,52 @@
+/* NetworkManager system settings service
+ *
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 Red Hat, Inc.
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define PLUGIN_NAME "ifcfg-suse"
+
+#define SC_TYPE_PLUGIN_IFCFG (sc_plugin_ifcfg_get_type ())
+#define SC_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfg))
+#define SC_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass))
+#define SC_IS_PLUGIN_IFCFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG))
+#define SC_IS_PLUGIN_IFCFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFCFG))
+#define SC_PLUGIN_IFCFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgClass))
+
+typedef struct _SCPluginIfcfg SCPluginIfcfg;
+typedef struct _SCPluginIfcfgClass SCPluginIfcfgClass;
+
+struct _SCPluginIfcfg {
+ GObject parent;
+};
+
+struct _SCPluginIfcfgClass {
+ GObjectClass parent;
+};
+
+GType sc_plugin_ifcfg_get_type (void);
+
+GQuark ifcfg_plugin_error_quark (void);
+
+#endif /* _PLUGIN_H_ */
+
diff --git a/src/settings/plugins/ifnet/Makefile.am b/src/settings/plugins/ifnet/Makefile.am
new file mode 100644
index 000000000..9bf8a79a1
--- /dev/null
+++ b/src/settings/plugins/ifnet/Makefile.am
@@ -0,0 +1,57 @@
+SUBDIRS = . tests
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la
+
+noinst_LTLIBRARIES = lib-ifnet-io.la
+
+libnm_settings_plugin_ifnet_la_SOURCES = \
+ nm-ifnet-connection.c \
+ nm-ifnet-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifnet_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version
+
+libnm_settings_plugin_ifnet_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ lib-ifnet-io.la\
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GUDEV_LIBS) \
+ $(GIO_LIBS)
+
+lib_ifnet_io_la_SOURCES = \
+ net_parser.c\
+ net_parser.h\
+ connection_parser.c \
+ connection_parser.h \
+ net_utils.h\
+ net_utils.c\
+ wpa_parser.h\
+ wpa_parser.c
+
+lib_ifnet_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSBINDIR=\"$(sbindir)\"
+
+lib_ifnet_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS)\
+ $(GIO_LIBS)
diff --git a/src/settings/plugins/ifnet/Makefile.in b/src/settings/plugins/ifnet/Makefile.in
new file mode 100644
index 000000000..793258f75
--- /dev/null
+++ b/src/settings/plugins/ifnet/Makefile.in
@@ -0,0 +1,922 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/ifnet
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+lib_ifnet_io_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_lib_ifnet_io_la_OBJECTS = lib_ifnet_io_la-net_parser.lo \
+ lib_ifnet_io_la-connection_parser.lo \
+ lib_ifnet_io_la-net_utils.lo lib_ifnet_io_la-wpa_parser.lo
+lib_ifnet_io_la_OBJECTS = $(am_lib_ifnet_io_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnm_settings_plugin_ifnet_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la lib-ifnet-io.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libnm_settings_plugin_ifnet_la_OBJECTS = \
+ libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo \
+ libnm_settings_plugin_ifnet_la-plugin.lo
+libnm_settings_plugin_ifnet_la_OBJECTS = \
+ $(am_libnm_settings_plugin_ifnet_la_OBJECTS)
+libnm_settings_plugin_ifnet_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libnm_settings_plugin_ifnet_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(lib_ifnet_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifnet_la_SOURCES)
+DIST_SOURCES = $(lib_ifnet_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifnet_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = . tests
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifnet.la
+noinst_LTLIBRARIES = lib-ifnet-io.la
+libnm_settings_plugin_ifnet_la_SOURCES = \
+ nm-ifnet-connection.c \
+ nm-ifnet-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifnet_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifnet_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ lib-ifnet-io.la\
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GUDEV_LIBS) \
+ $(GIO_LIBS)
+
+lib_ifnet_io_la_SOURCES = \
+ net_parser.c\
+ net_parser.h\
+ connection_parser.c \
+ connection_parser.h \
+ net_utils.h\
+ net_utils.c\
+ wpa_parser.h\
+ wpa_parser.c
+
+lib_ifnet_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DSBINDIR=\"$(sbindir)\"
+
+lib_ifnet_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS)\
+ $(GIO_LIBS)
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifnet/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+ }
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+lib-ifnet-io.la: $(lib_ifnet_io_la_OBJECTS) $(lib_ifnet_io_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(lib_ifnet_io_la_OBJECTS) $(lib_ifnet_io_la_LIBADD) $(LIBS)
+libnm-settings-plugin-ifnet.la: $(libnm_settings_plugin_ifnet_la_OBJECTS) $(libnm_settings_plugin_ifnet_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnm_settings_plugin_ifnet_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifnet_la_OBJECTS) $(libnm_settings_plugin_ifnet_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-connection_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-net_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-net_utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib_ifnet_io_la-wpa_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+lib_ifnet_io_la-net_parser.lo: net_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-net_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-net_parser.Tpo -c -o lib_ifnet_io_la-net_parser.lo `test -f 'net_parser.c' || echo '$(srcdir)/'`net_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-net_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-net_parser.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='net_parser.c' object='lib_ifnet_io_la-net_parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-net_parser.lo `test -f 'net_parser.c' || echo '$(srcdir)/'`net_parser.c
+
+lib_ifnet_io_la-connection_parser.lo: connection_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-connection_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-connection_parser.Tpo -c -o lib_ifnet_io_la-connection_parser.lo `test -f 'connection_parser.c' || echo '$(srcdir)/'`connection_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-connection_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-connection_parser.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='connection_parser.c' object='lib_ifnet_io_la-connection_parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-connection_parser.lo `test -f 'connection_parser.c' || echo '$(srcdir)/'`connection_parser.c
+
+lib_ifnet_io_la-net_utils.lo: net_utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-net_utils.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-net_utils.Tpo -c -o lib_ifnet_io_la-net_utils.lo `test -f 'net_utils.c' || echo '$(srcdir)/'`net_utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-net_utils.Tpo $(DEPDIR)/lib_ifnet_io_la-net_utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='net_utils.c' object='lib_ifnet_io_la-net_utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-net_utils.lo `test -f 'net_utils.c' || echo '$(srcdir)/'`net_utils.c
+
+lib_ifnet_io_la-wpa_parser.lo: wpa_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib_ifnet_io_la-wpa_parser.lo -MD -MP -MF $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Tpo -c -o lib_ifnet_io_la-wpa_parser.lo `test -f 'wpa_parser.c' || echo '$(srcdir)/'`wpa_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Tpo $(DEPDIR)/lib_ifnet_io_la-wpa_parser.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wpa_parser.c' object='lib_ifnet_io_la-wpa_parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib_ifnet_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib_ifnet_io_la-wpa_parser.lo `test -f 'wpa_parser.c' || echo '$(srcdir)/'`wpa_parser.c
+
+libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo: nm-ifnet-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Tpo -c -o libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo `test -f 'nm-ifnet-connection.c' || echo '$(srcdir)/'`nm-ifnet-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifnet_la-nm-ifnet-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifnet-connection.c' object='libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifnet_la-nm-ifnet-connection.lo `test -f 'nm-ifnet-connection.c' || echo '$(srcdir)/'`nm-ifnet-connection.c
+
+libnm_settings_plugin_ifnet_la-plugin.lo: plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifnet_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Tpo -c -o libnm_settings_plugin_ifnet_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifnet_la-plugin.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifnet_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifnet_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifnet_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pkglibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pkglibLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-pkglibLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c
new file mode 100644
index 000000000..982f94f9c
--- /dev/null
+++ b/src/settings/plugins/ifnet/connection_parser.c
@@ -0,0 +1,3069 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <netinet/ether.h>
+#include <errno.h>
+#include <ctype.h>
+#include <glib/gi18n.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-8021x.h>
+#include <nm-system-config-interface.h>
+#include <nm-utils.h>
+
+#include "net_utils.h"
+#include "wpa_parser.h"
+#include "connection_parser.h"
+#include "nm-ifnet-connection.h"
+
+static const char *
+get_prefix (void)
+{
+ return _("System");
+}
+
+static void
+update_connection_id (NMConnection *connection, const char *conn_name)
+{
+ gchar *idstr = NULL;
+ gchar *uuid_base = NULL;
+ gchar *uuid = NULL;
+ int name_len;
+ NMSettingConnection *setting;
+
+ name_len = strlen (conn_name);
+ if ((name_len > 2) && (g_str_has_prefix (conn_name, "0x"))) {
+ gchar * conn_name_printable = utils_hexstr2bin (conn_name + 2, name_len - 2);
+ idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name_printable);
+ g_free (conn_name_printable);
+ } else
+ idstr = g_strdup_printf ("%s (%s)", get_prefix (), conn_name);
+ uuid_base = idstr;
+ uuid = nm_utils_uuid_generate_from_string (uuid_base);
+ setting =
+ (NMSettingConnection *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_CONNECTION);
+ g_object_set (setting, NM_SETTING_CONNECTION_ID, idstr,
+ NM_SETTING_CONNECTION_UUID, uuid, NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "update_connection_setting_from_config_block: name:%s, id:%s, uuid: %s",
+ conn_name, idstr, uuid);
+
+ g_free (uuid);
+ g_free (idstr);
+}
+
+static gboolean eap_simple_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+
+static gboolean eap_tls_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+
+static gboolean eap_peap_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+
+static gboolean eap_ttls_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+
+typedef struct {
+ const char *method;
+ gboolean (*reader) (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error);
+ gboolean wifi_phase2_only;
+} EAPReader;
+
+static EAPReader eap_readers[] = {
+ {"md5", eap_simple_reader, TRUE},
+ {"pap", eap_simple_reader, TRUE},
+ {"chap", eap_simple_reader, TRUE},
+ {"mschap", eap_simple_reader, TRUE},
+ {"mschapv2", eap_simple_reader, TRUE},
+ {"leap", eap_simple_reader, TRUE},
+ {"tls", eap_tls_reader, FALSE},
+ {"peap", eap_peap_reader, FALSE},
+ {"ttls", eap_ttls_reader, FALSE},
+ {NULL, NULL}
+};
+
+/* reading identity and password */
+static gboolean
+eap_simple_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ const char *value;
+
+ /* identity */
+ value = wpa_get_value (ssid, "identity");
+ if (!value) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
+
+ /* password */
+ value = wpa_get_value (ssid, "password");
+ if (!value) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_PASSWORD for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+
+ g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL);
+
+ return TRUE;
+}
+
+static gboolean
+eap_tls_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ const char *value;
+ const char *ca_cert = NULL;
+ const char *client_cert = NULL;
+ const char *privkey = NULL;
+ const char *privkey_password = NULL;
+ gboolean success = FALSE;
+ NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
+
+ /* identity */
+ value = wpa_get_value (ssid, "identity");
+ if (!value) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_IDENTITY for EAP method '%s'.",
+ eap_method);
+ return FALSE;
+ }
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL);
+
+ /* ca cert */
+ ca_cert = wpa_get_value (ssid, phase2 ? "ca_cert2" : "ca_cert");
+ if (ca_cert) {
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
+ ca_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL, error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ ca_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL, error))
+ goto done;
+ }
+ } else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: missing %s for EAP"
+ " method '%s'; this is insecure!",
+ phase2 ? "IEEE_8021X_INNER_CA_CERT" :
+ "IEEE_8021X_CA_CERT", eap_method);
+ }
+
+ /* Private key password */
+ privkey_password = wpa_get_value (ssid,
+ phase2 ? "private_key_passwd2" :
+ "private_key_passwd");
+
+ if (!privkey_password) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing %s for EAP method '%s'.",
+ phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" :
+ "IEEE_8021X_PRIVATE_KEY_PASSWORD", eap_method);
+ goto done;
+ }
+
+ /* The private key itself */
+ privkey = wpa_get_value (ssid, phase2 ? "private_key2" : "private_key");
+ if (!privkey) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing %s for EAP method '%s'.",
+ phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" :
+ "IEEE_8021X_PRIVATE_KEY", eap_method);
+ goto done;
+ }
+
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_private_key (s_8021x,
+ privkey,
+ privkey_password,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ &privkey_format,
+ error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_private_key (s_8021x,
+ privkey,
+ privkey_password,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ &privkey_format, error))
+ goto done;
+ }
+
+ /* Only set the client certificate if the private key is not PKCS#12 format,
+ * as NM (due to supplicant restrictions) requires. If the key was PKCS#12,
+ * then nm_setting_802_1x_set_private_key() already set the client certificate
+ * to the same value as the private key.
+ */
+ if (privkey_format == NM_SETTING_802_1X_CK_FORMAT_RAW_KEY
+ || privkey_format == NM_SETTING_802_1X_CK_FORMAT_X509) {
+ client_cert = wpa_get_value (ssid,
+ phase2 ? "client_cert2" :
+ "client_cert");
+ if (!client_cert) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing %s for EAP method '%s'.",
+ phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" :
+ "IEEE_8021X_CLIENT_CERT", eap_method);
+ goto done;
+ }
+
+ if (phase2) {
+ if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x,
+ client_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL,
+ error))
+ goto done;
+ } else {
+ if (!nm_setting_802_1x_set_client_cert (s_8021x,
+ client_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL, error))
+ goto done;
+ }
+ }
+
+ success = TRUE;
+
+done:
+ return success;
+}
+
+static gboolean
+eap_peap_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ const char *ca_cert = NULL;
+ const char *inner_auth = NULL;
+ const char *peapver = NULL;
+ char **list = NULL, **iter, *lower;
+ gboolean success = FALSE;
+
+ ca_cert = wpa_get_value (ssid, "ca_cert");
+ if (ca_cert) {
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ ca_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL, error))
+ goto done;
+ } else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: missing "
+ "IEEE_8021X_CA_CERT for EAP method '%s'; this is"
+ " insecure!", eap_method);
+ }
+
+ peapver = wpa_get_value (ssid, "phase1");
+ /* peap version, default is automatic */
+ if (peapver && strstr (peapver, "peapver")) {
+ if (strstr (peapver, "peapver=0"))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER,
+ "0", NULL);
+ else if (strstr (peapver, "peapver=1"))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPVER,
+ "1", NULL);
+ else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown IEEE_8021X_PEAP_VERSION value '%s'",
+ peapver);
+ goto done;
+ }
+ }
+
+ /* peaplabel */
+ if (peapver && strstr (peapver, "peaplabel=1"))
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE1_PEAPLABEL, "1",
+ NULL);
+
+ inner_auth = wpa_get_value (ssid, "phase2");
+ if (!inner_auth) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+ goto done;
+ }
+ /* Handle options for the inner auth method */
+ list = g_strsplit (inner_auth, " ", 0);
+ for (iter = list; iter && *iter; iter++) {
+ gchar *pos = NULL;
+
+ if (!strlen (*iter))
+ continue;
+
+ if (!(pos = strstr (*iter, "MSCHAPV2"))
+ || !(pos = strstr (*iter, "MD5"))
+ || !(pos = strstr (*iter, "GTC"))) {
+ if (!eap_simple_reader
+ (pos, ssid, s_8021x, TRUE, error))
+ goto done;
+ } else if (!(pos = strstr (*iter, "TLS"))) {
+ if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error))
+ goto done;
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
+ *iter);
+ goto done;
+ }
+
+ pos = strchr (*iter, '=');
+ pos++;
+ lower = g_ascii_strdown (pos, -1);
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, lower,
+ NULL);
+ g_free (lower);
+ break;
+ }
+
+ if (!nm_setting_802_1x_get_phase2_auth (s_8021x)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "No valid IEEE_8021X_INNER_AUTH_METHODS found.");
+ goto done;
+ }
+
+ success = TRUE;
+
+done:
+ if (list)
+ g_strfreev (list);
+ return success;
+}
+
+static gboolean
+eap_ttls_reader (const char *eap_method,
+ const char *ssid,
+ NMSetting8021x *s_8021x,
+ gboolean phase2,
+ GError **error)
+{
+ gboolean success = FALSE;
+ const char *anon_ident = NULL;
+ const char *ca_cert = NULL;
+ const char *tmp;
+ char **list = NULL, **iter, *inner_auth = NULL;
+
+ /* ca cert */
+ ca_cert = wpa_get_value (ssid, "ca_cert");
+ if (ca_cert) {
+ if (!nm_setting_802_1x_set_ca_cert (s_8021x,
+ ca_cert,
+ NM_SETTING_802_1X_CK_SCHEME_PATH,
+ NULL, error))
+ goto done;
+ } else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: missing "
+ "IEEE_8021X_CA_CERT for EAP method '%s'; this is"
+ " insecure!", eap_method);
+ }
+
+ /* anonymous indentity for tls */
+ anon_ident = wpa_get_value (ssid, "anonymous_identity");
+ if (anon_ident && strlen (anon_ident))
+ g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY,
+ anon_ident, NULL);
+
+ tmp = wpa_get_value (ssid, "phase2");
+ if (!tmp) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_INNER_AUTH_METHODS.");
+ goto done;
+ }
+
+ /* Handle options for the inner auth method */
+ inner_auth = g_ascii_strdown (tmp, -1);
+ list = g_strsplit (inner_auth, " ", 0);
+ for (iter = list; iter && *iter; iter++) {
+ gchar *pos = NULL;
+
+ if (!strlen (*iter))
+ continue;
+ if ((pos = strstr (*iter, "mschapv2")) != NULL
+ || (pos = strstr (*iter, "mschap")) != NULL
+ || (pos = strstr (*iter, "pap")) != NULL
+ || (pos = strstr (*iter, "chap")) != NULL) {
+ if (!eap_simple_reader
+ (pos, ssid, s_8021x, TRUE, error))
+ goto done;
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH,
+ pos, NULL);
+ } else if ((pos = strstr (*iter, "tls")) != NULL) {
+ if (!eap_tls_reader (pos, ssid, s_8021x, TRUE, error))
+ goto done;
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP,
+ "tls", NULL);
+ } else if ((pos = strstr (*iter, "mschapv2")) != NULL
+ || (pos = strstr (*iter, "md5")) != NULL) {
+ if (!eap_simple_reader
+ (pos, ssid, s_8021x, TRUE, error)) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "SIMPLE ERROR");
+ goto done;
+ }
+ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP,
+ pos, NULL);
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown IEEE_8021X_INNER_AUTH_METHOD '%s'.",
+ *iter);
+ goto done;
+ }
+ break;
+ }
+
+ success = TRUE;
+done:
+ if (list)
+ g_strfreev (list);
+ g_free (inner_auth);
+ return success;
+}
+
+/* type is already decided by net_parser, this function is just used to
+ * doing tansformation*/
+static const gchar *
+guess_connection_type (const char *conn_name)
+{
+ const gchar *type = ifnet_get_data (conn_name, "type");
+ const gchar *ret_type = NULL;
+
+ if (!g_strcmp0 (type, "ppp"))
+ ret_type = NM_SETTING_PPPOE_SETTING_NAME;
+
+ if (!g_strcmp0 (type, "wireless"))
+ ret_type = NM_SETTING_WIRELESS_SETTING_NAME;
+
+ if (!ret_type)
+ ret_type = NM_SETTING_WIRED_SETTING_NAME;
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "guessed connection type (%s) = %s", conn_name, ret_type);
+ return ret_type;
+}
+
+/* Reading mac address for setting connection option.
+ * Unmanaged device mac address is required by NetworkManager*/
+static gboolean
+read_mac_address (const char *conn_name, GByteArray **array, GError **error)
+{
+ const char *value = ifnet_get_data (conn_name, "mac");
+ struct ether_addr *mac;
+
+ if (!value || !strlen (value))
+ return TRUE;
+
+ mac = ether_aton (value);
+ if (!mac) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "The MAC address '%s' was invalid.", value);
+ return FALSE;
+ }
+
+ *array = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN);
+ return TRUE;
+}
+
+static void
+make_wired_connection_setting (NMConnection *connection,
+ const char *conn_name,
+ GError **error)
+{
+ GByteArray *mac = NULL;
+ NMSettingWired *s_wired = NULL;
+ const char *value = NULL;
+
+ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
+
+ /* mtu_xxx */
+ value = ifnet_get_data (conn_name, "mtu");
+ if (value) {
+ long int mtu;
+
+ errno = 0;
+ mtu = strtol (value, NULL, 10);
+ if (errno || mtu < 0 || mtu > 65535) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: invalid MTU '%s' for %s",
+ value, conn_name);
+ } else
+ g_object_set (s_wired, NM_SETTING_WIRED_MTU,
+ (guint32) mtu, NULL);
+ }
+
+ if (read_mac_address (conn_name, &mac, error)) {
+ if (mac) {
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS,
+ mac, NULL);
+ g_byte_array_free (mac, TRUE);
+ }
+ } else {
+ g_object_unref (s_wired);
+ s_wired = NULL;
+ }
+ if (s_wired)
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+}
+
+/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
+ * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/
+static void
+make_ip4_setting (NMConnection *connection,
+ const char *conn_name,
+ GError **error)
+{
+
+ NMSettingIP4Config *ip4_setting =
+ NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ const char *value, *method;
+ gboolean is_static_block = is_static_ip4 (conn_name);
+ ip_block *iblock = NULL;
+
+ /* set dhcp options (dhcp_xxx) */
+ value = ifnet_get_data (conn_name, "dhcp");
+ g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, value
+ && strstr (value, "nodns") ? TRUE : FALSE,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, value
+ && strstr (value, "nogateway") ? TRUE : FALSE, NULL);
+
+ if (!is_static_block) {
+ method = ifnet_get_data (conn_name, "config");
+ if (!method){
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown config for %s", conn_name);
+ g_object_unref (ip4_setting);
+ return;
+ }
+ if (!strcmp (method, "dhcp"))
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD,
+ NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
+ else if (!strcmp (method, "autoip")){
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD,
+ NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (ip4_setting));
+ return;
+ } else if (!strcmp (method, "shared")){
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD,
+ NM_SETTING_IP4_CONFIG_METHOD_SHARED,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (ip4_setting));
+ return;
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown config for %s", conn_name);
+ g_object_unref (ip4_setting);
+ return;
+ }
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Using %s method for %s",
+ method, conn_name);
+ }else {
+ iblock = convert_ip4_config_block (conn_name);
+ if (!iblock) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Ifnet plugin: can't aquire ip configuration for %s",
+ conn_name);
+ g_object_unref (ip4_setting);
+ return;
+ }
+ /************** add all ip settings to the connection**********/
+ while (iblock) {
+ ip_block *current_iblock;
+ NMIP4Address *ip4_addr = nm_ip4_address_new ();
+
+ nm_ip4_address_set_address (ip4_addr, iblock->ip);
+ nm_ip4_address_set_prefix (ip4_addr,
+ nm_utils_ip4_netmask_to_prefix
+ (iblock->netmask));
+ /* currently all the IPs has the same gateway */
+ nm_ip4_address_set_gateway (ip4_addr, iblock->gateway);
+ if (iblock->gateway)
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES,
+ TRUE, NULL);
+ if (!nm_setting_ip4_config_add_address (ip4_setting, ip4_addr))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "ignoring duplicate IP4 address");
+ nm_ip4_address_unref (ip4_addr);
+ current_iblock = iblock;
+ iblock = iblock->next;
+ destroy_ip_block (current_iblock);
+
+ }
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name),
+ NULL);
+ }
+
+ /* add dhcp hostname and client id */
+ if (!is_static_block && !strcmp (method, "dhcp")) {
+ gchar *dhcp_hostname, *client_id;
+
+ get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id);
+ if (dhcp_hostname) {
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
+ dhcp_hostname, NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "DHCP hostname: %s",
+ dhcp_hostname);
+ g_free (dhcp_hostname);
+ }
+ if (client_id) {
+ g_object_set (ip4_setting,
+ NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID,
+ client_id, NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "DHCP client id: %s",
+ client_id);
+ g_free (client_id);
+ }
+ }
+
+ /* add all IPv4 dns servers, IPv6 servers will be ignored */
+ set_ip4_dns_servers (ip4_setting, conn_name);
+
+ /* DNS searches */
+ value = ifnet_get_data (conn_name, "dns_search");
+ if (value) {
+ char *stripped = g_strdup (value);
+ char **searches = NULL;
+
+ strip_string (stripped, '"');
+
+ searches = g_strsplit (stripped, " ", 0);
+ if (searches) {
+ char **item;
+
+ for (item = searches; *item; item++) {
+ if (strlen (*item)) {
+ if (!nm_setting_ip4_config_add_dns_search (ip4_setting, *item))
+ PLUGIN_WARN
+ (IFNET_PLUGIN_NAME,
+ " warning: duplicate DNS domain '%s'",
+ *item);
+ }
+ }
+ g_strfreev (searches);
+ }
+ }
+
+ /* static routes */
+ iblock = convert_ip4_routes_block (conn_name);
+ while (iblock) {
+ ip_block *current_iblock = iblock;
+ const char *metric_str;
+ char *stripped;
+ long int metric;
+ NMIP4Route *route = nm_ip4_route_new ();
+
+ nm_ip4_route_set_dest (route, iblock->ip);
+ nm_ip4_route_set_next_hop (route, iblock->gateway);
+ nm_ip4_route_set_prefix (route,
+ nm_utils_ip4_netmask_to_prefix
+ (iblock->netmask));
+ if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
+ metric = strtol (metric_str, NULL, 10);
+ nm_ip4_route_set_metric (route, (guint32) metric);
+ } else {
+ metric_str = ifnet_get_global_data ("metric");
+ if (metric_str) {
+ stripped = g_strdup (metric_str);
+ strip_string (stripped, '"');
+ metric = strtol (metric_str, NULL, 10);
+ nm_ip4_route_set_metric (route,
+ (guint32) metric);
+ g_free (stripped);
+ }
+ }
+
+ if (!nm_setting_ip4_config_add_route (ip4_setting, route))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "warning: duplicate IP4 route");
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "new IP4 route:%d\n", iblock->ip);
+
+ nm_ip4_route_unref (route);
+
+ current_iblock = iblock;
+ iblock = iblock->next;
+ destroy_ip_block (current_iblock);
+ }
+
+ /* Finally add setting to connection */
+ nm_connection_add_setting (connection, NM_SETTING (ip4_setting));
+}
+
+static void
+make_ip6_setting (NMConnection *connection,
+ const char *conn_name,
+ GError **error)
+{
+ NMSettingIP6Config *s_ip6 = NULL;
+ gboolean is_static_block = is_static_ip6 (conn_name);
+
+ // used to disable IPv6
+ gboolean ipv6_enabled = FALSE;
+ gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+ const char *value;
+ ip6_block *iblock;
+ gboolean never_default = !has_default_ip6_route (conn_name);
+
+ s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+ if (!s_ip6) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Could not allocate IP6 setting");
+ return;
+ }
+
+ value = ifnet_get_data (conn_name, "enable_ipv6");
+ if (value && is_true (value))
+ ipv6_enabled = TRUE;
+
+ //FIXME Handle other methods that NM supports in future
+ // Currently only Manual and DHCP are supported
+ if (!ipv6_enabled) {
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD,
+ NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL);
+ goto done;
+ } else if (!is_static_block) {
+ // config_eth* contains "dhcp6"
+ method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
+ never_default = FALSE;
+ }
+ // else if (!has_ip6_address(conn_name))
+ // doesn't have "dhcp6" && doesn't have any ipv6 address
+ // method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
+ else
+ // doesn't have "dhcp6" && has at least one ipv6 address
+ method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "IPv6 for %s enabled, using %s",
+ conn_name, method);
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, method,
+ NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, FALSE,
+ NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, FALSE,
+ NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default, NULL);
+
+ /* Make manual settings */
+ if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ ip6_block *current_iblock;
+
+ iblock = convert_ip6_config_block (conn_name);
+ if (!iblock) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Ifnet plugin: can't aquire ip6 configuration for %s",
+ conn_name);
+ goto error;
+ }
+ /* add all IPv6 addresses */
+ while (iblock) {
+ NMIP6Address *ip6_addr = nm_ip6_address_new ();
+
+ nm_ip6_address_set_address (ip6_addr, iblock->ip);
+ nm_ip6_address_set_prefix (ip6_addr, iblock->prefix);
+ if (nm_setting_ip6_config_add_address (s_ip6, ip6_addr)) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "ipv6 addresses count: %d",
+ nm_setting_ip6_config_get_num_addresses
+ (s_ip6));
+ } else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "ignoring duplicate IP4 address");
+ }
+ nm_ip6_address_unref (ip6_addr);
+ current_iblock = iblock;
+ iblock = iblock->next;
+ destroy_ip6_block (current_iblock);
+ }
+
+ } else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ /* - autoconf or DHCPv6 stuff goes here */
+ }
+ // DNS Servers, set NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS TRUE here
+ set_ip6_dns_servers (s_ip6, conn_name);
+
+ /* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */
+
+ // Add routes
+ iblock = convert_ip6_routes_block (conn_name);
+ if (iblock)
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES,
+ TRUE, NULL);
+ /* Add all IPv6 routes */
+ while (iblock) {
+ ip6_block *current_iblock = iblock;
+ const char *metric_str;
+ char *stripped;
+ long int metric = 1;
+ NMIP6Route *route = nm_ip6_route_new ();
+
+ nm_ip6_route_set_dest (route, iblock->ip);
+ nm_ip6_route_set_next_hop (route, iblock->next_hop);
+ nm_ip6_route_set_prefix (route, iblock->prefix);
+ /* metric is not per routes configuration right now
+ * global metric is also supported (metric="x") */
+ if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) {
+ metric = strtol (metric_str, NULL, 10);
+ nm_ip6_route_set_metric (route, (guint32) metric);
+ } else {
+ metric_str = ifnet_get_global_data ("metric");
+ if (metric_str) {
+ stripped = g_strdup (metric_str);
+ strip_string (stripped, '"');
+ metric = strtol (metric_str, NULL, 10);
+ nm_ip6_route_set_metric (route,
+ (guint32) metric);
+ g_free (stripped);
+ } else
+ nm_ip6_route_set_metric (route, (guint32) 1);
+ }
+
+ if (!nm_setting_ip6_config_add_route (s_ip6, route))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: duplicate IP6 route");
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, " info: new IP6 route");
+ nm_ip6_route_unref (route);
+
+ current_iblock = iblock;
+ iblock = iblock->next;
+ destroy_ip6_block (current_iblock);
+ }
+
+done:
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+ return;
+
+error:
+ g_object_unref (s_ip6);
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, " warning: Ignore IPv6 for %s",
+ conn_name);
+ return;
+}
+
+static NMSetting *
+make_wireless_connection_setting (const char *conn_name,
+ NMSetting8021x **s_8021x,
+ GError **error)
+{
+ GByteArray *array, *mac = NULL;
+ NMSettingWireless *wireless_setting = NULL;
+ gboolean adhoc = FALSE;
+ const char *value;
+ const char *type;
+
+ /* PPP over WIFI is not supported yet */
+ g_return_val_if_fail (conn_name != NULL
+ && strcmp (ifnet_get_data (conn_name, "type"),
+ "ppp") != 0, NULL);
+ type = ifnet_get_data (conn_name, "type");
+ if (strcmp (type, "ppp") == 0) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "PPP over WIFI is not supported yet");
+ return NULL;
+ }
+
+ wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+ if (read_mac_address (conn_name, &mac, error)) {
+ if (mac) {
+ g_object_set (wireless_setting,
+ NM_SETTING_WIRELESS_MAC_ADDRESS, mac,
+ NULL);
+ g_byte_array_free (mac, TRUE);
+
+ }
+ } else {
+ g_object_unref (wireless_setting);
+ return NULL;
+ }
+
+ /* handle ssid (hex and ascii) */
+ if (conn_name) {
+ gsize ssid_len = 0, value_len = strlen (conn_name);
+ const char *p;
+ char *tmp, *converted = NULL;
+
+ ssid_len = value_len;
+ if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) {
+ /* Hex representation */
+ if (value_len % 2) {
+ g_set_error (error, ifnet_plugin_error_quark (),
+ 0,
+ "Invalid SSID '%s' size (looks like hex but length not multiple of 2)",
+ conn_name);
+ goto error;
+ }
+ // ignore "0x"
+ p = conn_name + 2;
+ if (!is_hex (p)) {
+ g_set_error (error,
+ ifnet_plugin_error_quark (),
+ 0,
+ "Invalid SSID '%s' character (looks like hex SSID but '%c' isn't a hex digit)",
+ conn_name, *p);
+ goto error;
+
+ }
+ tmp = utils_hexstr2bin (p, value_len - 2);
+ ssid_len = (value_len - 2) / 2;
+ converted = g_malloc0 (ssid_len + 1);
+ memcpy (converted, tmp, ssid_len);
+ g_free (tmp);
+ }
+
+ if (ssid_len > 32 || ssid_len == 0) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid SSID '%s' (size %zu not between 1 and 32 inclusive)",
+ conn_name, ssid_len);
+ goto error;
+ }
+ array = g_byte_array_sized_new (ssid_len);
+ g_byte_array_append (array, (const guint8 *) (converted ? converted : conn_name), ssid_len);
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, array, NULL);
+ g_byte_array_free (array, TRUE);
+ g_free (converted);
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing SSID");
+ goto error;
+ }
+
+ /* mode=0: infrastructure
+ * mode=1: adhoc */
+ value = wpa_get_value (conn_name, "mode");
+ if (value)
+ adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE;
+
+ if (exist_ssid (conn_name)) {
+ const char *mode = adhoc ? "adhoc" : "infrastructure";
+
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, mode,
+ NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Using mode: %s", mode);
+ }
+
+ /* BSSID setting */
+ value = wpa_get_value (conn_name, "bssid");
+ if (value) {
+ struct ether_addr *eth;
+ GByteArray *bssid;
+
+ eth = ether_aton (value);
+ if (!eth) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid BSSID '%s'", value);
+ goto error;
+ }
+
+ bssid = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN);
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID,
+ bssid, NULL);
+ g_byte_array_free (bssid, TRUE);
+
+ }
+
+ /* mtu_ssid="xx" */
+ value = ifnet_get_data (conn_name, "mtu");
+ if (value) {
+ long int mtu;
+
+ errno = 0;
+ mtu = strtol (value, NULL, 10);
+ if (errno || mtu < 0 || mtu > 50000) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: invalid MTU '%s' for %s",
+ value, conn_name);
+ } else
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_MTU,
+ (guint32) mtu, NULL);
+
+ }
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "wireless_setting added for %s",
+ conn_name);
+ return NM_SETTING (wireless_setting);
+error:
+ if (wireless_setting)
+ g_object_unref (wireless_setting);
+ return NULL;
+
+}
+
+static NMSettingWirelessSecurity *
+make_leap_setting (const char *ssid, GError **error)
+{
+ NMSettingWirelessSecurity *wsec;
+ const char *value;
+
+ wsec =
+ NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+
+ value = wpa_get_value (ssid, "key_mgmt");
+ if (!value || strcmp (value, "IEEE8021X"))
+ goto error; /* Not LEAP */
+
+ value = wpa_get_value (ssid, "eap");
+ if (!value || strcasecmp (value, "LEAP"))
+ goto error; /* Not LEAP */
+
+ value = wpa_get_value (ssid, "password");
+ if (value && strlen (value))
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD,
+ value, NULL);
+
+ value = wpa_get_value (ssid, "identity");
+ if (!value || !strlen (value)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing LEAP identity");
+ goto error;
+ }
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, value,
+ NULL);
+
+ g_object_set (wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x",
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL);
+
+ return wsec;
+error:
+ if (wsec)
+ g_object_unref (wsec);
+ return NULL;
+}
+
+static gboolean
+add_one_wep_key (const char *ssid,
+ const char *key,
+ int key_idx,
+ NMSettingWirelessSecurity *s_wsec,
+ GError **error)
+{
+ const char *value;
+ char *converted = NULL;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (ssid != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+ g_return_val_if_fail (key_idx >= 0 && key_idx <= 3, FALSE);
+ g_return_val_if_fail (s_wsec != NULL, FALSE);
+
+ value = wpa_get_value (ssid, key);
+ if (!value)
+ return TRUE;
+
+ /* Validate keys */
+ if (strlen (value) == 10 || strlen (value) == 26) {
+ /* Hexadecimal WEP key */
+ if (!is_hex (value)) {
+ g_set_error (error, ifnet_plugin_error_quark (),
+ 0, "Invalid hexadecimal WEP key.");
+ goto out;
+ }
+ converted = g_strdup (value);
+ } else if (value[0] == '"'
+ && (strlen (value) == 7 || strlen (value) == 15)) {
+ /* ASCII passphrase */
+ char *tmp = g_strdup (value);
+ char *p = strip_string (tmp, '"');
+
+ if (!is_ascii (p)) {
+ g_set_error (error, ifnet_plugin_error_quark (),
+ 0, "Invalid ASCII WEP passphrase.");
+ g_free (tmp);
+ goto out;
+
+ }
+
+ converted = utils_bin2hexstr (tmp, strlen (tmp), strlen (tmp) * 2);
+ g_free (tmp);
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid WEP key length. Key: %s", value);
+ goto out;
+ }
+
+ if (converted) {
+ nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, converted);
+ g_free (converted);
+ success = TRUE;
+ }
+
+out:
+ return success;
+}
+
+static gboolean
+add_wep_keys (const char *ssid,
+ NMSettingWirelessSecurity *s_wsec,
+ GError **error)
+{
+ if (!add_one_wep_key (ssid, "wep_key0", 0, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ssid, "wep_key1", 1, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ssid, "wep_key2", 2, s_wsec, error))
+ return FALSE;
+ if (!add_one_wep_key (ssid, "wep_key3", 3, s_wsec, error))
+ return FALSE;
+ return TRUE;
+
+}
+
+static NMSettingWirelessSecurity *
+make_wep_setting (const char *ssid, GError **error)
+{
+ const char *auth_alg, *value;
+ int default_key_idx = 0;
+ NMSettingWirelessSecurity *s_wireless_sec;
+
+ s_wireless_sec =
+ NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+ g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+ "none", NULL);
+
+ /* default key index */
+ value = wpa_get_value (ssid, "wep_tx_keyidx");
+ if (value) {
+ default_key_idx = atoi (value);
+ if (default_key_idx >= 0 && default_key_idx <= 3) {
+ g_object_set (s_wireless_sec,
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX,
+ default_key_idx, NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "Default key index: %d", default_key_idx);
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid default WEP key '%s'", value);
+ goto error;
+ }
+ }
+
+ if (!add_wep_keys (ssid, s_wireless_sec, error))
+ goto error;
+
+ /* If there's a default key, ensure that key exists */
+ if ((default_key_idx == 1)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Default WEP key index was 2, but no valid KEY2 exists.");
+ goto error;
+ } else if ((default_key_idx == 2)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec,
+ 2)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Default WEP key index was 3, but no valid KEY3 exists.");
+ goto error;
+ } else if ((default_key_idx == 3)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec,
+ 3)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Default WEP key index was 4, but no valid KEY4 exists.");
+ goto error;
+ }
+
+ /* authentication algorithms */
+ auth_alg = wpa_get_value (ssid, "auth_alg");
+ if (auth_alg) {
+ if (strcmp (auth_alg, "OPEN") == 0) {
+ g_object_set (s_wireless_sec,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG,
+ "open", NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "WEP: Use open system authentication");
+ } else if (strcmp (auth_alg, "SHARED") == 0) {
+ g_object_set (s_wireless_sec,
+ NM_SETTING_WIRELESS_SECURITY_AUTH_ALG,
+ "shared", NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "WEP: Use shared system authentication");
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid WEP authentication algorithm '%s'",
+ auth_alg);
+ goto error;
+ }
+
+ }
+
+ if (!nm_setting_wireless_security_get_wep_key (s_wireless_sec, 0)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2)
+ && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3)
+ && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) {
+ if (auth_alg && !strcmp (auth_alg, "shared")) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "WEP Shared Key authentication is invalid for "
+ "unencrypted connections.");
+ goto error;
+ }
+ /* Unencrypted */
+ g_object_unref (s_wireless_sec);
+ s_wireless_sec = NULL;
+ }
+ return s_wireless_sec;
+
+error:
+ if (s_wireless_sec)
+ g_object_unref (s_wireless_sec);
+ return NULL;
+}
+
+static char *
+parse_wpa_psk (const char *psk, GError **error)
+{
+ char *hashed = NULL;
+ gboolean quoted = FALSE;
+
+ if (!psk) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing WPA_PSK for WPA-PSK key management");
+ return NULL;
+ }
+
+ /* Passphrase must be between 10 and 66 characters in length becuase WPA
+ * hex keys are exactly 64 characters (no quoting), and WPA passphrases
+ * are between 8 and 63 characters (inclusive), plus optional quoting if
+ * the passphrase contains spaces.
+ */
+
+ if (psk[0] == '"' && psk[strlen (psk) - 1] == '"')
+ quoted = TRUE;
+ if (!quoted && (strlen (psk) == 64)) {
+ /* Verify the hex PSK; 64 digits */
+ if (!is_hex (psk)) {
+ g_set_error (error, ifnet_plugin_error_quark (),
+ 0,
+ "Invalid WPA_PSK (contains non-hexadecimal characters)");
+ goto out;
+ }
+ hashed = g_strdup (psk);
+ } else {
+ char *stripped = g_strdup (psk);
+
+ strip_string (stripped, '"');
+
+ /* Length check */
+ if (strlen (stripped) < 8 || strlen (stripped) > 63) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid WPA_PSK (passphrases must be between "
+ "8 and 63 characters long (inclusive))");
+ g_free (stripped);
+ goto out;
+ }
+
+ hashed = g_strdup (stripped);
+ g_free (stripped);
+ }
+
+ if (!hashed) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid WPA_PSK (doesn't look like a passphrase or hex key)");
+ goto out;
+ }
+
+out:
+ return hashed;
+}
+
+static gboolean
+fill_wpa_ciphers (const char *ssid,
+ NMSettingWirelessSecurity *wsec,
+ gboolean group,
+ gboolean adhoc)
+{
+ const char *value;
+ char **list = NULL, **iter;
+ int i = 0;
+
+ value = wpa_get_value (ssid, group ? "group" : "pairwise");
+ if (!value)
+ return TRUE;
+
+ list = g_strsplit_set (value, " ", 0);
+ for (iter = list; iter && *iter; iter++, i++) {
+ /* Ad-Hoc configurations cannot have pairwise ciphers, and can only
+ * have one group cipher. Ignore any additional group ciphers and
+ * any pairwise ciphers specified.
+ */
+ if (adhoc) {
+ if (group && (i > 0)) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: ignoring group cipher '%s' (only one group cipher allowed in Ad-Hoc mode)",
+ *iter);
+ continue;
+ } else if (!group) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: ignoring pairwise cipher '%s' (pairwise not used in Ad-Hoc mode)",
+ *iter);
+ continue;
+ }
+ }
+
+ if (!strcmp (*iter, "CCMP")) {
+ if (group)
+ nm_setting_wireless_security_add_group (wsec,
+ "ccmp");
+ else
+ nm_setting_wireless_security_add_pairwise (wsec,
+ "ccmp");
+ } else if (!strcmp (*iter, "TKIP")) {
+ if (group)
+ nm_setting_wireless_security_add_group (wsec,
+ "tkip");
+ else
+ nm_setting_wireless_security_add_pairwise (wsec,
+ "tkip");
+ } else if (group && !strcmp (*iter, "WEP104"))
+ nm_setting_wireless_security_add_group (wsec, "wep104");
+ else if (group && !strcmp (*iter, "WEP40"))
+ nm_setting_wireless_security_add_group (wsec, "wep40");
+ else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: ignoring invalid %s cipher '%s'",
+ group ? "CIPHER_GROUP" : "CIPHER_PAIRWISE",
+ *iter);
+ }
+ }
+
+ if (list)
+ g_strfreev (list);
+ return TRUE;
+}
+
+static NMSetting8021x *
+fill_8021x (const char *ssid,
+ const char *key_mgmt,
+ gboolean wifi,
+ GError **error)
+{
+ NMSetting8021x *s_8021x;
+ const char *value;
+ char **list, **iter;
+
+ value = wpa_get_value (ssid, "eap");
+ if (!value) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing IEEE_8021X_EAP_METHODS for key management '%s'",
+ key_mgmt);
+ return NULL;
+ }
+
+ list = g_strsplit (value, " ", 0);
+
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ /* Validate and handle each EAP method */
+ for (iter = list; iter && *iter; iter++) {
+ EAPReader *eap = &eap_readers[0];
+ gboolean found = FALSE;
+ char *lower = NULL;
+
+ lower = g_ascii_strdown (*iter, -1);
+ while (eap->method && !found) {
+ if (strcmp (eap->method, lower))
+ goto next;
+
+ /* Some EAP methods don't provide keying material, thus they
+ * cannot be used with WiFi unless they are an inner method
+ * used with TTLS or PEAP or whatever.
+ */
+ if (wifi && eap->wifi_phase2_only) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: ignored invalid "
+ "IEEE_8021X_EAP_METHOD '%s'; not allowed for wifi.",
+ lower);
+ goto next;
+ }
+
+ /* Parse EAP method specific options */
+ if (!(*eap->reader)
+ (lower, ssid, s_8021x, FALSE, error)) {
+ g_free (lower);
+ goto error;
+ }
+ nm_setting_802_1x_add_eap_method (s_8021x, lower);
+ found = TRUE;
+
+ next:
+ eap++;
+ }
+
+ if (!found) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: ignored unknown"
+ "IEEE_8021X_EAP_METHOD '%s'.", lower);
+ }
+ g_free (lower);
+ }
+ g_strfreev (list);
+
+ if (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 0) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "No valid EAP methods found in IEEE_8021X_EAP_METHODS.");
+ goto error;
+ }
+
+ return s_8021x;
+
+error:
+ g_object_unref (s_8021x);
+ return NULL;
+}
+
+static NMSettingWirelessSecurity *
+make_wpa_setting (const char *ssid,
+ NMSetting8021x **s_8021x,
+ GError **error)
+{
+ NMSettingWirelessSecurity *wsec;
+ const char *value;
+ char *lower;
+ gboolean adhoc = FALSE;
+
+ if (!exist_ssid (ssid)) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "No security info found for ssid: %s", ssid);
+ return NULL;
+ }
+
+ wsec =
+ NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
+
+ /* mode=1: adhoc
+ * mode=0: infrastructure */
+ value = wpa_get_value (ssid, "mode");
+ if (value)
+ adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE;
+
+ value = wpa_get_value (ssid, "key_mgmt");
+ /* Not WPA or Dynamic WEP */
+ if (!value)
+ goto error;
+ if (strcmp (value, "WPA-PSK") && strcmp (value, "WPA-EAP"))
+ goto error;
+ /* Pairwise and Group ciphers */
+ fill_wpa_ciphers (ssid, wsec, FALSE, adhoc);
+ fill_wpa_ciphers (ssid, wsec, TRUE, adhoc);
+
+ /* WPA and/or RSN */
+ if (adhoc) {
+ /* Ad-Hoc mode only supports WPA proto for now */
+ nm_setting_wireless_security_add_proto (wsec, "wpa");
+ } else {
+ nm_setting_wireless_security_add_proto (wsec, "wpa");
+ nm_setting_wireless_security_add_proto (wsec, "rsn");
+
+ }
+
+ if (!strcmp (value, "WPA-PSK")) {
+ char *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error);
+
+ if (!psk)
+ goto error;
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk,
+ NULL);
+ g_free (psk);
+
+ if (adhoc)
+ g_object_set (wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+ "wpa-none", NULL);
+ else
+ g_object_set (wsec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+ "wpa-psk", NULL);
+ } else if (!strcmp (value, "WPA-EAP") || !strcmp (value, "IEEE8021X")) {
+ if (adhoc) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Ad-Hoc mode cannot be used with KEY_MGMT type '%s'",
+ value);
+ goto error;
+ }
+ *s_8021x = fill_8021x (ssid, value, TRUE, error);
+ if (!*s_8021x)
+ goto error;
+
+ lower = g_ascii_strdown (value, -1);
+ g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+ lower, NULL);
+ g_free (lower);
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Unknown wireless KEY_MGMT type '%s'", value);
+ goto error;
+ }
+ return wsec;
+error:
+ if (wsec)
+ g_object_unref (wsec);
+ return NULL;
+}
+
+static NMSettingWirelessSecurity *
+make_wireless_security_setting (const char *conn_name,
+ NMSetting8021x **s_8021x,
+ GError ** error)
+{
+ NMSettingWirelessSecurity *wsec = NULL;
+ const char *ssid;
+ gboolean adhoc = FALSE;
+ const char *value;
+
+ g_return_val_if_fail (conn_name != NULL
+ && strcmp (ifnet_get_data (conn_name, "type"),
+ "ppp") != 0, NULL);
+ if (!wpa_get_value (conn_name, "ssid"))
+ return NULL;
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "updating wireless security settings (%s).", conn_name);
+
+ ssid = conn_name;
+ value = wpa_get_value (ssid, "mode");
+ if (value)
+ adhoc = strcmp (value, "1") == 0 ? TRUE : FALSE;
+
+ if (!adhoc) {
+ wsec = make_leap_setting (ssid, error);
+ if (error && *error)
+ goto error;
+ }
+ if (!wsec) {
+ wsec = make_wpa_setting (ssid, s_8021x, error);
+ if (error && *error)
+ goto error;
+ }
+ if (!wsec) {
+ wsec = make_wep_setting (ssid, error);
+ if (error && *error)
+ goto error;
+ }
+
+ if (!wsec) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Can't handle security information for ssid: %s",
+ conn_name);
+ }
+
+ return wsec;
+error:
+ return NULL;
+}
+
+/* Currently only support username and password */
+static void
+make_pppoe_connection_setting (NMConnection *connection,
+ const char *conn_name,
+ GError **error)
+{
+ NMSettingPPPOE *s_pppoe;
+ NMSettingPPP *s_ppp;
+ const char *value;
+
+ s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ());
+
+ /* username */
+ value = ifnet_get_data (conn_name, "username");
+ if (!value) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "ppp requires at lease a username");
+ return;
+ }
+ g_object_set (s_pppoe, NM_SETTING_PPPOE_USERNAME, value, NULL);
+
+ /* password */
+ value = ifnet_get_data (conn_name, "password");
+ if (!value) {
+ value = "";
+ }
+
+ g_object_set (s_pppoe, NM_SETTING_PPPOE_PASSWORD, value, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_pppoe));
+
+ /* PPP setting */
+ s_ppp = (NMSettingPPP *) nm_setting_ppp_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_ppp));
+}
+
+NMConnection *
+ifnet_update_connection_from_config_block (const char *conn_name, GError **error)
+{
+ const gchar *type = NULL;
+ NMConnection *connection = NULL;
+ NMSettingConnection *setting = NULL;
+ NMSetting8021x *s_8021x = NULL;
+ NMSettingWirelessSecurity *wsec = NULL;
+ gboolean auto_conn = TRUE;
+ const char *value = NULL;
+ gboolean success = FALSE;
+
+ connection = nm_connection_new ();
+ if (!connection)
+ return NULL;
+ setting =
+ (NMSettingConnection *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_CONNECTION);
+ if (!setting) {
+ setting = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ g_assert (setting);
+ nm_connection_add_setting (connection, NM_SETTING (setting));
+ }
+
+ type = guess_connection_type (conn_name);
+ value = ifnet_get_data (conn_name, "auto");
+ if (value && !strcmp (value, "false"))
+ auto_conn = FALSE;
+ update_connection_id (connection, conn_name);
+ g_object_set (setting, NM_SETTING_CONNECTION_TYPE, type,
+ NM_SETTING_CONNECTION_READ_ONLY, FALSE,
+ NM_SETTING_CONNECTION_AUTOCONNECT, auto_conn, NULL);
+
+ if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type)
+ || !strcmp (NM_SETTING_PPPOE_SETTING_NAME, type)) {
+ /* wired setting */
+ make_wired_connection_setting (connection, conn_name, error);
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto error;
+ }
+ /* pppoe setting */
+ if (!strcmp (NM_SETTING_PPPOE_SETTING_NAME, type))
+ make_pppoe_connection_setting (connection, conn_name,
+ error);
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto error;
+ }
+ } else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
+ /* wireless setting */
+ NMSetting *wireless_setting;
+
+ wireless_setting = make_wireless_connection_setting (conn_name, &s_8021x, error);
+ if (!wireless_setting)
+ goto error;
+ nm_connection_add_setting (connection, wireless_setting);
+
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto error;
+ }
+
+ /* wireless security setting */
+ wsec = make_wireless_security_setting (conn_name, &s_8021x, error);
+ if (wsec) {
+ nm_connection_add_setting (connection,
+ NM_SETTING (wsec));
+ if (s_8021x)
+ nm_connection_add_setting (connection,
+ NM_SETTING
+ (s_8021x));
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_SEC,
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
+ NULL);
+ }
+
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto error;
+ }
+
+ } else
+ goto error;
+
+ /* IPv4 setting */
+ make_ip4_setting (connection, conn_name, error);
+ if (error && *error)
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+
+ /* IPv6 setting */
+ make_ip6_setting (connection, conn_name, error);
+ if (error && *error)
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+
+ success = nm_connection_verify (connection, error);
+ if (error && *error)
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, success);
+ if (!success)
+ goto error;
+ return connection;
+
+error:
+ g_object_unref (setting);
+ g_object_unref (connection);
+ return NULL;
+}
+
+typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x * setting);
+typedef const char *(*PathFunc) (NMSetting8021x * setting);
+typedef const GByteArray *(*BlobFunc) (NMSetting8021x * setting);
+
+typedef struct ObjectType {
+ const char *setting_key;
+ SchemeFunc scheme_func;
+ PathFunc path_func;
+ BlobFunc blob_func;
+ const char *conn_name_key;
+ const char *suffix;
+} ObjectType;
+
+static const ObjectType ca_type = {
+ NM_SETTING_802_1X_CA_CERT,
+ nm_setting_802_1x_get_ca_cert_scheme,
+ nm_setting_802_1x_get_ca_cert_path,
+ nm_setting_802_1x_get_ca_cert_blob,
+ "ca_cert",
+ "ca-cert.der"
+};
+
+static const ObjectType phase2_ca_type = {
+ NM_SETTING_802_1X_PHASE2_CA_CERT,
+ nm_setting_802_1x_get_phase2_ca_cert_scheme,
+ nm_setting_802_1x_get_phase2_ca_cert_path,
+ nm_setting_802_1x_get_phase2_ca_cert_blob,
+ "ca_cert2",
+ "inner-ca-cert.der"
+};
+
+static const ObjectType client_type = {
+ NM_SETTING_802_1X_CLIENT_CERT,
+ nm_setting_802_1x_get_client_cert_scheme,
+ nm_setting_802_1x_get_client_cert_path,
+ nm_setting_802_1x_get_client_cert_blob,
+ "client_cert",
+ "client-cert.der"
+};
+
+static const ObjectType phase2_client_type = {
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ nm_setting_802_1x_get_phase2_client_cert_scheme,
+ nm_setting_802_1x_get_phase2_client_cert_path,
+ nm_setting_802_1x_get_phase2_client_cert_blob,
+ "client_cert2",
+ "inner-client-cert.der"
+};
+
+static const ObjectType pk_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ "private_key",
+ "private-key.pem"
+};
+
+static const ObjectType phase2_pk_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ "private_key2",
+ "inner-private-key.pem"
+};
+
+static const ObjectType p12_type = {
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob,
+ "private_key",
+ "private-key.p12"
+};
+
+static const ObjectType phase2_p12_type = {
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob,
+ "private_key2",
+ "inner-private-key.p12"
+};
+
+static gboolean
+write_object (NMSetting8021x *s_8021x,
+ const char *conn_name,
+ const GByteArray *override_data,
+ const ObjectType *objtype,
+ GError **error)
+{
+ NMSetting8021xCKScheme scheme;
+ const char *path = NULL;
+ const GByteArray *blob = NULL;
+
+ g_return_val_if_fail (conn_name != NULL, FALSE);
+ g_return_val_if_fail (objtype != NULL, FALSE);
+ if (override_data)
+ /* if given explicit data to save, always use that instead of asking
+ * the setting what to do.
+ */
+ blob = override_data;
+ else {
+ scheme = (*(objtype->scheme_func)) (s_8021x);
+ switch (scheme) {
+ case NM_SETTING_802_1X_CK_SCHEME_BLOB:
+ blob = (*(objtype->blob_func)) (s_8021x);
+ break;
+ case NM_SETTING_802_1X_CK_SCHEME_PATH:
+ path = (*(objtype->path_func)) (s_8021x);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If the object path was specified, prefer that over any raw cert data that
+ * may have been sent.
+ */
+ if (path) {
+ wpa_set_data (conn_name, (gchar *) objtype->conn_name_key,
+ (gchar *) path);
+ return TRUE;
+ }
+
+ /* does not support writing encryption data now */
+ if (blob) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ " warning: Currently we do not support certs writing.");
+ }
+
+ return TRUE;
+}
+
+static gboolean
+write_8021x_certs (NMSetting8021x *s_8021x,
+ gboolean phase2,
+ const char *conn_name,
+ GError **error)
+{
+ char *password = NULL;
+ const ObjectType *otype = NULL;
+ gboolean is_pkcs12 = FALSE, success = FALSE;
+ const GByteArray *blob = NULL;
+ GByteArray *enc_key = NULL;
+ gchar *generated_pw = NULL;
+
+ /* CA certificate */
+ if (phase2)
+ otype = &phase2_ca_type;
+ else
+ otype = &ca_type;
+
+ if (!write_object (s_8021x, conn_name, NULL, otype, error))
+ return FALSE;
+
+ /* Private key */
+ if (phase2) {
+ if (nm_setting_802_1x_get_phase2_private_key_scheme (s_8021x) !=
+ NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) {
+ if (nm_setting_802_1x_get_phase2_private_key_format
+ (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
+ is_pkcs12 = TRUE;
+ }
+ password = (char *)
+ nm_setting_802_1x_get_phase2_private_key_password (s_8021x);
+ } else {
+ if (nm_setting_802_1x_get_private_key_scheme (s_8021x) !=
+ NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) {
+ if (nm_setting_802_1x_get_private_key_format (s_8021x)
+ == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
+ is_pkcs12 = TRUE;
+ }
+ password = (char *)
+ nm_setting_802_1x_get_private_key_password (s_8021x);
+ }
+
+ if (is_pkcs12)
+ otype = phase2 ? &phase2_p12_type : &p12_type;
+ else
+ otype = phase2 ? &phase2_pk_type : &pk_type;
+
+ if ((*(otype->scheme_func)) (s_8021x) ==
+ NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ blob = (*(otype->blob_func)) (s_8021x);
+
+ /* Only do the private key re-encrypt dance if we got the raw key data, which
+ * by definition will be unencrypted. If we're given a direct path to the
+ * private key file, it'll be encrypted, so we don't need to re-encrypt.
+ */
+ if (blob && !is_pkcs12) {
+ /* Encrypt the unencrypted private key with the fake password */
+ enc_key =
+ nm_utils_rsa_key_encrypt (blob, password, &generated_pw,
+ error);
+ if (!enc_key)
+ goto out;
+
+ if (generated_pw)
+ password = generated_pw;
+ }
+
+ /* Save the private key */
+ if (!write_object
+ (s_8021x, conn_name, enc_key ? enc_key : blob, otype, error))
+ goto out;
+
+ if (phase2)
+ wpa_set_data (conn_name, "private_key_passwd2", password);
+ else
+ wpa_set_data (conn_name, "private_key_passwd", password);
+
+ /* Client certificate */
+ if (is_pkcs12) {
+ wpa_set_data (conn_name,
+ phase2 ? "client_cert2" : "client_cert", NULL);
+ } else {
+ if (phase2)
+ otype = &phase2_client_type;
+ else
+ otype = &client_type;
+
+ /* Save the client certificate */
+ if (!write_object (s_8021x, conn_name, NULL, otype, error))
+ goto out;
+ }
+
+ success = TRUE;
+out:
+ if (generated_pw) {
+ memset (generated_pw, 0, strlen (generated_pw));
+ g_free (generated_pw);
+ }
+ if (enc_key) {
+ memset (enc_key->data, 0, enc_key->len);
+ g_byte_array_free (enc_key, TRUE);
+ }
+ return success;
+}
+
+static gboolean
+write_8021x_setting (NMConnection *connection,
+ const char *conn_name,
+ gboolean wired,
+ GError **error)
+{
+ NMSetting8021x *s_8021x;
+ const char *value;
+ char *tmp = NULL;
+ gboolean success = FALSE;
+ GString *phase2_auth;
+ GString *phase1;
+
+ s_8021x =
+ (NMSetting8021x *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_802_1X);
+
+ if (!s_8021x) {
+ return TRUE;
+ }
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding 8021x setting for %s",
+ conn_name);
+
+ /* If wired, write KEY_MGMT */
+ if (wired)
+ wpa_set_data (conn_name, "key_mgmt", "IEEE8021X");
+
+ /* EAP method */
+ if (nm_setting_802_1x_get_num_eap_methods (s_8021x)) {
+ value = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ if (value)
+ tmp = g_ascii_strup (value, -1);
+ }
+ wpa_set_data (conn_name, "eap", tmp ? tmp : NULL);
+ g_free (tmp);
+
+ wpa_set_data (conn_name, "identity",
+ (gchar *) nm_setting_802_1x_get_identity (s_8021x));
+
+ wpa_set_data (conn_name, "anonymous_identity", (gchar *)
+ nm_setting_802_1x_get_anonymous_identity (s_8021x));
+
+ wpa_set_data (conn_name, "password",
+ (gchar *) nm_setting_802_1x_get_password (s_8021x));
+
+ phase1 = g_string_new (NULL);
+
+ /* PEAP version */
+ wpa_set_data (conn_name, "phase1", NULL);
+ value = nm_setting_802_1x_get_phase1_peapver (s_8021x);
+ if (value && (!strcmp (value, "0") || !strcmp (value, "1")))
+ g_string_append_printf (phase1, "peapver=%s ", value);
+
+ /* PEAP label */
+ value = nm_setting_802_1x_get_phase1_peaplabel (s_8021x);
+ if (value && !strcmp (value, "1"))
+ g_string_append_printf (phase1, "peaplabel=%s ", value);
+ if (phase1->len) {
+ tmp = g_strstrip (g_strdup (phase1->str));
+ wpa_set_data (conn_name, "phase1", tmp);
+ g_free (tmp);
+ }
+
+ /* Phase2 auth methods */
+ wpa_set_data (conn_name, "phase2", NULL);
+ phase2_auth = g_string_new (NULL);
+
+ value = nm_setting_802_1x_get_phase2_auth (s_8021x);
+ if (value) {
+ tmp = g_ascii_strup (value, -1);
+ g_string_append_printf (phase2_auth, "auth=%s ", tmp);
+ g_free (tmp);
+ }
+
+ /* Phase2 auth heap */
+ value = nm_setting_802_1x_get_phase2_autheap (s_8021x);
+ if (value) {
+ tmp = g_ascii_strup (value, -1);
+ g_string_append_printf (phase2_auth, "autheap=%s ", tmp);
+ g_free (tmp);
+ }
+ tmp = g_strstrip (g_strdup (phase2_auth->str));
+ wpa_set_data (conn_name, "phase2", phase2_auth->len ? tmp : NULL);
+ g_free (tmp);
+
+ g_string_free (phase2_auth, TRUE);
+ g_string_free (phase1, TRUE);
+
+ success = write_8021x_certs (s_8021x, FALSE, conn_name, error);
+ if (success) {
+ /* phase2/inner certs */
+ success = write_8021x_certs (s_8021x, TRUE, conn_name, error);
+ }
+
+ return success;
+}
+
+static gboolean
+write_wireless_security_setting (NMConnection * connection,
+ gchar * conn_name,
+ gboolean adhoc,
+ gboolean * no_8021x, GError ** error)
+{
+ NMSettingWirelessSecurity *s_wsec;
+ const char *key_mgmt, *auth_alg, *key, *cipher, *psk;
+ gboolean wep = FALSE, wpa = FALSE;
+ char *tmp;
+ guint32 i, num;
+ GString *str;
+
+ s_wsec =
+ (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_WIRELESS_SECURITY);
+ if (!s_wsec) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
+ return FALSE;
+ }
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ g_assert (key_mgmt);
+
+ auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec);
+
+ if (!strcmp (key_mgmt, "none")) {
+ wpa_set_data (conn_name, "key_mgmt", "NONE");
+ wep = TRUE;
+ *no_8021x = TRUE;
+ } else if (!strcmp (key_mgmt, "wpa-none")
+ || !strcmp (key_mgmt, "wpa-psk")) {
+ wpa_set_data (conn_name, "key_mgmt", "WPA-PSK");
+ wpa = TRUE;
+ *no_8021x = TRUE;
+ } else if (!strcmp (key_mgmt, "ieee8021x")) {
+ wpa_set_data (conn_name, "key_mgmt", "IEEE8021X");
+ } else if (!strcmp (key_mgmt, "wpa-eap")) {
+ wpa_set_data (conn_name, "key_mgmt", "WPA-EAP");
+ wpa = TRUE;
+ } else
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Unknown key_mgmt: %s", key_mgmt);
+
+ if (auth_alg) {
+ if (!strcmp (auth_alg, "shared"))
+ wpa_set_data (conn_name, "auth_alg", "SHARED");
+ else if (!strcmp (auth_alg, "open"))
+ wpa_set_data (conn_name, "auth_alg", "OPEN");
+ else if (!strcmp (auth_alg, "leap")) {
+ wpa_set_data (conn_name, "auth_alg", "LEAP");
+ wpa_set_data (conn_name, "eap", "LEAP");
+ wpa_set_data (conn_name, "identity", (gchar *)
+ nm_setting_wireless_security_get_leap_username
+ (s_wsec));
+ wpa_set_data (conn_name, "password", (gchar *)
+ nm_setting_wireless_security_get_leap_password
+ (s_wsec));
+ *no_8021x = TRUE;
+ }
+ } else
+ wpa_set_data (conn_name, "auth_alg", NULL);
+
+ /* Default WEP TX key index */
+ wpa_set_data (conn_name, "wep_tx_keyidx", NULL);
+ if (wep) {
+ tmp =
+ g_strdup_printf ("%d",
+ nm_setting_wireless_security_get_wep_tx_keyidx
+ (s_wsec));
+ wpa_set_data (conn_name, "wep_tx_keyidx", tmp);
+ g_free (tmp);
+ }
+
+ /* WEP keys */
+ for (i = 0; i < 4; i++) {
+ int length;
+
+ key = nm_setting_wireless_security_get_wep_key (s_wsec, i);
+ if (!key)
+ continue;
+ tmp = g_strdup_printf ("wep_key%d", i);
+ length = strlen (key);
+ if (length == 10 || length == 26 || length == 58)
+ wpa_set_data (conn_name, tmp, (gchar *) key);
+ else {
+ gchar *tmp_key = g_strdup_printf ("\"%s\"", key);
+
+ wpa_set_data (conn_name, tmp, tmp_key);
+ g_free (tmp_key);
+ }
+ g_free (tmp);
+ }
+
+ /* WPA Pairwise ciphers */
+ wpa_set_data (conn_name, "pairwise", NULL);
+ str = g_string_new (NULL);
+ num = nm_setting_wireless_security_get_num_pairwise (s_wsec);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (str, ' ');
+ cipher = nm_setting_wireless_security_get_pairwise (s_wsec, i);
+ tmp = g_ascii_strup (cipher, -1);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+ if (strlen (str->str))
+ wpa_set_data (conn_name, "pairwise", str->str);
+ g_string_free (str, TRUE);
+
+ /* WPA Group ciphers */
+ wpa_set_data (conn_name, "group", NULL);
+ str = g_string_new (NULL);
+ num = nm_setting_wireless_security_get_num_groups (s_wsec);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (str, ' ');
+ cipher = nm_setting_wireless_security_get_group (s_wsec, i);
+ tmp = g_ascii_strup (cipher, -1);
+ g_string_append (str, tmp);
+ g_free (tmp);
+ }
+ if (strlen (str->str))
+ wpa_set_data (conn_name, "group", str->str);
+ g_string_free (str, TRUE);
+
+ /* WPA Passphrase */
+ if (wpa) {
+ GString *quoted = NULL;
+
+ psk = nm_setting_wireless_security_get_psk (s_wsec);
+ if (psk && (strlen (psk) != 64)) {
+ quoted = g_string_sized_new (strlen (psk) + 2);
+ g_string_append_c (quoted, '"');
+ g_string_append (quoted, psk);
+ g_string_append_c (quoted, '"');
+ }
+ /* psk will be lost here if we don't check it for NULL */
+ if (psk)
+ wpa_set_data (conn_name, "psk",
+ quoted ? quoted->str : (gchar *) psk);
+ if (quoted)
+ g_string_free (quoted, TRUE);
+ } else
+ wpa_set_data (conn_name, "psk", NULL);
+
+ return TRUE;
+}
+
+/* remove old ssid and add new one*/
+static void
+update_wireless_ssid (NMConnection *connection,
+ const char *conn_name,
+ const char *ssid,
+ gboolean hex)
+{
+ if(strcmp (conn_name, ssid)){
+ ifnet_delete_network (conn_name);
+ wpa_delete_security (conn_name);
+ }
+
+ ifnet_add_network (ssid, "wireless");
+ wpa_add_security (ssid);
+}
+
+static gboolean
+write_wireless_setting (NMConnection *connection,
+ const char *conn_name,
+ gboolean *no_8021x,
+ const char **out_new_name,
+ GError **error)
+{
+ NMSettingWireless *s_wireless;
+ const GByteArray *ssid, *mac, *bssid;
+ const char *mode;
+ char buf[33];
+ guint32 mtu, i;
+ gboolean adhoc = FALSE, hex_ssid = FALSE;
+ gchar *ssid_str, *tmp;
+
+ s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ if (!s_wireless) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ ssid = nm_setting_wireless_get_ssid (s_wireless);
+ if (!ssid) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing SSID in '%s' setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+ if (!ssid->len || ssid->len > 32) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Invalid SSID in '%s' setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ /* If the SSID contains any non-alnum characters, we need to use
+ * the hex notation of the SSID instead. (Because openrc doesn't
+ * support these characters, see bug #356337)
+ */
+ for (i = 0; i < ssid->len; i++) {
+ if (!isalnum (ssid->data[i])) {
+ hex_ssid = TRUE;
+ break;
+ }
+ }
+
+ if (hex_ssid) {
+ GString *str;
+
+ /* Hex SSIDs don't get quoted */
+ str = g_string_sized_new (ssid->len * 2 + 3);
+ g_string_append (str, "0x");
+ for (i = 0; i < ssid->len; i++)
+ g_string_append_printf (str, "%02X", ssid->data[i]);
+ update_wireless_ssid (connection, conn_name, str->str, hex_ssid);
+ ssid_str = g_string_free (str, FALSE);
+ } else {
+ /* Printable SSIDs get quoted */
+ memset (buf, 0, sizeof (buf));
+ memcpy (buf, ssid->data, ssid->len);
+ g_strstrip (buf);
+ update_wireless_ssid (connection, conn_name, buf, hex_ssid);
+ ssid_str = g_strdup (buf);
+ }
+
+ ifnet_set_data (ssid_str, "mac", NULL);
+ mac = nm_setting_wireless_get_mac_address (s_wireless);
+ if (mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ mac->data[0], mac->data[1], mac->data[2],
+ mac->data[3], mac->data[4],
+ mac->data[5]);
+ ifnet_set_data (ssid_str, "mac", tmp);
+ g_free (tmp);
+ }
+
+ ifnet_set_data (ssid_str, "mtu", NULL);
+ mtu = nm_setting_wireless_get_mtu (s_wireless);
+ if (mtu) {
+ tmp = g_strdup_printf ("%u", mtu);
+ ifnet_set_data (ssid_str, "mtu", tmp);
+ g_free (tmp);
+ }
+
+ ifnet_set_data (ssid_str, "mode", NULL);
+ mode = nm_setting_wireless_get_mode (s_wireless);
+ if (!mode || !strcmp (mode, "infrastructure")) {
+ wpa_set_data (ssid_str, "mode", "0");
+ } else if (!strcmp (mode, "adhoc")) {
+ wpa_set_data (ssid_str, "mode", "1");
+ adhoc = TRUE;
+ } else {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Invalid mode '%s' in '%s' setting",
+ mode, NM_SETTING_WIRELESS_SETTING_NAME);
+ return FALSE;
+ }
+
+ wpa_set_data (ssid_str, "bssid", NULL);
+ bssid = nm_setting_wireless_get_bssid (s_wireless);
+ if (bssid) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ bssid->data[0], bssid->data[1],
+ bssid->data[2], bssid->data[3],
+ bssid->data[4], bssid->data[5]);
+ wpa_set_data (ssid_str, "bssid", tmp);
+ g_free (tmp);
+ }
+
+ if (nm_setting_wireless_get_security (s_wireless)) {
+ if (!write_wireless_security_setting
+ (connection, ssid_str, adhoc, no_8021x, error))
+ return FALSE;
+ } else
+ wpa_delete_security (ssid_str);
+
+ if (out_new_name)
+ *out_new_name = ifnet_get_data (ssid_str, "name");
+ g_free (ssid_str);
+ return TRUE;
+}
+
+static gboolean
+write_wired_setting (NMConnection *connection,
+ const char *conn_name,
+ GError **error)
+{
+ NMSettingWired *s_wired;
+ const GByteArray *mac;
+ char *tmp;
+ guint32 mtu;
+
+ s_wired =
+ (NMSettingWired *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_WIRED);
+ if (!s_wired) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ return FALSE;
+ }
+
+ ifnet_set_data (conn_name, "mac", NULL);
+ mac = nm_setting_wired_get_mac_address (s_wired);
+ if (mac) {
+ tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ mac->data[0], mac->data[1], mac->data[2],
+ mac->data[3], mac->data[4],
+ mac->data[5]);
+ ifnet_set_data (conn_name, "mac", tmp);
+ g_free (tmp);
+ }
+
+ ifnet_set_data (conn_name, "mtu", NULL);
+ mtu = nm_setting_wired_get_mtu (s_wired);
+ if (mtu) {
+ tmp = g_strdup_printf ("%u", mtu);
+ ifnet_set_data (conn_name, "mtu", tmp);
+ g_free (tmp);
+ }
+ //FIXME may add connection type in future
+ //ifnet_set_data (conn_name, "TYPE", TYPE_ETHERNET);
+
+ return TRUE;
+}
+
+static void
+write_connection_setting (NMSettingConnection *s_con, const char *conn_name)
+{
+ ifnet_set_data (conn_name, "auto",
+ nm_setting_connection_get_autoconnect (s_con) ? "true" :
+ "false");
+}
+
+static gboolean
+write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error)
+{
+ NMSettingIP4Config *s_ip4;
+ const char *value;
+ char *tmp;
+ guint32 i, num;
+ GString *searches;
+ GString *ips;
+ GString *routes;
+ GString *dns;
+ gboolean has_def_route = FALSE;
+ gboolean success = FALSE;
+
+ s_ip4 =
+ (NMSettingIP4Config *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_IP4_CONFIG);
+ if (!s_ip4) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ return FALSE;
+ }
+ routes = g_string_new (NULL);
+
+ value = nm_setting_ip4_config_get_method (s_ip4);
+ g_assert (value);
+ if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
+
+ num = nm_setting_ip4_config_get_num_addresses (s_ip4);
+ ips = g_string_new (NULL);
+ /* IPv4 addresses */
+ for (i = 0; i < num; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ NMIP4Address *addr;
+ guint32 ip;
+
+ addr = nm_setting_ip4_config_get_address (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_address_get_address (addr);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0],
+ sizeof (buf));
+ g_string_append_printf (ips, "\"%s", &buf[0]);
+
+ tmp =
+ g_strdup_printf ("%u",
+ nm_ip4_address_get_prefix (addr));
+ g_string_append_printf (ips, "/%s\" ", tmp);
+ g_free (tmp);
+
+ /* only the first gateway will be written */
+ if (!has_def_route && nm_ip4_address_get_gateway (addr)) {
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_address_get_gateway (addr);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0],
+ sizeof (buf));
+ g_string_append_printf (routes,
+ "\"default via %s\" ",
+ &buf[0]);
+ has_def_route = TRUE;
+ }
+ }
+ ifnet_set_data (conn_name, "config", ips->str);
+ g_string_free (ips, TRUE);
+ } else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_SHARED))
+ ifnet_set_data (conn_name, "config", "shared");
+ else if (!strcmp (value, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
+ ifnet_set_data (conn_name, "config", "autoip");
+ else
+ ifnet_set_data (conn_name, "config", "dhcp");
+
+ /* DNS Servers */
+ num = nm_setting_ip4_config_get_num_dns (s_ip4);
+ if (num > 0) {
+ dns = g_string_new (NULL);
+ for (i = 0; i < num; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ guint32 ip;
+
+ ip = nm_setting_ip4_config_get_dns (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0],
+ sizeof (buf));
+ g_string_append_printf (dns, " %s", buf);
+ }
+ ifnet_set_data (conn_name, "dns_servers", dns->str);
+ g_string_free (dns, TRUE);
+ } else
+ ifnet_set_data (conn_name, "dns_servers", NULL);
+
+ /* DNS Searches */
+ num = nm_setting_ip4_config_get_num_dns_searches (s_ip4);
+ if (num > 0) {
+ searches = g_string_new (NULL);
+ for (i = 0; i < num; i++) {
+ if (i > 0)
+ g_string_append_c (searches, ' ');
+ g_string_append (searches,
+ nm_setting_ip4_config_get_dns_search
+ (s_ip4, i));
+ }
+ ifnet_set_data (conn_name, "dns_search", searches->str);
+ g_string_free (searches, TRUE);
+ } else
+ ifnet_set_data (conn_name, "dns_search", NULL);
+ /* FIXME Will be implemented when configuration supports it
+ if (!strcmp(value, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
+ value = nm_setting_ip4_config_get_dhcp_hostname(s_ip4);
+ if (value)
+ ifnet_set_data(conn_name, "DHCP_HOSTNAME", value,
+ FALSE);
+
+ value = nm_setting_ip4_config_get_dhcp_client_id(s_ip4);
+ if (value)
+ ifnet_set_data(conn_name, "DHCP_CLIENT_ID", value,
+ FALSE);
+ }
+ */
+
+ /* Static routes */
+ num = nm_setting_ip4_config_get_num_routes (s_ip4);
+ if (num > 0) {
+ for (i = 0; i < num; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ NMIP4Route *route;
+ guint32 ip;
+
+ route = nm_setting_ip4_config_get_route (s_ip4, i);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_route_get_dest (route);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0],
+ sizeof (buf));
+ g_string_append_printf (routes, "\"%s", buf);
+
+ tmp =
+ g_strdup_printf ("%u",
+ nm_ip4_route_get_prefix (route));
+ g_string_append_printf (routes, "/%s via ", tmp);
+ g_free (tmp);
+
+ memset (buf, 0, sizeof (buf));
+ ip = nm_ip4_route_get_next_hop (route);
+ inet_ntop (AF_INET, (const void *) &ip, &buf[0],
+ sizeof (buf));
+ g_string_append_printf (routes, "%s\" ", buf);
+ }
+ }
+ if (routes->len > 0)
+ ifnet_set_data (conn_name, "routes", routes->str);
+ else
+ ifnet_set_data (conn_name, "routes", NULL);
+ g_string_free (routes, TRUE);
+
+ success = TRUE;
+
+ return success;
+}
+
+static gboolean
+write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **error)
+{
+ char dest[INET6_ADDRSTRLEN + 1];
+ char next_hop[INET6_ADDRSTRLEN + 1];
+ NMIP6Route *route;
+ const struct in6_addr *ip;
+ guint32 prefix;
+ guint32 i, num;
+ GString *routes_string;
+ const char *old_routes;
+
+ g_return_val_if_fail (s_ip6 != NULL, FALSE);
+ num = nm_setting_ip6_config_get_num_routes (s_ip6);
+ if (num == 0) {
+ return TRUE;
+ }
+
+ old_routes = ifnet_get_data (conn_name, "routes");
+ routes_string = g_string_new (old_routes);
+ if (old_routes)
+ g_string_append (routes_string, "\" ");
+ for (i = 0; i < num; i++) {
+ route = nm_setting_ip6_config_get_route (s_ip6, i);
+
+ memset (dest, 0, sizeof (dest));
+ ip = nm_ip6_route_get_dest (route);
+ inet_ntop (AF_INET6, (const void *) ip, &dest[0],
+ sizeof (dest));
+
+ prefix = nm_ip6_route_get_prefix (route);
+
+ memset (next_hop, 0, sizeof (next_hop));
+ ip = nm_ip6_route_get_next_hop (route);
+ inet_ntop (AF_INET6, (const void *) ip, &next_hop[0],
+ sizeof (next_hop));
+
+ g_string_append_printf (routes_string, "\"%s/%u via %s\" ",
+ dest, prefix, next_hop);
+ }
+ if (num > 0)
+ ifnet_set_data (conn_name, "routes", routes_string->str);
+ g_string_free (routes_string, TRUE);
+
+ return TRUE;
+}
+
+static gboolean
+write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error)
+{
+ NMSettingIP6Config *s_ip6;
+ const char *value;
+ char *prefix;
+ guint32 i, num;
+ GString *searches;
+ char buf[INET6_ADDRSTRLEN + 1];
+ NMIP6Address *addr;
+ const struct in6_addr *ip;
+
+ s_ip6 =
+ (NMSettingIP6Config *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_IP6_CONFIG);
+ if (!s_ip6) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ return FALSE;
+ }
+
+ value = nm_setting_ip6_config_get_method (s_ip6);
+ g_assert (value);
+ if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
+ ifnet_set_data (conn_name, "enable_ipv6", "false");
+ return TRUE;
+ } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ /* nothing to do now */
+ } else {
+ // if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
+ const char *config = ifnet_get_data (conn_name, "config");
+ gchar *tmp;
+
+ if (!config)
+ tmp = g_strdup_printf ("dhcp6");
+ else
+ tmp = g_strdup_printf ("%s\" \"dhcp6\"", config);
+ ifnet_set_data (conn_name, "config", tmp);
+ g_free (tmp);
+ }
+ /* else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
+ } else if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
+ } */
+
+ /* Remember to set IPv6 enabled */
+ ifnet_set_data (conn_name, "enable_ipv6", "true");
+
+ if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
+ const char *config = ifnet_get_data (conn_name, "config");
+ gchar *tmp;
+ GString *ip_str;
+
+ if (!config)
+ config = "";
+ num = nm_setting_ip6_config_get_num_addresses (s_ip6);
+
+ /* IPv6 addresses */
+ ip_str = g_string_new (NULL);
+ for (i = 0; i < num; i++) {
+ addr = nm_setting_ip6_config_get_address (s_ip6, i);
+ ip = nm_ip6_address_get_address (addr);
+ prefix =
+ g_strdup_printf ("%u",
+ nm_ip6_address_get_prefix (addr));
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET6, (const void *) ip, buf,
+ sizeof (buf));
+ g_string_append_printf (ip_str, "\"%s/", buf);
+ g_string_append_printf (ip_str, "%s\" ", prefix);
+ g_free (prefix);
+ }
+ tmp = g_strdup_printf ("%s\" %s", config, ip_str->str);
+ ifnet_set_data (conn_name, "config", tmp);
+ g_free (tmp);
+ g_string_free (ip_str, TRUE);
+ }
+
+ /* DNS Servers */
+ num = nm_setting_ip6_config_get_num_dns (s_ip6);
+ if (num > 0) {
+ const char *dns_servers = ifnet_get_data (conn_name, "dns_servers");
+ gchar *tmp;
+ GString *dns_string = g_string_new (NULL);
+
+ if (!dns_servers)
+ dns_servers = "";
+ for (i = 0; i < num; i++) {
+ ip = nm_setting_ip6_config_get_dns (s_ip6, i);
+
+ memset (buf, 0, sizeof (buf));
+ inet_ntop (AF_INET6, (const void *) ip, buf,
+ sizeof (buf));
+ if (!strstr (dns_servers, buf))
+ g_string_append_printf (dns_string, "%s ", buf);
+ }
+ tmp = g_strdup_printf ("%s %s", dns_servers, dns_string->str);
+ ifnet_set_data (conn_name, "dns_servers", tmp);
+ g_free (tmp);
+ g_string_free (dns_string, TRUE);
+
+ } else
+ /* DNS Searches */
+ num = nm_setting_ip6_config_get_num_dns_searches (s_ip6);
+ if (num > 0) {
+ const char *ip4_domains;
+
+ ip4_domains = ifnet_get_data (conn_name, "dns_search");
+ if (!ip4_domains)
+ ip4_domains = "";
+ searches = g_string_new (ip4_domains);
+ for (i = 0; i < num; i++) {
+ const gchar *search = NULL;
+
+ search =
+ nm_setting_ip6_config_get_dns_search (s_ip6, i);
+ if (search && !strstr (searches->str, search)) {
+ if (searches->len > 0)
+ g_string_append_c (searches, ' ');
+ g_string_append (searches, search);
+ }
+ }
+ ifnet_set_data (conn_name, "dns_search", searches->str);
+ g_string_free (searches, TRUE);
+ }
+
+ write_route6_file (s_ip6, conn_name, error);
+ if (error && *error)
+ return FALSE;
+ return TRUE;
+}
+
+static gboolean
+write_pppoe_setting (const char *conn_name, NMSettingPPPOE * s_pppoe)
+{
+ const gchar *value;
+
+ value = nm_setting_pppoe_get_username (s_pppoe);
+ if (!value) {
+ return FALSE;
+ }
+ ifnet_set_data (conn_name, "username", (gchar *) value);
+
+ value = nm_setting_pppoe_get_password (s_pppoe);
+ /* password could be NULL here */
+ if (value) {
+ ifnet_set_data (conn_name, "password", (gchar *) value);
+ }
+ return TRUE;
+}
+
+gboolean
+ifnet_update_parsers_by_connection (NMConnection *connection,
+ const char *conn_name,
+ const char *config_file,
+ const char *wpa_file,
+ gchar **out_new_name,
+ GError **error)
+{
+ NMSettingConnection *s_con;
+ NMSettingIP6Config *s_ip6;
+ gboolean success = FALSE;
+ const char *type;
+ gboolean no_8021x = FALSE;
+ gboolean wired = FALSE, pppoe = TRUE;
+ const char *new_name = NULL;
+
+ s_con =
+ NM_SETTING_CONNECTION (nm_connection_get_setting
+ (connection, NM_TYPE_SETTING_CONNECTION));
+ if (!s_con) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing '%s' setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ return FALSE;
+ }
+
+
+ type = nm_setting_connection_get_connection_type (s_con);
+ if (!type) {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Missing connection type!");
+ goto out;
+ }
+
+ if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
+ /* Writing wired setting */
+ if (!write_wired_setting (connection, conn_name, error))
+ goto out;
+ wired = TRUE;
+ no_8021x = TRUE;
+ } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) {
+ /* Writing wireless setting */
+ if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error))
+ goto out;
+ } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) {
+ NMSettingPPPOE *s_pppoe;
+
+ /* Writing pppoe setting */
+ s_pppoe = NM_SETTING_PPPOE (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE));
+ if (!write_pppoe_setting (conn_name, s_pppoe))
+ goto out;
+ pppoe = TRUE;
+ wired = TRUE;
+ no_8021x = TRUE;
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Can't write connection type '%s'", type);
+ goto out;
+ }
+
+ /* connection name may have been updated; use it when writing out
+ * the rest of the settings.
+ */
+ if (new_name)
+ conn_name = new_name;
+
+ //FIXME wired connection doesn't support 8021x now
+ if (!no_8021x) {
+ if (!write_8021x_setting (connection, conn_name, wired, error))
+ goto out;
+ }
+
+ /* IPv4 Setting */
+ if (!write_ip4_setting (connection, conn_name, error))
+ goto out;
+
+ s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
+ if (s_ip6) {
+ /* IPv6 Setting */
+ if (!write_ip6_setting (connection, conn_name, error))
+ goto out;
+ }
+
+ /* Connection Setting */
+ write_connection_setting (s_con, conn_name);
+
+ /* connection id will be displayed in nm-applet */
+ update_connection_id (connection, conn_name);
+
+ success = ifnet_flush_to_file (config_file);
+ if (success)
+ wpa_flush_to_file (wpa_file);
+
+ if (out_new_name)
+ *out_new_name = g_strdup (conn_name);
+
+out:
+ return success;
+}
+
+gboolean
+ifnet_delete_connection_in_parsers (const char *conn_name,
+ const char *config_file,
+ const char *wpa_file)
+{
+ gboolean result = FALSE;
+
+ ifnet_delete_network (conn_name);
+ result = ifnet_flush_to_file (config_file);
+ if (result) {
+ /* connection may not have security information
+ * so simply ignore the return value*/
+ wpa_delete_security (conn_name);
+ wpa_flush_to_file (wpa_file);
+ }
+
+ return result;
+}
+
+/* get the available wired name(eth*). */
+static gchar *
+get_wired_name ()
+{
+ int i = 0;
+
+ for (; i < 256; i++) {
+ gchar *conn_name = g_strdup_printf ("eth%d", i);
+
+ if (!ifnet_has_network (conn_name)) {
+ return conn_name;
+ } else
+ g_free (conn_name);
+ }
+ return NULL;
+}
+
+/* get the available pppoe name(ppp*). */
+static gchar *
+get_ppp_name ()
+{
+ int i = 0;
+
+ for (; i < 256; i++) {
+ gchar *conn_name = g_strdup_printf ("ppp%d", i);
+
+ if (!ifnet_has_network (conn_name)) {
+ return conn_name;
+ } else
+ g_free (conn_name);
+ }
+ return NULL;
+}
+
+/* get wireless ssid */
+static gchar *
+get_wireless_name (NMConnection * connection)
+{
+ NMSettingWireless *s_wireless;
+ const GByteArray *ssid;
+ gboolean hex_ssid = FALSE;
+ gchar *result = NULL;
+ char buf[33];
+ int i = 0;
+
+ s_wireless =
+ (NMSettingWireless *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_WIRELESS);
+ if (!s_wireless)
+ return NULL;
+
+ ssid = nm_setting_wireless_get_ssid (s_wireless);
+ if (!ssid->len || ssid->len > 32) {
+ return NULL;
+ }
+
+ for (i = 0; i < ssid->len; i++) {
+ if (!isprint (ssid->data[i])) {
+ hex_ssid = TRUE;
+ break;
+ }
+ }
+
+ if (hex_ssid) {
+ GString *str;
+
+ str = g_string_sized_new (ssid->len * 2 + 3);
+ g_string_append (str, "0x");
+ for (i = 0; i < ssid->len; i++)
+ g_string_append_printf (str, "%02X", ssid->data[i]);
+ result = g_strdup (str->str);
+ g_string_free (str, TRUE);
+ } else {
+ memset (buf, 0, sizeof (buf));
+ memcpy (buf, ssid->data, ssid->len);
+ result = g_strdup_printf ("%s", buf);
+ g_strstrip (result);
+ }
+
+ return result;
+}
+
+char *
+ifnet_add_new_connection (NMConnection *connection,
+ const char *config_file,
+ const char *wpa_file,
+ GError **error)
+{
+ NMSettingConnection *s_con;
+ gboolean success = FALSE;
+ const char *type;
+ gchar *new_type, *new_name = NULL;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+ type = nm_setting_connection_get_connection_type (s_con);
+ g_assert (type);
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding %s connection", type);
+
+ /* get name and type
+ * Wireless type: wireless
+ * Wired type: wired
+ * PPPoE type: ppp*/
+ if (!strcmp (type, NM_SETTING_WIRED_SETTING_NAME)) {
+ new_name = get_wired_name ();
+ if (!new_name)
+ goto out;
+ new_type = "wired";
+ } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) {
+ new_name = get_wireless_name (connection);
+ new_type = "wireless";
+ } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) {
+ new_name = get_ppp_name ();
+ if (!new_name)
+ goto out;
+ new_type = "ppp";
+ } else {
+ g_set_error (error, ifnet_plugin_error_quark (), 0,
+ "Can't write connection type '%s'", type);
+ goto out;
+ }
+
+ if (ifnet_add_network (new_name, new_type)) {
+ success = ifnet_update_parsers_by_connection (connection,
+ new_name,
+ config_file,
+ wpa_file,
+ NULL,
+ error);
+ }
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Added new connection: %s, result: %s",
+ new_name, success ? "success" : "fail");
+
+out:
+ if (!success)
+ g_free (new_name);
+ return success ? new_name : NULL;
+}
diff --git a/src/settings/plugins/ifnet/connection_parser.h b/src/settings/plugins/ifnet/connection_parser.h
new file mode 100644
index 000000000..b617b6051
--- /dev/null
+++ b/src/settings/plugins/ifnet/connection_parser.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef _CONNECTION_PARSER_H
+#define _CONNECTION_PARSER_H
+#include <nm-connection.h>
+#include "net_parser.h"
+
+NMConnection *ifnet_update_connection_from_config_block (const char *conn_name,
+ GError **error);
+
+/* nm_conn_name is used to update nm_ifnet_connection's priv data */
+gboolean ifnet_update_parsers_by_connection (NMConnection *connection,
+ const char *conn_name,
+ const char *config_file,
+ const char *wpa_file,
+ gchar **out_new_name,
+ GError **error);
+
+gboolean ifnet_delete_connection_in_parsers (const char *conn_name,
+ const char *config_file,
+ const char *wpa_file);
+
+char * ifnet_add_new_connection (NMConnection *connection,
+ const char *config_file,
+ const char *wpa_file,
+ GError ** error);
+#endif
diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c
new file mode 100644
index 000000000..a48103db8
--- /dev/null
+++ b/src/settings/plugins/ifnet/net_parser.c
@@ -0,0 +1,639 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <string.h>
+#include <nm-system-config-interface.h>
+#include <stdio.h>
+#include "net_parser.h"
+#include "net_utils.h"
+
+/* Save all the connection information */
+static GHashTable *conn_table;
+
+/* Save global settings which are used for writing*/
+static GHashTable *global_settings_table;
+
+/* Save functions */
+static GList *functions_list;
+
+/* Used to decide whether to write changes to file*/
+static gboolean net_parser_data_changed = FALSE;
+
+static GHashTable *
+add_new_connection_config (const gchar * type, const gchar * name)
+{
+ GHashTable *new_conn;
+ gchar *new_name;
+
+ if (!name)
+ return NULL;
+
+ /* Return existing connection */
+ if ((new_conn = g_hash_table_lookup (conn_table, name)) != NULL)
+ return new_conn;
+ new_conn = g_hash_table_new (g_str_hash, g_str_equal);
+ new_name = g_strdup (name);
+ g_hash_table_insert (new_conn, g_strdup ("name"), new_name);
+ g_hash_table_insert (new_conn, g_strdup ("type"), g_strdup (type));
+ g_hash_table_insert (conn_table, new_name, new_conn);
+ return new_conn;
+}
+
+gboolean
+ifnet_add_network (const char *name, const char *type)
+{
+ if (ifnet_has_network (name))
+ return TRUE;
+ if (add_new_connection_config (type, name)) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding network for %s", name);
+ net_parser_data_changed = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+ifnet_has_network (const char *conn_name)
+{
+ return g_hash_table_lookup (conn_table, conn_name) != NULL;
+}
+
+static GHashTable *
+get_connection_config (const char *name)
+{
+ return g_hash_table_lookup (conn_table, name);
+}
+
+/* Ignored name won't be treated as wireless ssid */
+static gchar *ignore_name[] = {
+ "vlan", "bond", "atm", "ath", "ippp", "vpn", "tap", "tun", "1",
+ "br", "nas", "6to4", "timeout", "kvm", "force", NULL
+};
+
+static gboolean
+ignore_connection_name (const char *name)
+{
+ gboolean result = FALSE;
+ guint i = 0;
+
+ /* check ignore_name list */
+ while (ignore_name[i] != NULL) {
+ if (g_ascii_strncasecmp
+ (name, ignore_name[i], strlen (ignore_name[i])) == 0) {
+ return TRUE;
+ }
+ i++;
+ }
+ /* Ignore mac address based configuration */
+ if (strlen (name) == 12 && is_hex (name))
+ result = TRUE;
+ return result;
+
+}
+
+static gboolean
+is_global_setting (char *key)
+{
+ static gchar *global_settings[] = { "wpa_supplicant_", NULL };
+ int i;
+
+ for (i = 0; global_settings[i] != NULL; i++) {
+ if (strstr (key, global_settings[i]))
+ return 1;
+ }
+ return 0;
+}
+
+/* Parse a complete line */
+/* Connection type is determined here */
+static void
+init_block_by_line (gchar * buf)
+{
+ gchar **key_value;
+ gchar *pos;
+ gchar *data;
+ gchar *tmp;
+ GHashTable *conn;
+
+ key_value = g_strsplit (buf, "=", 2);
+ if (g_strv_length (key_value) != 2) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle this line: %s\n",
+ buf);
+ g_strfreev (key_value);
+ return;
+ }
+ pos = g_strrstr (key_value[0], "_");
+ if (pos == NULL || is_global_setting (key_value[0])) {
+ /* global data */
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "global:%s-%s\n", key_value[0],
+ key_value[1]);
+ g_hash_table_insert (global_settings_table,
+ g_strdup (key_value[0]),
+ g_strdup (key_value[1]));
+ g_strfreev (key_value);
+ return;
+ }
+ *pos++ = '\0';
+ if ((conn = get_connection_config (pos)) == NULL) {
+ if (g_ascii_strncasecmp (pos, "eth", 3) == 0
+ && strlen (pos) == 4)
+ /* wired connection */
+ conn = add_new_connection_config ("wired", pos);
+ else if (g_ascii_strncasecmp (pos, "ppp", 3) == 0
+ && strlen (pos) == 4)
+ /* pppoe connection */
+ conn = add_new_connection_config ("ppp", pos);
+ else if (ignore_connection_name (pos)) {
+ /* ignored connection */
+ conn = add_new_connection_config ("ignore", pos);
+ } else
+ /* wireless connection */
+ conn = add_new_connection_config ("wireless", pos);
+ }
+ data = g_strdup (key_value[1]);
+ tmp = strip_string (data, '(');
+ tmp = strip_string (tmp, ')');
+ strip_string (tmp, '"');
+ strip_string (tmp, '\'');
+ if (conn)
+ g_hash_table_insert (conn, g_strdup (key_value[0]),
+ g_strdup (tmp));
+ g_free (data);
+ g_strfreev (key_value);
+}
+
+static void
+destroy_connection_config (GHashTable * conn)
+{
+ gpointer key, value;
+ GHashTableIter iter;
+
+ g_hash_table_iter_init (&iter, conn);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_free (key);
+ g_free (value);
+ }
+
+ g_hash_table_destroy (conn);
+}
+
+// read settings from /etc/NetworkManager/nm-system-settings.conf
+const char *
+ifnet_get_global_setting (const char *group, const char *key)
+{
+ GError *error = NULL;
+ GKeyFile *keyfile = g_key_file_new ();
+ gchar *result = NULL;
+
+ if (!g_key_file_load_from_file (keyfile,
+ IFNET_SYSTEM_SETTINGS_KEY_FILE,
+ G_KEY_FILE_NONE, &error)) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "loading system config file (%s) caused error: (%d) %s",
+ IFNET_SYSTEM_SETTINGS_KEY_FILE,
+ error ? error->code : -1, error
+ && error->message ? error->message : "(unknown)");
+ } else {
+ result = g_key_file_get_string (keyfile, group, key, &error);
+ }
+ g_key_file_free (keyfile);
+ return result;
+}
+
+static void
+strip_function (GIOChannel * channel, gchar * line)
+{
+
+ int counter = 0;
+ gchar *p, *tmp;
+ gboolean begin = FALSE;
+ GString *function_str = g_string_new (line);
+
+ g_string_append (function_str, "\n");
+ while (1) {
+ p = line;
+ while (*p != '\0') {
+ if (*p == '{') {
+ counter++;
+ begin = TRUE;
+ } else if (*p == '}')
+ counter--;
+ p++;
+ }
+ if (begin && counter == 0) {
+ g_free (line);
+ goto done;
+ }
+ while (1) {
+ g_free (line);
+ if (g_io_channel_read_line
+ (channel, &line, NULL, NULL,
+ NULL) == G_IO_STATUS_EOF)
+ goto done;
+ g_string_append (function_str, line);
+ tmp = g_strdup (line);
+ g_strstrip (tmp);
+ if (tmp[0] != '#' && tmp[0] != '\0') {
+ g_free (tmp);
+ break;
+ } else
+ g_free (tmp);
+ }
+ }
+done:
+ functions_list =
+ g_list_append (functions_list, g_strdup (function_str->str));
+ g_string_free (function_str, TRUE);
+}
+
+static gboolean
+is_function (gchar * line)
+{
+ static gchar *func_names[] =
+ { "preup", "predown", "postup", "postdown", "failup", "faildown",
+ NULL,
+ };
+ int i;
+
+ for (i = 0; func_names[i]; i++) {
+ if (g_str_has_prefix (line, func_names[i])) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "Ignoring function: %s", func_names[i]);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+gboolean
+ifnet_init (gchar * config_file)
+{
+ GIOChannel *channel = NULL;
+ gchar *line;
+
+ /* Handle multiple lines with brackets */
+ gboolean complete = TRUE;
+
+ /* line buffer */
+ GString *buf;
+
+ net_parser_data_changed = FALSE;
+
+ conn_table = g_hash_table_new (g_str_hash, g_str_equal);
+ global_settings_table = g_hash_table_new (g_str_hash, g_str_equal);
+ functions_list = NULL;
+
+ if (g_file_test (config_file, G_FILE_TEST_IS_REGULAR))
+ channel = g_io_channel_new_file (config_file, "r", NULL);
+ if (channel == NULL) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Error: Can't open %s\n", config_file);
+ return FALSE;
+ }
+
+ buf = g_string_new (NULL);
+ while (g_io_channel_read_line
+ (channel, &line, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
+ g_strstrip (line);
+ /* convert multiple lines to a complete line and
+ * pass it to init_block_by_line() */
+ if (is_function (line)) {
+ strip_function (channel, line);
+ continue;
+ }
+ if (line[0] != '#' && line[0] != '\0') {
+ gchar *pos = NULL;
+
+ if (!complete) {
+ complete =
+ g_strrstr (line,
+ ")") == NULL ? FALSE : TRUE;
+ if ((pos = strchr (line, '#')) != NULL)
+ *pos = '\0';
+ g_strstrip (line);
+ if (line[0] != '\0') {
+ g_string_append_printf (buf,
+ " %s", line);
+ }
+ g_free (line);
+ if (!complete)
+ continue;
+ } else {
+ complete =
+ (g_strrstr (line, "(") != NULL
+ && g_strrstr (line, ")") != NULL)
+ || g_strrstr (line, "(") == NULL;
+ if ((pos = strchr (line, '#')) != NULL)
+ *pos = '\0';
+ g_strstrip (line);
+ if (line[0] != '\0')
+ g_string_append (buf, line);
+ g_free (line);
+ if (!complete)
+ continue;
+ }
+ init_block_by_line (buf->str);
+ g_string_free (buf, TRUE);
+ buf = g_string_new (NULL);
+ } else
+ /* Blank line or comment line */
+ g_free (line);
+ }
+
+ g_string_free (buf, TRUE);
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+ return TRUE;
+}
+
+const char *
+ifnet_get_data (const char *conn_name, const char *key)
+{
+ GHashTable *conn = g_hash_table_lookup (conn_table, conn_name);
+
+ if (conn)
+ return g_hash_table_lookup (conn, key);
+ return NULL;
+}
+
+void
+ifnet_set_data (const char *conn_name, const char *key, const char *value)
+{
+ gpointer old_key = NULL, old_value = NULL;
+ GHashTable *conn = g_hash_table_lookup (conn_table, conn_name);
+ gchar * stripped = NULL;
+
+ if (!conn) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "%s does not exsit!", conn_name);
+ return;
+ }
+ if (value){
+ stripped = g_strdup (value);
+ strip_string (stripped, '"');
+ }
+ /* Remove existing key value pair */
+ if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) {
+ if (stripped && !strcmp(old_value, stripped)){
+ g_free (stripped);
+ return;
+ }
+ g_hash_table_remove (conn, old_key);
+ g_free (old_key);
+ g_free (old_value);
+ } else if (!value)
+ return;
+ if (stripped)
+ g_hash_table_insert (conn, g_strdup (key), stripped);
+ net_parser_data_changed = TRUE;
+}
+
+// Remember to free return value
+const char *
+ifnet_get_global_data (const gchar * key)
+{
+ return g_hash_table_lookup (global_settings_table, key);
+}
+
+// Return names of legal connections
+GList *
+ifnet_get_connection_names (void)
+{
+ GList *names = g_hash_table_get_keys (conn_table);
+ GList *result = NULL;
+
+ while (names) {
+ if (!ignore_connection_name (names->data))
+ result = g_list_prepend (result, names->data);
+ names = names->next;
+ }
+ g_list_free (names);
+ return g_list_reverse (result);
+}
+
+/* format IP and route for writing */
+static void
+format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name)
+{
+ gchar **ipset;
+ guint length, i;
+ GString *formated_string = g_string_new (NULL);
+
+ strip_string (value, '"');
+ ipset = g_strsplit (value, "\" \"", 0);
+ length = g_strv_length (ipset);
+
+ //only one line
+ if (length < 2) {
+ *out_line =
+ g_strdup_printf ("%s_%s=( \"%s\" )\n", key, name, value);
+ goto done;
+ }
+ // Multiple lines
+ g_string_append_printf (formated_string, "%s_%s=(\n", key, name);
+ for (i = 0; i < length; i++)
+ g_string_append_printf (formated_string,
+ "\t\"%s\"\n", ipset[i]);
+ g_string_append (formated_string, ")\n");
+ *out_line = g_strdup (formated_string->str);
+done:
+ g_string_free (formated_string, TRUE);
+ g_strfreev (ipset);
+}
+
+gboolean
+ifnet_flush_to_file (const char *config_file)
+{
+ GIOChannel *channel;
+ GError **error = NULL;
+ gpointer key, value, name, network;
+ GHashTableIter iter, iter_network;
+ GList *list_iter;
+ gchar *out_line;
+ gsize bytes_written;
+ gboolean result = FALSE;
+
+ if (!net_parser_data_changed)
+ return TRUE;
+ if (!conn_table || !global_settings_table)
+ return FALSE;
+
+ channel = g_io_channel_new_file (config_file, "w", NULL);
+ if (!channel) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Can't open file %s for writing", config_file);
+ return FALSE;
+ }
+ g_hash_table_iter_init (&iter, global_settings_table);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file);
+ g_io_channel_write_chars (channel,
+ "#Generated by NetworkManager\n"
+ "###### Global Configuration ######\n",
+ -1, &bytes_written, error);
+ /* Writing global data */
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ out_line =
+ g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value);
+ g_io_channel_write_chars (channel, out_line, -1,
+ &bytes_written, error);
+ if (bytes_written == 0 || (error && *error))
+ break;
+ g_free (out_line);
+ }
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto done;
+ }
+
+ /* Writing connection data */
+ g_io_channel_write_chars (channel,
+ "\n###### Connection Configuration ######\n",
+ -1, &bytes_written, error);
+ g_hash_table_iter_init (&iter, conn_table);
+ while (g_hash_table_iter_next (&iter, &name, &network)) {
+ g_hash_table_iter_init (&iter_network, (GHashTable *) network);
+ g_io_channel_write_chars (channel,
+ "#----------------------------------\n",
+ -1, &bytes_written, error);
+
+ while (g_hash_table_iter_next (&iter_network, &key, &value)) {
+ if (!g_str_has_prefix ((gchar *) key, "name")
+ && !g_str_has_prefix ((gchar *) key, "type")) {
+ /* These keys contain brackets */
+ if (strcmp
+ ((gchar *) key,
+ "config") == 0
+ || strcmp ((gchar *) key,
+ "routes") == 0
+ || strcmp ((gchar *) key,
+ "pppd") == 0
+ || strcmp ((gchar *) key, "chat") == 0)
+ format_ips (value, &out_line, (gchar *)
+ key, (gchar *)
+ name);
+ else
+ out_line =
+ g_strdup_printf
+ ("%s_%s=\"%s\"\n",
+ (gchar *) key,
+ (gchar *) name, (gchar *) value);
+ g_io_channel_write_chars
+ (channel, out_line, -1,
+ &bytes_written, error);
+ if (bytes_written == 0 || (error && *error))
+ break;
+ g_free (out_line);
+ }
+ }
+ }
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto done;
+ }
+
+ /* Writing reserved functions */
+ if (functions_list) {
+ g_io_channel_write_chars (channel,
+ "\n###### Reserved Functions ######\n",
+ -1, &bytes_written, error);
+ /* Writing functions */
+ for (list_iter = functions_list; list_iter;
+ list_iter = g_list_next (list_iter)) {
+ out_line =
+ g_strdup_printf ("%s\n", (gchar *) list_iter->data);
+ g_io_channel_write_chars (channel, out_line, -1,
+ &bytes_written, error);
+ if (bytes_written == 0 || (error && *error))
+ break;
+ g_free (out_line);
+ }
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto done;
+ }
+ }
+
+ g_io_channel_flush (channel, error);
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Found error: %s", (*error)->message);
+ goto done;
+ }
+ result = TRUE;
+ net_parser_data_changed = FALSE;
+done:
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+ return result;
+}
+
+gboolean
+ifnet_delete_network (const char *conn_name)
+{
+ GHashTable *network = NULL;
+
+ g_return_val_if_fail (conn_table != NULL && conn_name != NULL, FALSE);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Deleting network for %s", conn_name);
+ network = g_hash_table_lookup (conn_table, conn_name);
+ if (!network)
+ return FALSE;
+ g_hash_table_remove (conn_table, conn_name);
+ destroy_connection_config (network);
+ net_parser_data_changed = TRUE;
+ return TRUE;
+}
+
+void
+ifnet_destroy (void)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+ GList *list_iter;
+
+ /* Destroy connection setting */
+ if (conn_table) {
+ g_hash_table_iter_init (&iter, conn_table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ destroy_connection_config ((GHashTable *)
+ value);
+ }
+ g_hash_table_destroy (conn_table);
+ conn_table = NULL;
+ }
+
+ /* Destroy global data */
+ if (global_settings_table) {
+ g_hash_table_iter_init (&iter, global_settings_table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_free (key);
+ g_free (value);
+ }
+ g_hash_table_destroy (global_settings_table);
+ global_settings_table = NULL;
+ }
+ for (list_iter = functions_list; list_iter;
+ list_iter = g_list_next (list_iter))
+ g_free (list_iter->data);
+ g_list_free (functions_list);
+}
diff --git a/src/settings/plugins/ifnet/net_parser.h b/src/settings/plugins/ifnet/net_parser.h
new file mode 100644
index 000000000..0411e939e
--- /dev/null
+++ b/src/settings/plugins/ifnet/net_parser.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef _NET_PARSER_H
+#define _NET_PARSER_H
+
+#include <glib.h>
+
+#define CONF_NET_FILE "/etc/conf.d/net"
+#define IFNET_SYSTEM_SETTINGS_KEY_FILE "/etc/NetworkManager/nm-system-settings.conf"
+#define IFNET_KEY_FILE_GROUP "ifnet"
+
+gboolean ifnet_init (gchar * config_file);
+void ifnet_destroy (void);
+
+/* Reader functions */
+GList *ifnet_get_connection_names (void);
+const char *ifnet_get_data (const char *conn_name, const char *key);
+const char *ifnet_get_global_data (const char *key);
+const char *ifnet_get_global_setting (const char *group, const char *key);
+gboolean ifnet_has_network (const char *conn_name);
+
+/* Writer functions */
+gboolean ifnet_flush_to_file (const char *config_file);
+void ifnet_set_data (const char *conn_name, const char *key, const char *value);
+gboolean ifnet_add_network (const char *name, const char *type);
+gboolean ifnet_delete_network (const char *conn_name);
+#endif
diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c
new file mode 100644
index 000000000..83f86ab50
--- /dev/null
+++ b/src/settings/plugins/ifnet/net_utils.c
@@ -0,0 +1,974 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <nm-utils.h>
+#include <nm-system-config-interface.h>
+#include "net_utils.h"
+#include "wpa_parser.h"
+#include "net_parser.h"
+
+/* emit heading and tailing blank space, tab, character t */
+gchar *
+strip_string (gchar * str, gchar t)
+{
+ gchar *ret = str;
+ gint length = 0;
+ guint i = 0;
+
+ while (ret[i] != '\0'
+ && (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) {
+ length++;
+ i++;
+ }
+ i = 0;
+ while (ret[i + length] != '\0') {
+ ret[i] = ret[i + length];
+ i++;
+ }
+ ret[i] = '\0';
+ length = strlen (ret);
+ while ((length - 1) >= 0
+ && (ret[length - 1] == ' ' || ret[length - 1] == '\n'
+ || ret[length - 1] == '\t' || ret[length - 1] == t))
+ length--;
+ ret[length] = '\0';
+ return ret;
+}
+
+gboolean
+is_hex (const char *value)
+{
+ const char *p = value;
+
+ if (!p)
+ return FALSE;
+ while (*p) {
+ if (!isxdigit (*p++))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+gboolean
+is_ascii (const char *value)
+{
+ const char *p = value;
+
+ while (*p) {
+ if (!isascii (*p++))
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+gboolean
+is_true (const char *str)
+{
+ if (!g_ascii_strcasecmp (str, "yes")
+ || !g_ascii_strcasecmp (str, "true"))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+hex2num (char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
+}
+
+static int
+hex2byte (const char *hex)
+{
+ int a, b;
+
+ a = hex2num (*hex++);
+ if (a < 0)
+ return -1;
+ b = hex2num (*hex++);
+ if (b < 0)
+ return -1;
+ return (a << 4) | b;
+}
+
+/* free return value by caller */
+gchar *
+utils_hexstr2bin (const gchar * hex, size_t len)
+{
+ size_t i;
+ int a;
+ const gchar *ipos = hex;
+ gchar *buf = NULL;
+ gchar *opos;
+
+ /* Length must be a multiple of 2 */
+ if ((len % 2) != 0)
+ return NULL;
+
+ opos = buf = g_malloc0 ((len / 2) + 1);
+ for (i = 0; i < len; i += 2) {
+ a = hex2byte (ipos);
+ if (a < 0) {
+ g_free (buf);
+ return NULL;
+ }
+ *opos++ = a;
+ ipos += 2;
+ }
+ return buf;
+}
+
+/* free return value by caller */
+gchar *
+utils_bin2hexstr (const gchar * bytes, int len, int final_len)
+{
+ static gchar hex_digits[] = "0123456789abcdef";
+ gchar *result;
+ int i;
+ gsize buflen = (len * 2) + 1;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */
+ if (final_len > -1)
+ g_return_val_if_fail (final_len < buflen, NULL);
+
+ result = g_malloc0 (buflen);
+ for (i = 0; i < len; i++) {
+ result[2 * i] = hex_digits[(bytes[i] >> 4) & 0xf];
+ result[2 * i + 1] = hex_digits[bytes[i] & 0xf];
+ }
+ /* Cut converted key off at the correct length for this cipher type */
+ if (final_len > -1)
+ result[final_len] = '\0';
+ else
+ result[buflen - 1] = '\0';
+
+ return result;
+}
+
+GQuark
+ifnet_plugin_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (G_UNLIKELY (error_quark == 0))
+ error_quark =
+ g_quark_from_static_string ("ifnet-plugin-error-quark");
+ return error_quark;
+}
+
+static char *
+find_default_gateway_str (char *str)
+{
+ char *tmp;
+
+ if ((tmp = strstr (str, "default via ")) != NULL) {
+ return tmp + strlen ("default via ");
+ } else if ((tmp = strstr (str, "default gw ")) != NULL) {
+ return tmp + strlen ("default gw ");
+ }
+ return NULL;
+}
+
+static char *
+find_gateway_str (char *str)
+{
+ char *tmp;
+
+ if ((tmp = strstr (str, "via ")) != NULL) {
+ return tmp + strlen ("via ");
+ } else if ((tmp = strstr (str, "gw ")) != NULL) {
+ return tmp + strlen ("gw ");
+ }
+ return NULL;
+}
+
+gboolean
+reload_parsers (void)
+{
+ ifnet_destroy ();
+ wpa_parser_destroy ();
+ if (!ifnet_init (CONF_NET_FILE))
+ return FALSE;
+ wpa_parser_init (WPA_SUPPLICANT_CONF);
+ return TRUE;
+}
+
+gchar *
+read_hostname (const char *path)
+{
+ gchar *contents = NULL, *result = NULL, *tmp;
+ gchar **all_lines = NULL;
+ guint line_num, i;
+
+ if (!g_file_get_contents (path, &contents, NULL, NULL))
+ return NULL;
+ all_lines = g_strsplit (contents, "\n", 0);
+ line_num = g_strv_length (all_lines);
+ for (i = 0; i < line_num; i++) {
+ g_strstrip (all_lines[i]);
+ if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
+ continue;
+ if (g_str_has_prefix (all_lines[i], "hostname")) {
+ tmp = strstr (all_lines[i], "=");
+ tmp++;
+ tmp = strip_string (tmp, '"');
+ result = g_strdup (tmp);
+ break;
+ }
+
+ }
+ g_strfreev (all_lines);
+ g_free (contents);
+ return result;
+}
+
+gboolean
+write_hostname (const gchar *hostname, const char *path)
+{
+ gboolean result;
+ char *contents;
+
+ contents = g_strdup_printf ("#Generated by NetworkManager\n"
+ "hostname=\"%s\"\n", hostname);
+ result = g_file_set_contents (path, contents, -1, NULL);
+ g_free (contents);
+ return result;
+}
+
+gboolean
+is_static_ip4 (const char *conn_name)
+{
+ const char *data = ifnet_get_data (conn_name, "config");
+ const char *dhcp6;
+
+ if (!data)
+ return FALSE;
+ if (!strcmp (data, "shared"))
+ return FALSE;
+ if (!strcmp (data, "autoip"))
+ return FALSE;
+ dhcp6 = strstr (data, "dhcp6");
+ if (dhcp6) {
+ gchar *dhcp4;
+
+ if (strstr (data, "dhcp "))
+ return FALSE;
+ dhcp4 = strstr (data, "dhcp");
+ if (!dhcp4)
+ return TRUE;
+ if (dhcp4[4] == '\0')
+ return FALSE;
+ return TRUE;
+ }
+ return strstr (data, "dhcp") == NULL ? TRUE : FALSE;
+}
+
+gboolean
+is_static_ip6 (const char *conn_name)
+{
+ const char *data = ifnet_get_data (conn_name, "config");
+
+ if (!data)
+ return TRUE;
+ return strstr (data, "dhcp6") == NULL ? TRUE : FALSE;
+}
+
+gboolean
+is_ip4_address (const char *in_address)
+{
+ const char *pattern =
+ "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$";
+ gchar *address = g_strdup (in_address);
+ gboolean result = FALSE;
+ gchar *tmp;
+ GRegex *regex = g_regex_new (pattern, 0, 0, NULL);
+ GMatchInfo *match_info;
+
+ if (!address)
+ goto done;
+ g_strstrip (address);
+ if ((tmp = strstr (address, "/")) != NULL)
+ *tmp = '\0';
+ if ((tmp = strstr (address, " ")) != NULL)
+ *tmp = '\0';
+ g_regex_match (regex, address, 0, &match_info);
+ result = g_match_info_matches (match_info);
+done:
+ if (match_info)
+ g_match_info_free (match_info);
+ g_regex_unref (regex);
+ g_free (address);
+ return result;
+}
+
+gboolean
+is_ip6_address (const char *in_address)
+{
+ struct in6_addr tmp_ip6_addr;
+ gchar *tmp, *address;
+ gboolean result = FALSE;
+
+ if (!in_address)
+ return FALSE;
+ address = g_strdup (in_address);
+ g_strstrip (address);
+ if ((tmp = strchr (address, '/')) != NULL)
+ *tmp = '\0';
+ if (inet_pton (AF_INET6, address, &tmp_ip6_addr))
+ result = TRUE;
+ g_free (address);
+ return result;
+
+}
+
+gboolean
+has_ip6_address (const char *conn_name)
+{
+ gchar **ipset;
+ guint length;
+ guint i;
+
+ g_return_val_if_fail (conn_name != NULL, FALSE);
+ ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+ length = g_strv_length (ipset);
+ for (i = 0; i < length; i++) {
+ if (!is_ip6_address (ipset[i]))
+ continue;
+ else {
+ g_strfreev (ipset);
+ return TRUE;
+ }
+
+ }
+ g_strfreev (ipset);
+ return FALSE;
+}
+
+gboolean
+has_default_route (const char *conn_name, gboolean (*check_fn) (const char *))
+{
+ char *routes = NULL, *end, *tmp;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (conn_name != NULL, FALSE);
+
+ routes = g_strdup (ifnet_get_data (conn_name, "routes"));
+ if (!routes)
+ return FALSE;
+ tmp = find_default_gateway_str (routes);
+ if (tmp) {
+ g_strstrip (tmp);
+ if ((end = strstr (tmp, "\"")) != NULL)
+ *end = '\0';
+ if (check_fn (tmp))
+ success = TRUE;
+ }
+
+ g_free (routes);
+ return success;
+}
+
+static ip_block *
+create_ip4_block (gchar * ip)
+{
+ ip_block *iblock = g_slice_new0 (ip_block);
+ struct in_addr tmp_ip4_addr;
+ int i;
+ guint length;
+ gchar **ip_mask;
+
+ /* prefix format */
+ if (strstr (ip, "/")) {
+ gchar *prefix;
+
+ ip_mask = g_strsplit (ip, "/", 0);
+ length = g_strv_length (ip_mask);
+ if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr))
+ goto error;
+ iblock->ip = tmp_ip4_addr.s_addr;
+ prefix = ip_mask[1];
+ i = 0;
+ while (i < length && isdigit (prefix[i]))
+ i++;
+ prefix[i] = '\0';
+ iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32)
+ atoi (ip_mask
+ [1]));
+ } else if (strstr (ip, "netmask")) {
+ ip_mask = g_strsplit (ip, " ", 0);
+ length = g_strv_length (ip_mask);
+ if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr))
+ goto error;
+ iblock->ip = tmp_ip4_addr.s_addr;
+ i = 0;
+ while (i < length && !strstr (ip_mask[++i], "netmask")) ;
+ while (i < length && ip_mask[++i][0] == '\0') ;
+ if (i >= length)
+ goto error;
+ if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr))
+ goto error;
+ iblock->netmask = tmp_ip4_addr.s_addr;
+ } else {
+ g_slice_free (ip_block, iblock);
+ if (!is_ip6_address (ip) && !strstr (ip, "dhcp"))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Can't handle ipv4 address: %s, missing netmask or prefix",
+ ip);
+ return NULL;
+ }
+ g_strfreev (ip_mask);
+ return iblock;
+error:
+ if (!is_ip6_address (ip))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 address: %s",
+ ip);
+ g_strfreev (ip_mask);
+ g_slice_free (ip_block, iblock);
+ return NULL;
+}
+
+static ip6_block *
+create_ip6_block (gchar * ip)
+{
+ ip6_block *iblock = g_slice_new0 (ip6_block);
+ gchar *dup_ip = g_strdup (ip);
+ struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr);
+ gchar *prefix = NULL;
+
+ if ((prefix = strstr (dup_ip, "/")) != NULL) {
+ *prefix = '\0';
+ prefix++;
+ }
+ if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) {
+ goto error;
+ }
+ iblock->ip = tmp_ip6_addr;
+ if (prefix) {
+ errno = 0;
+ iblock->prefix = strtol (prefix, NULL, 10);
+ if (errno || iblock->prefix <= 0 || iblock->prefix > 128) {
+ goto error;
+ }
+ } else
+ iblock->prefix = 64;
+ g_free (dup_ip);
+ return iblock;
+error:
+ if (!is_ip4_address (ip))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 address: %s",
+ ip);
+ g_slice_free (ip6_block, iblock);
+ g_slice_free (struct in6_addr, tmp_ip6_addr);
+
+ g_free (dup_ip);
+ return NULL;
+}
+
+static guint32
+get_ip4_gateway (gchar * gateway)
+{
+ gchar *tmp, *split;
+ struct in_addr tmp_ip4_addr;
+
+ if (!gateway)
+ return 0;
+ tmp = find_gateway_str (gateway);
+ if (!tmp) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Couldn't obtain gateway in \"%s\"", gateway);
+ return 0;
+ }
+ tmp = g_strdup (tmp);
+ strip_string (tmp, ' ');
+ strip_string (tmp, '"');
+ if ((split = strstr (tmp, "\"")) != NULL)
+ *split = '\0';
+ if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr))
+ goto error;
+ g_free (tmp);
+ return tmp_ip4_addr.s_addr;
+error:
+ if (!is_ip6_address (tmp))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 gateway: %s",
+ tmp);
+ g_free (tmp);
+ return 0;
+}
+
+static struct in6_addr *
+get_ip6_next_hop (gchar * next_hop)
+{
+ gchar *tmp;
+ struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr);
+
+ if (!next_hop)
+ return 0;
+ tmp = find_gateway_str (next_hop);
+ if (!tmp) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Couldn't obtain next_hop in \"%s\"", next_hop);
+ return 0;
+ }
+ tmp = g_strdup (tmp);
+ strip_string (tmp, ' ');
+ strip_string (tmp, '"');
+ g_strstrip (tmp);
+ if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr))
+ goto error;
+ g_free (tmp);
+ return tmp_ip6_addr;
+error:
+ if (!is_ip4_address (tmp))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Can't handle IPv6 next_hop: %s", tmp);
+ g_free (tmp);
+ g_slice_free (struct in6_addr, tmp_ip6_addr);
+
+ return NULL;
+}
+
+ip_block *
+convert_ip4_config_block (const char *conn_name)
+{
+ gchar **ipset;
+ guint length;
+ guint i;
+ gchar *ip;
+ guint32 def_gateway = 0;
+ const char *routes;
+ gchar *pos;
+ ip_block *start = NULL, *current = NULL, *iblock = NULL;
+ const char *pattern =
+ "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))";
+
+ g_return_val_if_fail (conn_name != NULL, NULL);
+
+ ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+ length = g_strv_length (ipset);
+
+ routes = ifnet_get_data (conn_name, "routes");
+ if (routes)
+ def_gateway = get_ip4_gateway (strstr (routes, "default"));
+
+ for (i = 0; i < length; i++) {
+ ip = ipset[i];
+ ip = strip_string (ip, '"');
+ //Handle ip like 192.168.4.{1..3}
+ if ((pos = strchr (ip, '{')) != NULL) {
+ gchar *ip_start, *ip_prefix;
+ gchar *begin_str, *end_str;
+ int begin, end, j;
+ GRegex *regex;
+ GMatchInfo *match_info;
+
+ regex = g_regex_new (pattern, 0, 0, NULL);
+ g_regex_match (regex, ip, 0, &match_info);
+ g_regex_unref (regex);
+
+ if (!g_match_info_matches (match_info)) {
+ g_match_info_free (match_info);
+ continue;
+ }
+ begin_str = g_match_info_fetch (match_info, 3);
+ end_str = g_match_info_fetch (match_info, 4);
+ begin = atoi (begin_str);
+ end = atoi (end_str);
+ ip_start = g_match_info_fetch (match_info, 2);
+ ip_prefix = g_match_info_fetch (match_info, 5);
+ if (end < begin || begin < 1 || end > 254) {
+ g_match_info_free (match_info);
+ continue;
+ }
+
+ for (j = begin; j <= end; j++) {
+ char suf[4];
+ gchar *newip;
+
+ sprintf (suf, "%d", j);
+ newip =
+ g_strconcat (ip_start, suf, ip_prefix,
+ NULL);
+ iblock = create_ip4_block (newip);
+ if (iblock == NULL) {
+ g_free (newip);
+ continue;
+ }
+ if (!iblock->gateway && def_gateway != 0)
+ iblock->gateway = def_gateway;
+ if (start == NULL)
+ start = current = iblock;
+ else {
+ current->next = iblock;
+ current = iblock;
+ }
+ g_free (newip);
+ }
+ g_free (begin_str);
+ g_free (end_str);
+ g_free (ip_start);
+ g_free (ip_prefix);
+ g_match_info_free (match_info);
+ } else {
+ iblock = create_ip4_block (ip);
+ if (iblock == NULL)
+ continue;
+ if (!iblock->gateway && def_gateway != 0)
+ iblock->gateway = def_gateway;
+ if (start == NULL)
+ start = current = iblock;
+ else {
+ current->next = iblock;
+ current = iblock;
+ }
+ }
+ }
+ g_strfreev (ipset);
+ return start;
+}
+
+ip6_block *
+convert_ip6_config_block (const char *conn_name)
+{
+ gchar **ipset;
+ guint length;
+ guint i;
+ gchar *ip;
+ ip6_block *start = NULL, *current = NULL, *iblock = NULL;
+
+ g_return_val_if_fail (conn_name != NULL, NULL);
+ ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0);
+ length = g_strv_length (ipset);
+ for (i = 0; i < length; i++) {
+ ip = ipset[i];
+ ip = strip_string (ip, '"');
+ iblock = create_ip6_block (ip);
+ if (iblock == NULL)
+ continue;
+ if (start == NULL)
+ start = current = iblock;
+ else {
+ current->next = iblock;
+ current = iblock;
+ }
+ }
+ g_strfreev (ipset);
+ return start;
+}
+
+ip_block *
+convert_ip4_routes_block (const char *conn_name)
+{
+ gchar **ipset;
+ guint length;
+ guint i;
+ gchar *ip;
+ const char *routes;
+ ip_block *start = NULL, *current = NULL, *iblock = NULL;
+
+ g_return_val_if_fail (conn_name != NULL, NULL);
+
+ routes = ifnet_get_data (conn_name, "routes");
+ if (!routes)
+ return NULL;
+ ipset = g_strsplit (routes, "\" \"", 0);
+ length = g_strv_length (ipset);
+ for (i = 0; i < length; i++) {
+ ip = ipset[i];
+ if (find_default_gateway_str (ip) || strstr (ip, "::")
+ || !find_gateway_str (ip))
+ continue;
+ ip = strip_string (ip, '"');
+ iblock = create_ip4_block (ip);
+ if (iblock == NULL)
+ continue;
+ iblock->gateway = get_ip4_gateway (ip);
+ if (start == NULL)
+ start = current = iblock;
+ else {
+ current->next = iblock;
+ current = iblock;
+ }
+ }
+ g_strfreev (ipset);
+ return start;
+}
+
+ip6_block *
+convert_ip6_routes_block (const char *conn_name)
+{
+ gchar **ipset;
+ guint length;
+ guint i;
+ gchar *ip, *tmp_addr;
+ const char *routes;
+ ip6_block *start = NULL, *current = NULL, *iblock = NULL;
+ struct in6_addr *tmp_ip6_addr;
+
+ g_return_val_if_fail (conn_name != NULL, NULL);
+ routes = ifnet_get_data (conn_name, "routes");
+ if (!routes)
+ return NULL;
+ ipset = g_strsplit (routes, "\" \"", 0);
+ length = g_strv_length (ipset);
+ for (i = 0; i < length; i++) {
+ ip = ipset[i];
+ ip = strip_string (ip, '"');
+ if (ip[0] == '\0')
+ continue;
+ if ((tmp_addr = find_default_gateway_str (ip)) != NULL) {
+ if (!is_ip6_address (tmp_addr))
+ continue;
+ else {
+ tmp_ip6_addr = g_slice_new0 (struct in6_addr);
+
+ if (inet_pton (AF_INET6, "::", tmp_ip6_addr)) {
+ iblock = g_slice_new0 (ip6_block);
+ iblock->ip = tmp_ip6_addr;
+ iblock->prefix = 128;
+ } else {
+ g_slice_free (struct in6_addr,
+ tmp_ip6_addr);
+ continue;
+ }
+ }
+ } else
+ iblock = create_ip6_block (ip);
+ if (iblock == NULL)
+ continue;
+ iblock->next_hop = get_ip6_next_hop (ip);
+ if (iblock->next_hop == NULL) {
+ destroy_ip6_block (iblock);
+ continue;
+ }
+ if (start == NULL)
+ start = current = iblock;
+ else {
+ current->next = iblock;
+ current = iblock;
+ }
+ }
+ g_strfreev (ipset);
+ return start;
+}
+
+void
+destroy_ip_block (ip_block * iblock)
+{
+ g_slice_free (ip_block, iblock);
+}
+
+void
+destroy_ip6_block (ip6_block * iblock)
+{
+ g_slice_free (struct in6_addr, iblock->ip);
+ g_slice_free (struct in6_addr, iblock->next_hop);
+
+ g_slice_free (ip6_block, iblock);
+}
+
+void
+set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name)
+{
+ const char *dns_servers;
+ gchar **server_list, *stripped;
+ guint length, i;
+ struct in_addr tmp_ip4_addr;
+ guint32 new_dns;
+
+ dns_servers = ifnet_get_data (conn_name, "dns_servers");
+ if (!dns_servers)
+ return;
+ stripped = g_strdup (dns_servers);
+ strip_string (stripped, '"');
+ server_list = g_strsplit (stripped, " ", 0);
+ g_free (stripped);
+
+ length = g_strv_length (server_list);
+ if (length)
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS,
+ TRUE, NULL);
+ for (i = 0; i < length; i++) {
+ g_strstrip (server_list[i]);
+ if (server_list[i][0] == '\0')
+ continue;
+ if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) {
+ if (!is_ip6_address (server_list[i]))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "ignored dns: %s\n",
+ server_list[i]);
+ continue;
+ }
+ new_dns = tmp_ip4_addr.s_addr;
+ if (new_dns && !nm_setting_ip4_config_add_dns (s_ip4, new_dns))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "warning: duplicate DNS server %s",
+ server_list[i]);
+ }
+ g_strfreev (server_list);
+}
+
+void
+set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name)
+{
+ const char *dns_servers;
+ gchar **server_list, *stripped;
+ guint length, i;
+ struct in6_addr tmp_ip6_addr;
+
+ dns_servers = ifnet_get_data (conn_name, "dns_servers");
+ if (!dns_servers)
+ return;
+
+ stripped = g_strdup (dns_servers);
+ strip_string (stripped, '"');
+ server_list = g_strsplit (stripped, " ", 0);
+ g_free (stripped);
+
+ length = g_strv_length (server_list);
+ if (length)
+ g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS,
+ TRUE, NULL);
+ for (i = 0; i < length; i++) {
+ g_strstrip (server_list[i]);
+ if (server_list[i][0] == '\0')
+ continue;
+ if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) {
+ if (is_ip6_address (server_list[i]))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "ignored dns: %s\n",
+ server_list[i]);
+ continue;
+ }
+ if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_ip6_addr)
+ && !nm_setting_ip6_config_add_dns (s_ip6, &tmp_ip6_addr))
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "warning: duplicate DNS server %s",
+ server_list[i]);
+ }
+ g_strfreev (server_list);
+}
+
+gboolean
+is_managed (const char *conn_name)
+{
+ gchar *config;
+
+ g_return_val_if_fail (conn_name != NULL, FALSE);
+ config = (gchar *) ifnet_get_data (conn_name, "managed");
+ if (!config)
+ return TRUE;
+ if (strcmp (config, "false") == 0)
+ return FALSE;
+ return TRUE;
+}
+
+void
+get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
+{
+ const char *dhcp_client;
+ const gchar *dhcpcd_conf = "/etc/dhcpcd.conf";
+ const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf";
+ gchar *line = NULL, *tmp = NULL, *contents = NULL;
+ gchar **all_lines;
+ guint line_num, i;
+
+ *hostname = NULL;
+ *client_id = NULL;
+ dhcp_client = ifnet_get_global_setting ("main", "dhcp");
+ if (dhcp_client) {
+ if (!strcmp (dhcp_client, "dhclient"))
+ g_file_get_contents (dhclient_conf, &contents, NULL,
+ NULL);
+ else if (!strcmp (dhcp_client, "dhcpcd"))
+ g_file_get_contents (dhcpcd_conf, &contents, NULL,
+ NULL);
+ } else {
+ if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR))
+ g_file_get_contents (dhclient_conf, &contents, NULL,
+ NULL);
+ else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR))
+ g_file_get_contents (dhcpcd_conf, &contents, NULL,
+ NULL);
+ }
+ if (!contents)
+ return;
+ all_lines = g_strsplit (contents, "\n", 0);
+ line_num = g_strv_length (all_lines);
+ for (i = 0; i < line_num; i++) {
+ line = all_lines[i];
+ // dhcpcd.conf
+ g_strstrip (line);
+ if (g_str_has_prefix (line, "hostname")) {
+ tmp = line + strlen ("hostname");
+ g_strstrip (tmp);
+ if (tmp[0] != '\0')
+ *hostname = g_strdup (tmp);
+ else
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "dhcpcd hostname not defined, ignoring");
+ } else if (g_str_has_prefix (line, "clientid")) {
+ tmp = line + strlen ("clientid");
+ g_strstrip (tmp);
+ if (tmp[0] != '\0')
+ *client_id = g_strdup (tmp);
+ else
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "dhcpcd clientid not defined, ignoring");
+ }
+ // dhclient.conf
+ else if ((tmp = strstr (line, "send host-name")) != NULL) {
+ tmp += strlen ("send host-name");
+ g_strstrip (tmp);
+ strip_string (tmp, ';');
+ strip_string (tmp, '"');
+ if (tmp[0] != '\0')
+ *hostname = g_strdup (tmp);
+ else
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "dhclient hostname not defined, ignoring");
+ } else if ((tmp = strstr (line, "send dhcp-client-identifier"))
+ != NULL) {
+ tmp += strlen ("send dhcp-client-identifier");
+ g_strstrip (tmp);
+ strip_string (tmp, ';');
+ if (tmp[0] != '\0')
+ *client_id = g_strdup (tmp);
+ else
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "dhclient clientid not defined, ignoring");
+ }
+ }
+ g_strfreev (all_lines);
+ g_free (contents);
+}
diff --git a/src/settings/plugins/ifnet/net_utils.h b/src/settings/plugins/ifnet/net_utils.h
new file mode 100644
index 000000000..42f8d6725
--- /dev/null
+++ b/src/settings/plugins/ifnet/net_utils.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef _IFNET_UTILS_H
+#define _IFNET_UTILS_H
+#define IFNET_PLUGIN_NAME "SCPlugin-Ifnet"
+#include <glib.h>
+#include <arpa/inet.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-ip4-config.h>
+#include "net_parser.h"
+#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address)
+#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address)
+
+typedef struct _ip_block {
+ guint32 ip;
+ guint32 netmask;
+ guint32 gateway;
+ struct _ip_block *next;
+} ip_block;
+
+typedef struct _ip6_block {
+ struct in6_addr *ip;
+ long int prefix;
+ struct in6_addr *next_hop;
+ struct _ip6_block *next;
+} ip6_block;
+
+gchar *read_hostname (const char *path);
+gboolean write_hostname (const char *hostname, const char *path);
+gboolean is_static_ip4 (const char *conn_name);
+gboolean is_static_ip6 (const char *conn_name);
+gboolean is_ip4_address (const char *in_address);
+gboolean is_ip6_address (const char *in_address);
+gboolean has_ip6_address (const char *conn_name);
+gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *));
+gboolean reload_parsers (void);
+
+ip_block *convert_ip4_config_block (const char *conn_name);
+ip6_block *convert_ip6_config_block (const char *conn_name);
+ip_block *convert_ip4_routes_block (const char *conn_name);
+ip6_block *convert_ip6_routes_block (const char *conn_name);
+void destroy_ip_block (ip_block * iblock);
+void destroy_ip6_block (ip6_block * iblock);
+
+void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, const char *conn_name);
+void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, const char *conn_name);
+
+gchar *strip_string (gchar *str, gchar t);
+gboolean is_managed (const char *conn_name);
+
+GQuark ifnet_plugin_error_quark (void);
+gchar *utils_hexstr2bin (const gchar * hex, size_t len);
+gchar *utils_bin2hexstr (const gchar * bytes, int len, int final_len);
+
+gboolean is_hex (const char *value);
+gboolean is_ascii (const char *value);
+gboolean is_true (const char *str);
+
+void get_dhcp_hostname_and_client_id (char **hostname, char **client_id);
+
+#endif
diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.c b/src/settings/plugins/ifnet/nm-ifnet-connection.c
new file mode 100644
index 000000000..8b7a153cc
--- /dev/null
+++ b/src/settings/plugins/ifnet/nm-ifnet-connection.c
@@ -0,0 +1,191 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <NetworkManager.h>
+#include <nm-utils.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-settings-connection.h>
+#include <nm-system-config-interface.h>
+#include <nm-settings-error.h>
+#include "nm-ifnet-connection.h"
+#include "connection_parser.h"
+#include "net_parser.h"
+#include "net_utils.h"
+#include "wpa_parser.h"
+#include "plugin.h"
+
+G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION)
+
+#define NM_IFNET_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionPrivate))
+enum {
+ PROP_ZERO,
+ PROP_CONN_NAME,
+ _PROP_END,
+};
+
+enum {
+ IFNET_SETUP_MONITORS,
+ IFNET_CANCEL_MONITORS,
+ IFNET_LAST_SIGNAL
+};
+
+static guint signals[IFNET_LAST_SIGNAL] = { 0 };
+
+typedef struct {
+ gchar *conn_name;
+ NMSystemConfigInterface *config;
+} NMIfnetConnectionPrivate;
+
+NMIfnetConnection *
+nm_ifnet_connection_new (const char *conn_name, NMConnection *source)
+{
+ NMConnection *tmp;
+ GObject *object;
+ GError *error = NULL;
+
+ g_return_val_if_fail (conn_name != NULL, NULL);
+
+ if (source)
+ tmp = g_object_ref (source);
+ else {
+ tmp = ifnet_update_connection_from_config_block (conn_name, &error);
+ if (!tmp){
+ g_error_free (error);
+ return NULL;
+ }
+ }
+
+ object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL);
+ if (!object) {
+ g_object_unref (tmp);
+ return NULL;
+ }
+
+ NM_IFNET_CONNECTION_GET_PRIVATE (object)->conn_name = g_strdup (conn_name);
+ nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, NULL);
+ g_object_unref (tmp);
+
+ return NM_IFNET_CONNECTION (object);
+}
+
+static void
+nm_ifnet_connection_init (NMIfnetConnection * connection)
+{
+}
+
+static void
+commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection);
+ gchar *new_name = NULL;
+
+ g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
+ if (!ifnet_update_parsers_by_connection (NM_CONNECTION (connection),
+ priv->conn_name,
+ CONF_NET_FILE,
+ WPA_SUPPLICANT_CONF,
+ &new_name,
+ &error)) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s", priv->conn_name);
+ reload_parsers ();
+ callback (connection, error, user_data);
+ g_error_free (error);
+ g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+ return;
+ }
+
+ g_free (priv->conn_name);
+ priv->conn_name = new_name;
+
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", priv->conn_name);
+
+ g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+}
+
+static void
+do_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection);
+
+ g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0);
+ if (!ifnet_delete_connection_in_parsers
+ (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF)) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to delete %s",
+ priv->conn_name);
+ reload_parsers ();
+ callback (connection, error, user_data);
+ g_error_free (error);
+ g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+ return;
+ }
+
+ NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data);
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s",
+ priv->conn_name);
+ g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0);
+}
+
+static void
+finalize (GObject * object)
+{
+ NMIfnetConnectionPrivate *priv =
+ NM_IFNET_CONNECTION_GET_PRIVATE (object);
+ g_return_if_fail (priv);
+
+ g_free (priv->conn_name);
+ G_OBJECT_CLASS (nm_ifnet_connection_parent_class)->finalize (object);
+}
+
+static void
+nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class);
+ NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class);
+
+ g_type_class_add_private (ifnet_connection_class,
+ sizeof (NMIfnetConnectionPrivate));
+
+ object_class->finalize = finalize;
+ settings_class->delete = do_delete;
+ settings_class->commit_changes = commit_changes;
+
+ signals[IFNET_SETUP_MONITORS] =
+ g_signal_new ("ifnet_setup_monitors",
+ G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[IFNET_CANCEL_MONITORS] =
+ g_signal_new ("ifnet_cancel_monitors",
+ G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+}
diff --git a/src/settings/plugins/ifnet/nm-ifnet-connection.h b/src/settings/plugins/ifnet/nm-ifnet-connection.h
new file mode 100644
index 000000000..9423f20d7
--- /dev/null
+++ b/src/settings/plugins/ifnet/nm-ifnet-connection.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef NM_IFNET_CONNECTION_H
+#define NM_IFNET_CONNECTION_H
+
+#include <nm-settings-connection.h>
+#include "net_parser.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ())
+#define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection))
+#define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
+#define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION))
+#define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFNET_CONNECTION))
+#define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass))
+
+typedef struct {
+ NMSettingsConnection parent;
+} NMIfnetConnection;
+
+typedef struct {
+ NMSettingsConnectionClass parent;
+} NMIfnetConnectionClass;
+
+GType nm_ifnet_connection_get_type (void);
+
+NMIfnetConnection *nm_ifnet_connection_new (const char *conn_name,
+ NMConnection *source);
+
+G_END_DECLS
+#endif /* NM_IFNET_CONNECTION_H */
diff --git a/src/settings/plugins/ifnet/plugin.c b/src/settings/plugins/ifnet/plugin.c
new file mode 100644
index 000000000..69b7bc803
--- /dev/null
+++ b/src/settings/plugins/ifnet/plugin.c
@@ -0,0 +1,541 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service (ifnet)
+ *
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <string.h>
+
+#include <gmodule.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <nm-utils.h>
+#include <nm-setting-connection.h>
+
+#include "NetworkManager.h"
+#include "nm-system-config-interface.h"
+#include "nm-ifnet-connection.h"
+
+#include "plugin.h"
+#include "net_utils.h"
+#include "net_parser.h"
+#include "wpa_parser.h"
+#include "connection_parser.h"
+
+#define IFNET_PLUGIN_NAME_PRINT "ifnet"
+#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix."
+#define IFNET_SYSTEM_HOSTNAME_FILE "/etc/conf.d/hostname"
+#define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE
+#define IFNET_KEY_FILE_KEY_MANAGED "managed"
+
+typedef struct {
+ GHashTable *config_connections;
+ gchar *hostname;
+ gboolean unmanaged_well_known;
+
+ GFileMonitor *hostname_monitor;
+ GFileMonitor *net_monitor;
+ GFileMonitor *wpa_monitor;
+
+} SCPluginIfnetPrivate;
+
+typedef void (*FileChangedFn) (gpointer user_data);
+
+typedef struct {
+ FileChangedFn callback;
+ gpointer user_data;
+} FileMonitorInfo;
+
+static void system_config_interface_init (NMSystemConfigInterface *class);
+
+static void reload_connections (gpointer config);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginIfnet, sc_plugin_ifnet, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, system_config_interface_init))
+#define SC_PLUGIN_IFNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetPrivate))
+/*
+static void
+ignore_cb(NMSettingsConnectionInterface * connection,
+ GError * error, gpointer user_data)
+{
+}
+*/
+static const char *
+get_hostname (NMSystemConfigInterface * config)
+{
+ return SC_PLUGIN_IFNET_GET_PRIVATE (config)->hostname;
+}
+
+static void
+update_system_hostname (gpointer config)
+{
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
+
+ if (priv->hostname)
+ g_free (priv->hostname);
+ priv->hostname = read_hostname (IFNET_SYSTEM_HOSTNAME_FILE);
+
+ g_object_notify (G_OBJECT (config),
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Hostname updated to: %s",
+ priv->hostname);
+}
+
+static void
+write_system_hostname (NMSystemConfigInterface * config,
+ const gchar * newhostname)
+{
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
+
+ g_return_if_fail (newhostname);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Write system hostname: %s",
+ newhostname);
+ if (write_hostname (newhostname, IFNET_SYSTEM_HOSTNAME_FILE)) {
+ g_free (priv->hostname);
+ priv->hostname = g_strdup (newhostname);
+ g_object_notify (G_OBJECT (config),
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+ } else
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Write system hostname: %s failed", newhostname);
+}
+
+static gboolean
+is_managed_plugin ()
+{
+ const char *result = NULL;
+
+ result = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED);
+ if (result)
+ return is_true (result);
+ return IFNET_MANAGE_WELL_KNOWN_DEFAULT;
+}
+
+static void
+file_changed (GFileMonitor * monitor,
+ GFile * file,
+ GFile * other_file,
+ GFileMonitorEvent event_type, gpointer user_data)
+{
+ FileMonitorInfo *info;
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ info = (FileMonitorInfo *) user_data;
+ info->callback (info->user_data);
+ break;
+ default:
+ break;
+ }
+}
+
+static GFileMonitor *
+monitor_file_changes (const char *filename,
+ FileChangedFn callback, gpointer user_data)
+{
+ GFile *file;
+ GFileMonitor *monitor;
+ FileMonitorInfo *info;
+ GError **error = NULL;
+
+ if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+ return NULL;
+ file = g_file_new_for_path (filename);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, error);
+ g_object_unref (file);
+
+ if (monitor) {
+ info = g_new0 (FileMonitorInfo, 1);
+ info->callback = callback;
+ info->user_data = user_data;
+ g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free,
+ info);
+ g_signal_connect (monitor, "changed", G_CALLBACK (file_changed),
+ info);
+ } else
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Monitoring %s failed, error: %s", filename,
+ error == NULL ? "nothing" : (*error)->message);
+
+ return monitor;
+}
+
+/* Callback for nm_settings_connection_replace_and_commit. Report any errors
+ * encountered when commiting connection settings updates. */
+static void
+commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused)
+{
+ if (error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, " error updating: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ } else {
+ NMSettingConnection *s_con;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection),
+ NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated",
+ nm_setting_connection_get_id (s_con));
+ }
+}
+
+static void
+setup_monitors (NMIfnetConnection * connection, gpointer user_data)
+{
+ SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data);
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
+
+ priv->hostname_monitor =
+ monitor_file_changes (IFNET_SYSTEM_HOSTNAME_FILE,
+ update_system_hostname, user_data);
+ priv->net_monitor =
+ monitor_file_changes (CONF_NET_FILE, reload_connections, user_data);
+ priv->wpa_monitor =
+ monitor_file_changes (WPA_SUPPLICANT_CONF, reload_connections,
+ user_data);
+}
+
+static void
+cancel_monitors (NMIfnetConnection * connection, gpointer user_data)
+{
+ SCPluginIfnet *self = SC_PLUGIN_IFNET (user_data);
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
+
+ if (priv->hostname_monitor) {
+ g_file_monitor_cancel (priv->hostname_monitor);
+ g_object_unref (priv->hostname_monitor);
+ }
+ if (priv->net_monitor) {
+ g_file_monitor_cancel (priv->net_monitor);
+ g_object_unref (priv->net_monitor);
+ }
+ if (priv->wpa_monitor) {
+ g_file_monitor_cancel (priv->wpa_monitor);
+ g_object_unref (priv->wpa_monitor);
+ }
+}
+
+static void
+reload_connections (gpointer config)
+{
+ SCPluginIfnet *self = SC_PLUGIN_IFNET (config);
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
+ GList *conn_names = NULL, *n_iter = NULL;
+
+ /* save names for removing unused connections */
+ GHashTable *new_conn_names = NULL;
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ if (priv->unmanaged_well_known)
+ return;
+
+ if (!reload_parsers ())
+ return;
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections");
+
+ conn_names = ifnet_get_connection_names ();
+ new_conn_names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+ for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) {
+ NMIfnetConnection *new;
+ NMIfnetConnection *old;
+ const char *conn_name = n_iter->data;
+
+ /* read the new connection */
+ new = nm_ifnet_connection_new (conn_name, NULL);
+ if (!new)
+ continue;
+
+ g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors",
+ G_CALLBACK (setup_monitors), config);
+ g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors",
+ G_CALLBACK (cancel_monitors), config);
+
+ old = g_hash_table_lookup (priv->config_connections, conn_name);
+ if (old && new) {
+ const char *auto_refresh;
+
+ auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh");
+ if (auto_refresh && is_true (auto_refresh)) {
+ if (!nm_connection_compare (NM_CONNECTION (old),
+ NM_CONNECTION (new),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name);
+
+ /* Remove and re-add to disconnect and reconnect with new settings */
+ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old));
+ g_hash_table_remove (priv->config_connections, conn_name);
+ g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new);
+ if (is_managed_plugin () && is_managed (conn_name))
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
+ }
+ } else {
+ /* Update existing connection with new settings */
+ nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (old),
+ NM_CONNECTION (new),
+ commit_cb, NULL);
+ g_object_unref (new);
+ }
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+ } else if (new) {
+ g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new);
+ if (is_managed_plugin () && is_managed (conn_name))
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
+ }
+ g_hash_table_insert (new_conn_names, (gpointer) conn_name, (gpointer) conn_name);
+ }
+
+ /* remove unused connections */
+ g_hash_table_iter_init (&iter, priv->config_connections);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (!g_hash_table_lookup (new_conn_names, key)) {
+ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (value));
+ g_hash_table_remove (priv->config_connections, key);
+ }
+ }
+ g_hash_table_destroy (new_conn_names);
+ g_list_free (conn_names);
+}
+
+static NMSettingsConnection *
+add_connection (NMSystemConfigInterface *config,
+ NMConnection *source,
+ GError **error)
+{
+ NMIfnetConnection *connection = NULL;
+ char *conn_name;
+
+ conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error);
+ if (conn_name)
+ connection = nm_ifnet_connection_new (conn_name, source);
+ reload_connections (config);
+ return connection ? NM_SETTINGS_CONNECTION (connection) : NULL;
+}
+
+static void
+check_unmanaged (gpointer key, gpointer data, gpointer user_data)
+{
+ GSList **list = (GSList **) user_data;
+ gchar *conn_name = (gchar *) key;
+ const char *unmanaged_spec;
+ GSList *iter;
+
+ if (is_managed (conn_name))
+ return;
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Checking unmanaged: %s", conn_name);
+ unmanaged_spec = ifnet_get_data (conn_name, "mac");
+ if (!unmanaged_spec)
+ return;
+
+ /* Just return if the unmanaged spec is already in the list */
+ for (iter = *list; iter; iter = g_slist_next (iter)) {
+ if (!strcmp ((char *) iter->data, unmanaged_spec))
+ return;
+ }
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Add unmanaged: %s", unmanaged_spec);
+ *list =
+ g_slist_prepend (*list, g_strdup_printf ("mac:%s", unmanaged_spec));
+}
+
+static GSList *
+get_unmanaged_specs (NMSystemConfigInterface * config)
+{
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
+ GSList *list = NULL;
+
+ g_return_val_if_fail (priv->config_connections != NULL, NULL);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "getting unmanaged specs...");
+ g_hash_table_foreach (priv->config_connections, check_unmanaged, &list);
+ return list;
+}
+
+static void
+SCPluginIfnet_init (NMSystemConfigInterface * config)
+{
+ SCPluginIfnet *self = SC_PLUGIN_IFNET (config);
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (self);
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initializing!");
+ if (!priv->config_connections)
+ priv->config_connections =
+ g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+ g_object_unref);
+ priv->unmanaged_well_known = !is_managed_plugin ();
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "management mode: %s",
+ priv->unmanaged_well_known ? "unmanaged" : "managed");
+ // GFileMonitor setup
+ setup_monitors (NULL, config);
+ reload_connections (config);
+ /* Read hostname */
+ update_system_hostname (self);
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Initialzation complete!");
+}
+
+static GSList *
+get_connections (NMSystemConfigInterface * config)
+{
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config);
+ GSList *connections = NULL;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) ... get_connections.",
+ GPOINTER_TO_UINT (config));
+ if (priv->unmanaged_well_known) {
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME,
+ "(%d) ... get_connections (managed=false): return empty list.",
+ GPOINTER_TO_UINT (config));
+ return NULL;
+ }
+
+ g_hash_table_iter_init (&iter, priv->config_connections);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ if (is_managed ((gchar *) key))
+ connections = g_slist_prepend (connections, value);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "(%d) connections count: %d",
+ GPOINTER_TO_UINT (config), g_slist_length (connections));
+ return connections;
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *class)
+{
+ class->init = SCPluginIfnet_init;
+ class->get_connections = get_connections;
+ class->get_unmanaged_specs = get_unmanaged_specs;
+ class->add_connection = add_connection;
+}
+
+static void
+sc_plugin_ifnet_init (SCPluginIfnet * plugin)
+{
+}
+
+static void
+get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object);
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, IFNET_PLUGIN_NAME_PRINT);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, IFNET_PLUGIN_INFO);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+ g_value_set_uint (value,
+ NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS
+ |
+ NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ g_value_set_string (value, get_hostname (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject * object, guint prop_id, const GValue * value,
+ GParamSpec * pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:{
+ const gchar *hostname = g_value_get_string (value);
+
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ write_system_hostname (NM_SYSTEM_CONFIG_INTERFACE
+ (object), hostname);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject * object)
+{
+ SCPluginIfnet *plugin = SC_PLUGIN_IFNET (object);
+ SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (plugin);
+
+ cancel_monitors (NULL, object);
+ if (priv->config_connections) {
+ g_hash_table_remove_all (priv->config_connections);
+ g_hash_table_destroy (priv->config_connections);
+ }
+
+ g_free (priv->hostname);
+ ifnet_destroy ();
+ wpa_parser_destroy ();
+ G_OBJECT_CLASS (sc_plugin_ifnet_parent_class)->dispose (object);
+}
+
+static void
+sc_plugin_ifnet_class_init (SCPluginIfnetClass * req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginIfnetPrivate));
+
+ object_class->dispose = dispose;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+ NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+ static SCPluginIfnet *singleton = NULL;
+
+ if (!singleton)
+ singleton
+ =
+ SC_PLUGIN_IFNET (g_object_new (SC_TYPE_PLUGIN_IFNET, NULL));
+ else
+ g_object_ref (singleton);
+ return G_OBJECT (singleton);
+}
diff --git a/src/settings/plugins/ifnet/plugin.h b/src/settings/plugins/ifnet/plugin.h
new file mode 100644
index 000000000..83099b63a
--- /dev/null
+++ b/src/settings/plugins/ifnet/plugin.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service (ifnet)
+ *
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define SC_TYPE_PLUGIN_IFNET (sc_plugin_ifnet_get_type ())
+#define SC_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnet))
+#define SC_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass))
+#define SC_IS_PLUGIN_IFNET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFNET))
+#define SC_IS_PLUGIN_IFNET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFNET))
+#define SC_PLUGIN_IFNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetClass))
+
+typedef struct _SCPluginIfnet SCPluginIfnet;
+typedef struct _SCPluginIfnetClass SCPluginIfnetClass;
+
+struct _SCPluginIfnet {
+ GObject parent;
+};
+
+struct _SCPluginIfnetClass {
+ GObjectClass parent;
+};
+
+GType sc_plugin_ifnet_get_type (void);
+#endif
diff --git a/src/settings/plugins/ifnet/tests/Makefile.am b/src/settings/plugins/ifnet/tests/Makefile.am
new file mode 100644
index 000000000..20a268052
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/Makefile.am
@@ -0,0 +1,18 @@
+INCLUDES=-I$(srcdir)/../ \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/settings
+TESTS = check_ifnet
+check_PROGRAMS = check_ifnet
+check_ifnet_SOURCES = test_all.c
+check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS)
+check_ifnet_LDADD = $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../lib-ifnet-io.la \
+ $(CHECK_LIBS) \
+ $(GLIB_LIBS)
+EXTRA_DIST = hostname \
+ net \
+ net.all \
+ nm-system-settings.conf \
+ wpa_supplicant.conf
diff --git a/src/settings/plugins/ifnet/tests/Makefile.in b/src/settings/plugins/ifnet/tests/Makefile.in
new file mode 100644
index 000000000..adb1816c7
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/Makefile.in
@@ -0,0 +1,716 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = check_ifnet$(EXEEXT)
+check_PROGRAMS = check_ifnet$(EXEEXT)
+subdir = src/settings/plugins/ifnet/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_check_ifnet_OBJECTS = check_ifnet-test_all.$(OBJEXT)
+check_ifnet_OBJECTS = $(am_check_ifnet_OBJECTS)
+am__DEPENDENCIES_1 =
+check_ifnet_DEPENDENCIES = $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../lib-ifnet-io.la $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(check_ifnet_SOURCES)
+DIST_SOURCES = $(check_ifnet_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = -I$(srcdir)/../ \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src/settings
+
+check_ifnet_SOURCES = test_all.c
+check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS)
+check_ifnet_LDADD = $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../lib-ifnet-io.la \
+ $(CHECK_LIBS) \
+ $(GLIB_LIBS)
+
+EXTRA_DIST = hostname \
+ net \
+ net.all \
+ nm-system-settings.conf \
+ wpa_supplicant.conf
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifnet/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+check_ifnet$(EXEEXT): $(check_ifnet_OBJECTS) $(check_ifnet_DEPENDENCIES)
+ @rm -f check_ifnet$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(check_ifnet_OBJECTS) $(check_ifnet_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_ifnet-test_all.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+check_ifnet-test_all.o: test_all.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT check_ifnet-test_all.o -MD -MP -MF $(DEPDIR)/check_ifnet-test_all.Tpo -c -o check_ifnet-test_all.o `test -f 'test_all.c' || echo '$(srcdir)/'`test_all.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_ifnet-test_all.Tpo $(DEPDIR)/check_ifnet-test_all.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_all.c' object='check_ifnet-test_all.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o check_ifnet-test_all.o `test -f 'test_all.c' || echo '$(srcdir)/'`test_all.c
+
+check_ifnet-test_all.obj: test_all.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT check_ifnet-test_all.obj -MD -MP -MF $(DEPDIR)/check_ifnet-test_all.Tpo -c -o check_ifnet-test_all.obj `if test -f 'test_all.c'; then $(CYGPATH_W) 'test_all.c'; else $(CYGPATH_W) '$(srcdir)/test_all.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_ifnet-test_all.Tpo $(DEPDIR)/check_ifnet-test_all.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_all.c' object='check_ifnet-test_all.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(check_ifnet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o check_ifnet-test_all.obj `if test -f 'test_all.c'; then $(CYGPATH_W) 'test_all.c'; else $(CYGPATH_W) '$(srcdir)/test_all.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifnet/tests/hostname b/src/settings/plugins/ifnet/tests/hostname
new file mode 100644
index 000000000..25c761655
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/hostname
@@ -0,0 +1,2 @@
+#Generated by NetworkManager
+hostname="gentoo"
diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net
new file mode 100644
index 000000000..e75500023
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/net
@@ -0,0 +1,147 @@
+# This blank configuration will automatically use DHCP for any net.*
+# scripts in /etc/init.d. To create a more complete configuration,
+# please review /etc/conf.d/net.example and save your configuration
+# in /etc/conf.d/net (this file :]!).
+
+config_eth0=(
+"202.117.16.121 netmask 255.255.255.0 brd 202.117.16.255"
+"192.168.4.121/24"
+"dhcp6"
+)
+routes_eth0=( "default via 202.117.16.1"
+ "192.168.4.0/24 via 192.168.4.1")
+dns_servers_eth0="202.117.0.20 202.117.0.21"
+dns_search_eth0="p12.edu.cn p13.edu.cn"
+
+config_eth1=(
+ "dhcp"
+)
+enable_ipv6_eth1="true"
+routes_eth1=( "default via 202.117.16.1" )
+dns_servers_eth1="202.117.0.20 202.117.0.21"
+config_eth2=(
+"202.117.16.1211 netmask 255.255.255.0 brd 202.117.16.255"
+"192.168.4.121/24"
+"4321:0:1:2:3:4:567:89ab/64"
+)
+routes_eth2=("default via 4321:0:1:2:3:4:567:89ab")
+enable_ipv6_eth2="true"
+config_eth3=("nufjlsjlll")
+managed_eth4=("false")
+routes_eth4=("default via 4321:0:1:2:3:4:567:89ab")
+config_eth5=("dhcp")
+config_eth6=("192.168.4.{1..101}/24")
+
+config_eth7=( "dhcp" )
+auto_eth7="true"
+
+
+config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255")
+routes_myxjtu2=("default via 202.117.16.1")
+dns_servers_myxjtu2="202.117.0.20 202.117.0.21"
+#key_myxjtu2="[1] s:xjtud key [1] enc restricted"
+#key_eth6="[1] aaaa-4444-3d [2] s:xjtudlc key [1] enc open"
+
+
+username_ppp0='user'
+password_ppp0='password'
+
+config_qiaomuf=("dhcp")
+
+config_1xtest=("dhcp")
+
+config_0xab3ace=("dhcp")
+
+modules=( "iproute2" )
+ config_kvm0=( "null" )
+ config_kvm1=( "null" )
+
+ tuntap_kvm0="tap"
+ tuntap_kvm1="tap"
+ tunctl_kvm0="-u user"
+ tunctl_kvm1="-u user"
+
+bridge_br0="eth0 kvm0 kvm1"
+config_br0=( "192.168.1.10/24" )
+ brctl_br0=( "setfd 0")
+ dhcp_eth1="nosendhost nontp -I"
+
+predown() {
+ # The default in the script is to test for NFS root and disallow
+ # downing interfaces in that case. Note that if you specify a
+ # predown() function you will override that logic. Here it is, in
+ # case you still want it...
+ if is_net_fs /; then
+ eerror "root filesystem is network mounted -- can't stop ${IFACE}"
+ return 1
+ fi
+
+ # Remember to return 0 on success
+ return 0
+}
+
+postup() {
+ # This function could be used, for example, to register with a
+ # dynamic DNS service. Another possibility would be to
+ # send/receive mail once the interface is brought up.
+
+ # Here is an example that allows the use of iproute rules
+ # which have been configured using the rules_eth0 variable.
+ #rules_eth0=" \
+ # 'from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100' \
+ # 'from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100' \
+ #"
+ eval set -- \$rules_${IFVAR}
+ if [ $# != 0 ]; then
+ einfo "Adding IP policy routing rules"
+ eindent
+ # Ensure that the kernel supports policy routing
+ if ! ip rule list | grep -q "^"; then
+ eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)"
+ eerror "in your kernel to use ip rules"
+ else
+ for x; do
+ ebegin "${x}"
+ ip rule add ${x}
+ eend $?
+ done
+ fi
+ eoutdent
+ # Flush the cache
+ ip route flush cache dev "${IFACE}"
+ fi
+
+}
+
+postdown() {
+ # Enable Wake-On-LAN for every interface except for lo
+ # Probably a good idea to set ifdown="no" in /etc/conf.d/net
+ # as well ;)
+ [ "${IFACE}" != "lo" ] && ethtool -s "${IFACE}" wol g
+
+ Automatically erase any ip rules created in the example postup above
+ if interface_exists "${IFACE}"; then
+ # Remove any rules for this interface
+ local rule
+ ip rule list | grep " iif ${IFACE}[ ]*" | {
+ while read rule; do
+ rule="${rule#*:}"
+ ip rule del ${rule}
+ done
+ }
+ # Flush the route cache
+ ip route flush cache dev "${IFACE}"
+ fi
+
+ # Return 0 always
+ return 0
+}
+
+failup() {
+ # This function is mostly here for completeness... I haven't
+ # thought of anything nifty to do with it yet ;-)
+}
+
+faildown()
+{}
+
diff --git a/src/settings/plugins/ifnet/tests/net.all b/src/settings/plugins/ifnet/tests/net.all
new file mode 100644
index 000000000..a30a1b95e
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/net.all
@@ -0,0 +1,864 @@
+##############################################################################
+# QUICK-START
+#
+# The quickest start is if you want to use DHCP.
+# In that case, everything should work out of the box, no configuration
+# necessary, though the startup script will warn you that you haven't
+# specified anything.
+
+# WARNING :- some examples have a mixture of IPv4 (ie 192.168.0.1) and IPv6
+# (ie 4321:0:1:2:3:4:567:89ab) internet addresses. They only work if you have
+# the relevant kernel option enabled. So if you don't have an IPv6 enabled
+# kernel then remove the IPv6 address from your config.
+
+# If you want to use a static address or use DHCP explicitly, jump
+# down to the section labelled INTERFACE HANDLERS.
+#
+# If you want to do anything more fancy, you should take the time to
+# read through the rest of this file.
+
+##############################################################################
+# MODULES
+#
+# We now support modular networking scripts which means we can easily
+# add support for new interface types and modules while keeping
+# compatability with existing ones.
+#
+# Modules load by default if the package they need is installed. If
+# you specify a module here that doesn't have it's package installed
+# then you get an error stating which package you need to install.
+# Ideally, you only use the modules setting when you have two or more
+# packages installed that supply the same service.
+#
+# In other words, you probably should DO NOTHING HERE...
+
+# Prefer ifconfig over iproute2
+modules=( "ifconfig" )
+
+# You can also specify other modules for an interface
+# In this case we prefer udhcpc over dhcpcd
+modules_eth0=( "udhcpc" )
+
+# You can also specify which modules not to use - for example you may be
+# using a supplicant or linux-wlan-ng to control wireless configuration but
+# you still want to configure network settings per ESSID associated with.
+modules=( "!iwconfig" "!wpa_supplicant" )
+# IMPORTANT: If you need the above, please disable modules in that order
+
+
+##############################################################################
+# INTERFACE HANDLERS
+#
+# We provide two interface handlers presently: ifconfig and iproute2.
+# You need one of these to do any kind of network configuration.
+# For ifconfig support, emerge sys-apps/net-tools
+# For iproute2 support, emerge sys-apps/iproute2
+
+# If you don't specify an interface then we prefer iproute2 if it's installed
+# To prefer ifconfig over iproute2
+modules=( "ifconfig" )
+
+# For a static configuration, use something like this
+# (They all do exactly the same thing btw)
+config_eth0=( "192.168.0.2/24" )
+config_eth0=( "192.168.0.2 netmask 255.255.255.0" )
+
+# We can also specify a broadcast
+config_eth0=( "192.168.0.2/24 brd 192.168.0.255" )
+config_eth0=( "192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" )
+
+# If you need more than one address, you can use something like this
+# NOTE: ifconfig creates an aliased device for each extra IPv4 address
+# (eth0:1, eth0:2, etc)
+# iproute2 does not do this as there is no need to
+config_eth0=(
+ "192.168.0.2/24"
+ "192.168.0.3/24"
+ "192.168.0.4/24"
+)
+# Or you can use sequence expressions
+config_eth0=( "192.168.0.{2..4}/24" )
+# which does the same as above. Be careful though as if you use this and
+# fallbacks, you have to ensure that both end up with the same number of
+# values otherwise your fallback won't work correctly.
+
+# You can also use IPv6 addresses
+# (you should always specify a prefix length with IPv6 here)
+config_eth0=(
+ "192.168.0.2/24"
+ "4321:0:1:2:3:4:567:89ab/64"
+ "4321:0:1:2:3:4:567:89ac/64"
+)
+
+# If you wish to keep existing addresses + routing and the interface is up,
+# you can specify a noop (no operation). If the interface is down or there
+# are no addresses assigned, then we move onto the next step (default dhcp)
+# This is useful when configuring your interface with a kernel command line
+# or similar
+config_eth0=( "noop" "192.168.0.2/24" )
+
+# If you don't want ANY address (only useful when calling for advanced stuff)
+config_eth0=( "null" )
+
+# Here's how to do routing if you need it
+routes_eth0=(
+ "default via 192.168.0.1" # IPv4 default route
+ "10.0.0.0/8 via 192.168.0.1" # IPv4 subnet route
+ "::/0" # IPv6 unicast
+)
+
+# If a specified module fails (like dhcp - see below), you can specify a
+# fallback like so
+fallback_eth0=( "192.168.0.2 netmask 255.255.255.0" )
+fallback_route_eth0=( "default via 192.168.0.1" )
+
+# NOTE: fallback entry must match the entry location in config_eth0
+# As such you can only have one fallback route.
+
+# Some users may need to alter the MTU - here's how
+mtu_eth0="1500"
+
+# Each module described below can set a default base metric, lower is
+# preferred over higher. This is so we can prefer a wired route over a
+# wireless route automaticaly. You can override this by setting
+metric_eth0="100"
+# or on a global basis
+metric="100"
+# The only downside of the global setting is that you have to ensure that
+# there are no conflicting routes yourself. For users with large routing
+# tables you may have to set a global metric as the due to a simple read of
+# the routing table taking over a minute at a time.
+
+##############################################################################
+# OPTIONAL MODULES
+
+# INTERFACE RENAMING
+# There is no consistent device renaming scheme for Linux.
+# The preferred way of naming devices is via the kernel module directly or
+# by using udev (http://www.reactivated.net/udevrules.php)
+
+# If you are unable to write udev rules, then we do provide a way of renaming
+# the interface based on it's MAC address, but it is not optimal.
+# Here is how to rename an interface whose MAC address is 00:11:22:33:44:55
+# to foo1
+rename_001122334455="foo1"
+
+# You can also do this based on current device name - although this is not
+# recommended. Here we rename eth1 to foo2.
+rename_eth1="foo2"
+
+#-----------------------------------------------------------------------------
+# WIRELESS (802.11 support)
+# Wireless can be provided by iwconfig or wpa_supplicant
+
+# iwconfig
+# emerge net-wireless/wireless-tools
+# Wireless options are held in /etc/conf.d/wireless - but could be here too
+# Consult the sample file /etc/conf.d/wireless.example for instructions
+# iwconfig is the default
+
+# wpa_supplicant
+# emerge net-wireless/wpa-supplicant
+# Wireless options are held in /etc/wpa_supplicant.conf
+# Consult the sample file /etc/wpa_supplicant.conf.example for instructions
+# To choose wpa_supplicant over iwconfig
+modules=( "wpa_supplicant" )
+# To configure wpa_supplicant
+wpa_supplicant_eth0="-Dwext" # For generic wireless
+wpa_supplicant_ath0="-Dmadwifi" # For Atheros based cards
+# Consult wpa_supplicant for more drivers
+# By default don't wait for wpa_suppliant to associate and authenticate.
+# If you would like to, so can specify how long in seconds
+associate_timeout_eth0=60
+# A value of 0 means wait forever.
+
+# GENERIC WIRELESS OPTIONS
+# PLEASE READ THE INSTRUCTIONS IN /etc/conf.d/wireless.example FOR
+# HOW TO USE THIS ESSID VARIABLE
+# You can also override any settings found here per ESSID - which is very
+# handy if you use different networks a lot
+config_ESSID=( "dhcp" )
+dhcpcd_ESSID="-t 5"
+
+# Setting name/domain server causes /etc/resolv.conf to be overwritten
+# Note that if DHCP is used, and you want this to take precedence then
+ set dhcp_ESSID="nodns"
+dns_servers_ESSID=( "192.168.0.1" "192.168.0.2" )
+dns_domain_ESSID="some.domain"
+dns_search_ESSID="search.this.domain search.that.domain"
+# Please check the man page for resolv.conf for more information
+# as domain and search are mutually exclusive.
+
+# You can also override any settings found here per MAC address of the AP
+# in case you use Access Points with the same ESSID but need different
+# networking configs. Below is an example - of course you use the same
+# method with other variables
+mac_config_001122334455=( "dhcp" )
+mac_dhcpcd_001122334455="-t 10"
+mac_dns_servers_001122334455=( "192.168.0.1" "192.168.0.2" )
+
+# When an interface has been associated with an Access Point, a global
+# variable called ESSID is set to the Access Point's ESSID for use in the
+# pre/post user functions below (although it's not available in preup as you
+# won't have associated then)
+
+# If you're using anything else to configure wireless on your interface AND
+# you have installed any of the above packages, you need to disable them
+modules=( "!iwconfig" "!wpa_supplicant" )
+
+#-----------------------------------------------------------------------------
+# DHCP
+# DHCP can be provided by dhclient, dhcpcd, pump or udhcpc.
+#
+# dhclient: emerge net-misc/dhcp
+# dhcpcd: emerge net-misc/dhcpcd
+# pump: emerge net-misc/pump
+# udhcpc: emerge net-misc/udhcp
+
+# If you have more than one DHCP client installed, you need to specify which
+# one to use - otherwise we default to dhcpcd if available.
+modules=( "dhclient" ) # to select dhclient over dhcpcd
+#
+# Notes:
+# - All clients send the current hostname to the DHCP server by default
+# - dhcpcd does not daemonize when the lease time is infinite
+# - udhcp-0.9.3-r3 and earlier do not support getting NTP servers
+# - pump does not support getting NIS servers
+# - DHCP tends to erase any existing device information - so add
+# static addresses after dhcp if you need them
+# - dhclient and udhcpc can set other resolv.conf options such as "option"
+# and "sortlist"- see the System module for more details
+
+# Regardless of which DHCP client you prefer, you configure them the
+# same way using one of following depending on which interface modules
+# you're using.
+config_eth0=( "dhcp" )
+
+# For passing custom options to dhcpcd use something like the following. This
+# example reduces the timeout for retrieving an address from 60 seconds (the
+# default) to 10 seconds.
+dhcpcd_eth0="-t 10"
+
+# dhclient, udhcpc and pump don't have many runtime options
+# You can pass options to them in a similar manner to dhcpcd though
+dhclient_eth0="..."
+udhcpc_eth0="..."
+pump_eth0="..."
+
+# GENERIC DHCP OPTIONS
+# Set generic DHCP options like so
+dhcp_eth0="release nodns nontp nonis nogateway nosendhost"
+
+# This tells the dhcp client to release it's lease when it stops, not to
+# overwrite dns, ntp and nis settings, not to set a default route and not to
+# send the current hostname to the dhcp server and when it starts.
+# You can use any combination of the above options - the default is not to
+# use any of them.
+
+#-----------------------------------------------------------------------------
+# For APIPA support, emerge net-misc/iputils or net-analyzer/arping
+
+# APIPA is a module that tries to find a free address in the range
+# 169.254.0.0-169.254.255.255 by arping a random address in that range on the
+# interface. If no reply is found then we assign that address to the interface
+
+# This is only useful for LANs where there is no DHCP server and you don't
+# connect directly to the internet.
+config_eth0=( "dhcp" )
+fallback_eth0=( "apipa" )
+
+#-----------------------------------------------------------------------------
+# ARPING Gateway configuration
+# and
+# Automatic Private IP Addressing (APIPA)
+# For arpingnet / apipa support, emerge net-misc/iputils or net-analyzer/arping
+#
+# This is a module that tries to find a gateway IP. If it exists then we use
+# that gateways configuration for our own. For the configuration variables
+# simply ensure that each octet is zero padded and the dots are removed.
+# Below is an example.
+#
+gateways_eth0="192.168.0.1 10.0.0.1"
+config_192168000001=( "192.168.0.2/24" )
+routes_192168000001=( "default via 192.168.0.1" )
+dns_servers_192168000001=( "192.168.0.1" )
+config_010000000001=( "10.0.0.254/8" )
+routes_010000000001=( "default via 10.0.0.1" )
+dns_servers_010000000001=( "10.0.0.1" )
+
+# We can also specify a specific MAC address for each gateway if different
+# networks have the same gateway.
+gateways_eth0="192.168.0.1,00:11:22:AA:BB:CC 10.0.0.1,33:44:55:DD:EE:FF"
+config_192168000001_001122AABBCC=( "192.168.0.2/24" )
+routes_192168000001_001122AABBCC=( "default via 192.168.0.1" )
+dns_servers_192168000001_001122AABBCC=( "192.168.0.1" )
+config_010000000001_334455DDEEFF=( "10.0.0.254/8" )
+routes_010000000001_334455DDEEFF=( "default via 10.0.0.1" )
+dns_servers_010000000001_334455DDEEFF=( "10.0.0.1" )
+
+# If we don't find any gateways (or there are none configured) then we try and
+# use APIPA to find a free address in the range 169.254.0.0-169.254.255.255
+# by arping a random address in that range on the interface. If no reply is
+# found then we assign that address to the interface.
+
+# This is only useful for LANs where there is no DHCP server.
+config_eth0=( "arping" )
+
+# or if no DHCP server can be found
+config_eth0=( "dhcp" )
+fallback_eth0=( "arping" )
+
+# NOTE: We default to sleeping for 1 second the first time we attempt an
+# arping to give the interface time to settle on the LAN. This appears to
+# be a good default for most instances, but if not you can alter it here.
+arping_sleep=5
+arping_sleep_lan=7
+
+# NOTE: We default to waiting 3 seconds to get an arping response. You can
+# change the default wait like so.
+arping_wait=3
+arping_wait_lan=2
+
+#-----------------------------------------------------------------------------
+# VLAN (802.1q support)
+# For VLAN support, emerge net-misc/vconfig
+
+# Specify the VLAN numbers for the interface like so
+# Please ensure your VLAN IDs are NOT zero-padded
+vlans_eth0="1 2"
+
+# You may not want to assign an IP the the physical interface, but we still
+# need it up.
+config_eth0=( "null" )
+
+# You can also configure the VLAN - see for vconfig man page for more details
+vconfig_eth0=( "set_name_type VLAN_PLUS_VID_NO_PAD" )
+vconfig_vlan1=( "set_flag 1" "set_egress_map 2 6" )
+config_vlan1=( "172.16.3.1 netmask 255.255.254.0" )
+config_vlan2=( "172.16.2.1 netmask 255.255.254.0" )
+
+# NOTE: Vlans can be configured with a . in their interface names
+# When configuring vlans with this name type, you need to replace . with a _
+config_eth0.1=( "dhcp" ) - does not work
+config_eth0_1=( "dhcp" ) - does work
+
+# NOTE: Vlans are controlled by their physical interface and not per vlan
+# This means you do not need to create init scripts in /etc/init.d for each
+# vlan, you must need to create one for the physical interface.
+# If you wish to control the configuration of each vlan through a separate
+# script, or wish to rename the vlan interface to something that vconfig
+# cannot then you need to do this.
+vlan_start_eth0="no"
+
+# If you do the above then you may want to depend on eth0 like so
+ RC_NEED_vlan1="net.eth0"
+# NOTE: depend functions only work in /etc/conf.d/net
+# and not in profile configs such as /etc/conf.d/net.foo
+
+#-----------------------------------------------------------------------------
+# Bonding
+# For link bonding/trunking emerge net-misc/ifenslave
+
+# To bond interfaces together
+slaves_bond0="eth0 eth1 eth2"
+config_bond0=( "null" ) # You may not want to assign an IP the the bond
+
+# If any of the slaves require extra configuration - for example wireless or
+# ppp devices - we need to depend function on the bonded interfaces
+RC_NEED_bond0="net.eth0 net.eth1"
+
+
+#-----------------------------------------------------------------------------
+# Classical IP over ATM
+# For CLIP support emerge net-dialup/linux-atm
+
+# Ensure that you have /etc/atmsigd.conf setup correctly
+# Now setup each clip interface like so
+clip_atm0=( "peer_ip [if.]vpi.vci [opts]" ... )
+# where "peer_ip" is the IP address of a PVC peer (in case of an ATM connection
+# with your ISP, your only peer is usually the ISP gateway closest to you),
+# "if" is the number of the ATM interface which will carry the PVC, "vpi.vci"
+# is the ATM VC address, and "opts" may optionally specify VC parameters like
+# qos, pcr, and the like (see "atmarp -s" for further reference). Please also
+# note quoting: it is meant to distinguish the VCs you want to create. You may,
+# in example, create an atm0 interface to more peers, like this:
+clip_atm0=( "1.1.1.254 0.8.35" "1.1.1.253 1.8.35" )
+
+# By default, the PVC will use the LLC/SNAP encapsulation. If you rather need a
+# null encapsulation (aka "VC mode"), please add the keyword "null" to opts.
+
+
+#-----------------------------------------------------------------------------
+# PPP
+# For PPP support, emerge net-dialup/ppp
+# PPP is used for most dialup connections, including ADSL.
+# The older ADSL module is documented below, but you are encouraged to try
+# this module first.
+#
+# You need to create the PPP net script yourself. Make it like so
+#ln -s net.lo /etc/init.d/net.ppp0
+#
+# We have to instruct ppp0 to actually use ppp
+config_ppp0=( "ppp" )
+#
+# Each PPP interface requires an interface to use as a "Link"
+link_ppp0="/dev/ttyS0" # Most PPP links will use a serial port
+link_ppp0="eth0" # PPPoE requires an ethernet interface
+link_ppp0="[itf.]vpi.vci" # PPPoA requires the ATM VC's address
+link_ppp0="/dev/null" # ISDN links should have this
+link_ppp0="pty 'your_link_command'" # PPP links over ssh, rsh, etc
+#
+# Here you should specify what pppd plugins you want to use
+# Available plugins are: pppoe, pppoa, capi, dhcpc, minconn, radius,
+# radattr, radrealms and winbind
+plugins_ppp0=(
+ "pppoe" # Required plugin for PPPoE
+ "pppoa vc-encaps" # Required plugin for PPPoA with an option
+ "capi" # Required plugin for ISDN
+)
+#
+# PPP requires at least a username. You can optionally set a password here too
+# If you don't, then it will use the password specified in /etc/ppp/*-secrets
+# against the specified username
+username_ppp0='user'
+password_ppp0='password'
+# NOTE: You can set a blank password like so
+password_ppp0=
+#
+# The PPP daemon has many options you can specify - although there are many
+# and may seem daunting, it is recommended that you read the pppd man page
+# before enabling any of them
+pppd_ppp0=(
+ "maxfail 0" # WARNING: It's not recommended you use this
+ # if you don't specify maxfail then we assume 0
+ "updetach" # If not set, "/etc/init.d/net.ppp0 start" will return
+ # immediately, without waiting the link to come up
+ # for the first time.
+ # Do not use it for dial-on-demand links!
+ "debug" # Enables syslog debugging
+ "noauth" # Do not require the peer to authenticate itself
+ "defaultroute" # Make this PPP interface the default route
+ "usepeerdns" # Use the DNS settings provided by PPP
+
+# On demand options
+ "demand" # Enable dial on demand
+ "idle 30" # Link goes down after 30 seconds of inactivity
+ "10.112.112.112:10.112.112.113" # Phony IP addresses
+ "ipcp-accept-remote" # Accept the peers idea of remote address
+ "ipcp-accept-local" # Accept the peers idea of local address
+ "holdoff 3" # Wait 3 seconds after link dies before re-starting
+
+# Dead peer detection
+ "lcp-echo-interval 15" # Send a LCP echo every 15 seconds
+ "lcp-echo-failure 3" # Make peer dead after 3 consective
+ # echo-requests
+
+# Compression options - use these to completely disable compression
+# noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp
+
+# Dial-up settings
+ "lock" # Lock serial port
+ "115200" # Set the serial port baud rate
+ "modem crtscts" # Enable hardware flow control
+ "192.168.0.1:192.168.0.2" # Local and remote IP addresses
+)
+#
+# Dial-up PPP users need to specify at least one telephone number
+phone_number_ppp0=( "12345689" ) # Maximum 2 phone numbers are supported
+# They will also need a chat script - here's a good one
+chat_ppp0=(
+# 'ABORT' 'BUSY'
+# 'ABORT' 'ERROR'
+# 'ABORT' 'NO ANSWER'
+# 'ABORT' 'NO CARRIER'
+# 'ABORT' 'NO DIALTONE'
+# 'ABORT' 'Invalid Login'
+# 'ABORT' 'Login incorrect'
+# 'TIMEOUT' '5'
+# '' 'ATZ'
+# 'OK' 'AT' # Put your modem initialization string here
+# 'OK' 'ATDT\T'
+# 'TIMEOUT' '60'
+# 'CONNECT' ''
+# 'TIMEOUT' '5'
+# '~--' ''
+)
+
+# If the link require extra configuration - for example wireless or
+# RFC 268 bridge - we need to depend on the bridge so they get
+# configured correctly.
+RC_NEED_ppp0="net.nas0"
+
+#WARNING: if MTU of the PPP interface is less than 1500 and you use this
+#machine as a router, you should add the following rule to your firewall
+#
+#iptables -I FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
+
+#-----------------------------------------------------------------------------
+# ADSL
+# For ADSL support, emerge net-dialup/rp-pppoe
+# WARNING: This ADSL module is being deprecated in favour of the PPP module
+# above.
+# You should make the following settings and also put your
+# username/password information in /etc/ppp/pap-secrets
+
+# Configure the interface to use ADSL
+config_eth0=( "adsl" )
+
+# You probably won't need to edit /etc/ppp/pppoe.conf if you set this
+adsl_user_eth0="my-adsl-username"
+
+#-----------------------------------------------------------------------------
+# ISDN
+# For ISDN support, emerge net-dialup/isdn4k-utils
+# You should make the following settings and also put your
+# username/password information in /etc/ppp/pap-secrets
+
+# Configure the interface to use ISDN
+config_ippp0=( "dhcp" )
+# It's important to specify dhcp if you need it!
+config_ippp0=( "192.168.0.1/24" )
+# Otherwise, you can use a static IP
+
+# NOTE: The interface name must be either ippp or isdn followed by a number
+
+# You may need this option to set the default route
+ipppd_eth0="defaultroute"
+
+#-----------------------------------------------------------------------------
+# MAC changer
+# To set a specific MAC address
+mac_eth0="00:11:22:33:44:55"
+
+# For changing MAC addresses using the below, emerge net-analyzer/macchanger
+# - to randomize the last 3 bytes only
+mac_eth0="random-ending"
+# - to randomize between the same physical type of connection (e.g. fibre,
+# copper, wireless) , all vendors
+mac_eth0="random-samekind"
+# - to randomize between any physical type of connection (e.g. fibre, copper,
+# wireless) , all vendors
+mac_eth0="random-anykind"
+# - full randomization - WARNING: some MAC addresses generated by this may NOT
+# act as expected
+mac_eth0="random-full"
+# custom - passes all parameters directly to net-analyzer/macchanger
+mac_eth0="some custom set of parameters"
+
+# You can also set other options based on the MAC address of your network card
+# Handy if you use different docking stations with laptops
+config_001122334455=( "dhcp" )
+
+#-----------------------------------------------------------------------------
+# TUN/TAP
+# For TUN/TAP support emerge net-misc/openvpn or sys-apps/usermode-utilities
+#
+# You must specify if we're a tun or tap device. Then you can give it any
+# name you like - such as vpn
+tuntap_vpn="tun"
+config_vpn=( "192.168.0.1/24")
+
+# Or stick wit the generic names - like tap0
+tuntap_tap0="tap"
+config_tap0=( "192.168.0.1/24")
+
+# For passing custom options to tunctl use something like the following. This
+# example sets the owner to adm
+tunctl_tun1="-u adm"
+# When using openvpn, there are no options
+
+#-----------------------------------------------------------------------------
+# Bridging (802.1d)
+# For bridging support emerge net-misc/bridge-utils
+
+# To add ports to bridge br0
+bridge_br0="eth0 eth1"
+# or dynamically add them when the interface comes up
+bridge_add_eth0="br0"
+bridge_add_eth1="br0"
+
+# You need to configure the ports to null values so dhcp does not get started
+config_eth0=( "null" )
+config_eth1=( "null" )
+
+# Finally give the bridge an address - dhcp or a static IP
+config_br0=( "dhcp" ) # may not work when adding ports dynamically
+config_br0=( "192.168.0.1/24" )
+
+# If any of the ports require extra configuration - for example wireless or
+# ppp devices - we need to depend on them like so.
+RC_NEED_br0="net.eth0 net.eth1"
+
+# Below is an example of configuring the bridge
+# Consult "man brctl" for more details
+brctl_br0=( "setfd 0" "sethello 0" "stp off" )
+
+#-----------------------------------------------------------------------------
+# RFC 2684 Bridge Support
+# For RFC 2684 bridge support emerge net-misc/br2684ctl
+
+# Interface names have to be of the form nas0, nas1, nas2, etc.
+# You have to specify a VPI and VCI for the interface like so
+br2684ctl_nas0="-a 0.38" # UK VPI and VCI
+
+# You may want to configure the encapsulation method as well by adding the -e
+# option to the command above (may need to be before the -a command)
+# -e 0 # LLC (default)
+# -e 1 # VC mux
+
+# Then you can configure the interface as normal
+config_nas0=( "192.168.0.1/24" )
+
+#-----------------------------------------------------------------------------
+# Tunnelling
+# WARNING: For tunnelling it is highly recommended that you
+# emerge sys-apps/iproute2
+#
+# For GRE tunnels
+iptunnel_vpn0="mode gre remote 207.170.82.1 key 0xffffffff ttl 255"
+
+# For IPIP tunnels
+iptunnel_vpn0="mode ipip remote 207.170.82.2 ttl 255"
+
+# To configure the interface
+config_vpn0=( "192.168.0.2 pointopoint 192.168.1.2" ) # ifconfig style
+config_vpn0=( "192.168.0.2 peer 192.168.1.1" ) # iproute2 style
+
+# 6to4 Tunnels allow IPv6 to work over IPv4 addresses, provided you
+# have a non-private address configured on an interface.
+ link_6to4="eth0" # Interface to base it's addresses on
+ config_6to4=( "ip6to4" )
+# You may want to depend on eth0 like so
+RC_NEED_6to4="net.eth0"
+# To ensure that eth0 is configured before 6to4. Of course, the tunnel could be
+# any name and this also works for any configured interface.
+# NOTE: If you're not using iproute2 then your 6to4 tunnel has to be called
+# sit0 - otherwise use a different name like 6to4 in the example above.
+
+
+#-----------------------------------------------------------------------------
+# System
+# For configuring system specifics such as domain, dns, ntp and nis servers
+# It's rare that you would need todo this, but you can anyway.
+# This is most benefit to wireless users who don't use DHCP so they can change
+# their configs based on ESSID. See wireless.example for more details
+
+# To use dns settings such as these, dns_servers_eth0 must be set!
+# If you omit the _eth0 suffix, then it applies to all interfaces unless
+# overridden by the interface suffix.
+dns_domain_eth0="your.domain"
+dns_servers_eth0="192.168.0.2 192.168.0.3"
+dns_search_eth0="this.domain that.domain"
+dns_options_eth0=( "timeout 1" "rotate" )
+dns_sortlist_eth0="130.155.160.0/255.255.240.0 130.155.0.0"
+# See the man page for resolv.conf for details about the options and sortlist
+# directives
+
+ntp_servers_eth0="192.168.0.2 192.168.0.3"
+
+nis_domain_eth0="domain"
+nis_servers_eth0="192.168.0.2 192.168.0.3"
+
+# NOTE: Setting any of these will stamp on the files in question. So if you
+# don't specify dns_servers but you do specify dns_domain then no nameservers
+# will be listed in /etc/resolv.conf even if there were any there to start
+# with.
+# If this is an issue for you then maybe you should look into a resolv.conf
+# manager like resolvconf-gentoo to manage this file for you. All packages
+# that baselayout supports use resolvconf-gentoo if installed.
+
+#-----------------------------------------------------------------------------
+# Cable in/out detection
+# Sometimes the cable is in, others it's out. Obviously you don't want to
+# restart net.eth0 every time when you plug it in either.
+#
+# netplug is a package that detects this and requires no extra configuration
+# on your part.
+# emerge sys-apps/netplug
+# or
+# emerge sys-apps/ifplugd
+# and you're done :)
+
+# By default we don't wait for netplug/ifplugd to configure the interface.
+# If you would like it to wait so that other services now that network is up
+# then you can specify a timeout here.
+plug_timeout="10"
+# A value of 0 means wait forever.
+
+# If you don't want to use netplug on a specific interface but you have it
+# installed, you can disable it for that interface via the modules statement
+modules_eth0=( "!netplug" )
+# You can do the same for ifplugd
+#
+# You can disable them both with the generic plug
+modules_eth0=( "!plug" )
+
+# To use specific ifplugd options, fex specifying wireless mode
+ifplugd_eth0="--api-mode=wlan"
+# man ifplugd for more options
+
+##############################################################################
+# ADVANCED CONFIGURATION
+#
+# Four functions can be defined which will be called surrounding the
+# start/stop operations. The functions are called with the interface
+# name first so that one function can control multiple adapters. An extra two
+# functions can be defined when an interface fails to start or stop.
+#
+# The return values for the preup and predown functions should be 0
+# (success) to indicate that configuration or deconfiguration of the
+# interface can continue. If preup returns a non-zero value, then
+# interface configuration will be aborted. If predown returns a
+# non-zero value, then the interface will not be allowed to continue
+# deconfiguration.
+#
+# The return values for the postup, postdown, failup and faildown functions are
+# ignored since there's nothing to do if they indicate failure.
+#
+# ${IFACE} is set to the interface being brought up/down
+# ${IFVAR} is ${IFACE} converted to variable name bash allows
+
+#preup() {
+# # Test for link on the interface prior to bringing it up. This
+# # only works on some network adapters and requires the mii-diag
+# # package to be installed.
+# if mii-tool "${IFACE}" 2> /dev/null | grep -q 'no link'; then
+# ewarn "No link on ${IFACE}, aborting configuration"
+# return 1
+# fi
+#
+# # Test for link on the interface prior to bringing it up. This
+# # only works on some network adapters and requires the ethtool
+# # package to be installed.
+# if ethtool "${IFACE}" | grep -q 'Link detected: no'; then
+# ewarn "No link on ${IFACE}, aborting configuration"
+# return 1
+# fi
+#
+#
+# # Remember to return 0 on success
+# return 0
+#}
+
+#predown() {
+# # The default in the script is to test for NFS root and disallow
+# # downing interfaces in that case. Note that if you specify a
+# # predown() function you will override that logic. Here it is, in
+# # case you still want it...
+# if is_net_fs /; then
+# eerror "root filesystem is network mounted -- can't stop ${IFACE}"
+# return 1
+# fi
+#
+# # Remember to return 0 on success
+# return 0
+#}
+
+#postup() {
+# # This function could be used, for example, to register with a
+# # dynamic DNS service. Another possibility would be to
+# # send/receive mail once the interface is brought up.
+
+# # Here is an example that allows the use of iproute rules
+# # which have been configured using the rules_eth0 variable.
+# #rules_eth0=(
+# # "from 24.80.102.112/32 to 192.168.1.0/24 table localnet priority 100"
+# # "from 216.113.223.51/32 to 192.168.1.0/24 table localnet priority 100"
+# #)
+# local x="rules_${IFVAR}[@]"
+# local -a rules=( "${!x}" )
+# if [[ -n ${rules} ]] ; then
+# einfo "Adding IP policy routing rules"
+# eindent
+# # Ensure that the kernel supports policy routing
+# if ! ip rule list | grep -q "^" ; then
+# eerror "You need to enable IP Policy Routing (CONFIG_IP_MULTIPLE_TABLES)"
+# eerror "in your kernel to use ip rules"
+# else
+# for x in "${rules[@]}" ; do
+# ebegin "${x}"
+# ip rule add ${x} dev "${IFACE}"
+# eend $?
+# done
+# fi
+# eoutdent
+# # Flush the cache
+# ip route flush cache dev "${IFACE}"
+# fi
+
+#}
+
+#postdown() {
+# # Enable Wake-On-LAN for every interface except for lo
+# # Probably a good idea to set RC_DOWN_INTERFACE="no" in /etc/conf.d/rc
+# # as well ;)
+# [[ ${IFACE} != "lo" ]] && ethtool -s "${IFACE}" wol g
+
+# Automatically erase any ip rules created in the example postup above
+# if interface_exists "${IFACE}" ; then
+# # Remove any rules for this interface
+# local rule
+# ip rule list | grep " iif ${IFACE}[ ]*" | {
+# while read rule ; do
+# rule="${rule#*:}"
+# ip rule del ${rule}
+# done
+# }
+# # Flush the route cache
+# ip route flush cache dev "${IFACE}"
+# fi
+
+# # Return 0 always
+# return 0
+#}
+
+#failup() {
+# # This function is mostly here for completeness... I haven't
+# # thought of anything nifty to do with it yet ;-)
+#}
+
+#faildown() {
+# # This function is mostly here for completeness... I haven't
+# # thought of anything nifty to do with it yet ;-)
+#}
+
+##############################################################################
+# FORCING MODULES
+# The Big Fat Warning :- If you use module forcing do not complain to us or
+# file bugs about it not working!
+#
+# Loading modules is a slow affair - we have to check each one for the following
+# 1) Code sanity
+# 2) Has the required package been emerged?
+# 3) Has it modified anything?
+# 4) Have all the dependant modules been loaded?
+
+# Then we have to strip out the conflicting modules based on user preference
+# and default configuration and sort them into the correct order.
+# Finally we check the end result for dependencies.
+
+# This, of course, takes valuable CPU time so we provide module forcing as a
+# means to speed things up. We still do *some* checking but not much.
+
+# It is essential that you force modules in the correct order and supply all
+# the modules you need. You must always supply an interface module - we
+# supply ifconfig or iproute2.
+
+# The Big Fat Warning :- If you use module forcing do not complain to us or
+# file bugs about it not working!
+
+# Now that we've warned you twice, here's how to do it
+modules_force=( "ifconfig" )
+modules_force=( "iproute2" "dhcpcd" )
+
+# We can also apply this to a specific interface
+modules_force_eth1=( "iproute2" )
+
+# The below will not work
+modules_force=( "dhcpcd" )
+# No interface (ifconfig/iproute2)
+modules_force=( "ifconfig" "essidnet" "iwconfig" )
+# Although it will not crash, essidnet will not work as it has to come after
+# iwconfig
+modules_force=( "iproute2" "ifconfig" )
+# The interface will be setup twice which will cause problems
diff --git a/src/settings/plugins/ifnet/tests/nm-system-settings.conf b/src/settings/plugins/ifnet/tests/nm-system-settings.conf
new file mode 100644
index 000000000..39bc87b8b
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/nm-system-settings.conf
@@ -0,0 +1,5 @@
+[main]
+plugins=ifnet,keyfile
+
+[ifnet]
+managed=false
diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c
new file mode 100644
index 000000000..d114bbba8
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/test_all.c
@@ -0,0 +1,399 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service (ifnet)
+ *
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <nm-utils.h>
+
+#include "net_parser.h"
+#include "nm-test-helpers.h"
+#include "net_utils.h"
+#include "wpa_parser.h"
+#include "connection_parser.h"
+
+static void
+test_getdata ()
+{
+ ASSERT (ifnet_get_data ("eth1", "config")
+ && strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0,
+ "get data", "config_eth1 is not correct");
+ ASSERT (ifnet_get_data ("ppp0", "username")
+ && strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0,
+ "get data", "config_ppp0 username is not correctly read");
+ ASSERT (ifnet_get_data ("ppp0", "password")
+ && strcmp (ifnet_get_data ("ppp0", "password"),
+ "password") == 0, "get data",
+ "config_ppp0 password is not correctly read");
+}
+
+static void
+test_read_hostname ()
+{
+ gchar *hostname = read_hostname ("hostname");
+
+ ASSERT (hostname != NULL, "get hostname", "hostname is NULL");
+ ASSERT (strcmp ("gentoo", hostname) == 0,
+ "get hostname",
+ "hostname is not correctly read, read:%s, expected: gentoo",
+ hostname);
+ g_free (hostname);
+}
+
+static void
+test_write_hostname ()
+{
+ gchar *hostname = read_hostname ("hostname");
+ gchar *tmp;
+
+ write_hostname ("gentoo-nm", "hostname");
+ tmp = read_hostname ("hostname");
+ ASSERT (strcmp (tmp, "gentoo-nm") == 0,
+ "write hostname", "write hostname error");
+ write_hostname (hostname, "hostname");
+ g_free (tmp);
+ g_free (hostname);
+}
+
+static void
+test_is_static ()
+{
+ ASSERT (is_static_ip4 ("eth1") == FALSE, "is static",
+ "a dhcp interface is recognized as static");
+ ASSERT (is_static_ip4 ("eth0") == TRUE, "is static",
+ "a static interface is recognized as dhcp");
+ ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static",
+ "a static interface is recognized as dhcp");
+}
+
+static void
+test_has_default_route ()
+{
+ ASSERT (has_default_ip4_route ("eth0"),
+ "has default route", "eth0 should have a default ipv4 route");
+ ASSERT (has_default_ip6_route ("eth4"),
+ "has default route", "eth4 should have a default ipv6 route");
+ ASSERT (!has_default_ip4_route ("eth5")
+ && !has_default_ip6_route ("eth5"),
+ "has default route", "eth5 shouldn't have a default route");
+}
+
+static void
+test_has_ip6_address ()
+{
+ ASSERT (has_ip6_address ("eth2"), "has ip6 address",
+ "eth2 should have a ipv6 address");
+ ASSERT (!has_ip6_address ("eth0"), "has ip6 address",
+ "eth0 shouldn't have a ipv6 address")
+
+}
+
+static void
+test_is_ip4_address ()
+{
+ gchar *address1 = "192.168.4.232/24";
+ gchar *address2 = "192.168.100.{1..254}/24";
+ gchar *address3 = "192.168.4.2555/24";
+
+ ASSERT (is_ip4_address (address1), "is ip4 address",
+ "%s should be a valid address", address1);
+ ASSERT (is_ip4_address (address2), "is ip4 address",
+ "%s should be a valid address", address2);
+ ASSERT (!is_ip4_address (address3), "is ip4 address",
+ "%s should be an invalid address", address3);
+}
+
+static void
+test_is_ip6_address ()
+{
+ gchar *address1 = "4321:0:1:2:3:4:567:89ac/24";
+
+ ASSERT (is_ip6_address (address1), "is ip6 address",
+ "%s should be a valid address", address1);
+}
+
+static void
+check_ip_block (ip_block * iblock, gchar * ip, gchar * netmask, gchar * gateway)
+{
+ char *str;
+ struct in_addr tmp_ip4_addr;
+
+ str = malloc (INET_ADDRSTRLEN);
+ tmp_ip4_addr.s_addr = iblock->ip;
+ inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
+ ASSERT (strcmp (ip, str) == 0, "check ip",
+ "ip expected:%s, find:%s", ip, str);
+ tmp_ip4_addr.s_addr = iblock->netmask;
+ inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
+ ASSERT (strcmp (netmask, str) == 0, "check netmask",
+ "netmask expected:%s, find:%s", netmask, str);
+ tmp_ip4_addr.s_addr = iblock->gateway;
+ inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN);
+ ASSERT (strcmp (gateway, str) == 0, "check gateway",
+ "gateway expected:%s, find:%s", gateway, str);
+ free (str);
+}
+
+static void
+test_convert_ipv4_config_block ()
+{
+ ip_block *iblock = convert_ip4_config_block ("eth0");
+ ip_block *tmp = iblock;
+
+ ASSERT (iblock != NULL, "convert ipv4 block",
+ "block eth0 should not be NULL");
+ check_ip_block (iblock, "202.117.16.121", "255.255.255.0",
+ "202.117.16.1");
+ iblock = iblock->next;
+ destroy_ip_block (tmp);
+ ASSERT (iblock != NULL, "convert ipv4 block",
+ "block eth0 should have a second IP address");
+ check_ip_block (iblock, "192.168.4.121", "255.255.255.0",
+ "202.117.16.1");
+ destroy_ip_block (iblock);
+ iblock = convert_ip4_config_block ("eth2");
+ ASSERT (iblock != NULL
+ && iblock->next == NULL,
+ "convert error IPv4 address", "should only get one address");
+ check_ip_block (iblock, "192.168.4.121", "255.255.255.0", "0.0.0.0");
+ destroy_ip_block (iblock);
+ iblock = convert_ip4_config_block ("eth3");
+ ASSERT (iblock == NULL, "convert config_block",
+ "convert error configuration");
+ destroy_ip_block (iblock);
+ iblock = convert_ip4_config_block ("eth6");
+ ASSERT (iblock != NULL, "convert config_block",
+ "convert error configuration");
+ destroy_ip_block (iblock);
+}
+
+static void
+test_convert_ipv4_routes_block ()
+{
+ ip_block *iblock = convert_ip4_routes_block ("eth0");
+ ip_block *tmp = iblock;
+
+ ASSERT (iblock != NULL, "convert ip4 routes", "should get one route");
+ check_ip_block (iblock, "192.168.4.0", "255.255.255.0", "192.168.4.1");
+ iblock = iblock->next;
+ destroy_ip_block (tmp);
+ ASSERT (iblock == NULL, "convert ip4 routes",
+ "should only get one route");
+}
+
+static void
+test_wpa_parser ()
+{
+ const char *value;
+
+ ASSERT (exist_ssid ("example"), "get wsec",
+ "ssid myxjtu2 is not found");
+ ASSERT (exist_ssid ("static-wep-test"), "exist_ssid",
+ "ssid static-wep-test is not found");
+ value = wpa_get_value ("static-wep-test", "key_mgmt");
+ ASSERT (value
+ && strcmp (value, "NONE") == 0, "get wpa data",
+ "key_mgmt of static-wep-test should be NONE, find %s", value);
+ value = wpa_get_value ("static-wep-test", "wep_key0");
+ ASSERT (value
+ && strcmp (value, "\"abcde\"") == 0,
+ "get wpa data",
+ "wep_key0 of static-wep-test should be abcde, find %s", value);
+ ASSERT (exist_ssid ("leap-example"), "get wsec",
+ "ssid leap-example is not found");
+}
+
+static void
+test_strip_string ()
+{
+ gchar *str = "( \"default via 202.117.16.1\" )";
+ gchar *result = g_strdup (str);
+ gchar *result_b = result;
+
+ result = strip_string (result, '(');
+ result = strip_string (result, ')');
+ result = strip_string (result, '"');
+ ASSERT (strcmp (result, "default via 202.117.16.1") ==
+ 0, "strip_string",
+ "string isn't stripped, result is: %s", result);
+ g_free (result_b);
+}
+
+static void
+test_is_unmanaged ()
+{
+ ASSERT (is_managed ("eth0"), "test_is_unmanaged",
+ "eth0 should be managed");
+ ASSERT (!is_managed ("eth4"), "test_is_unmanaged",
+ "eth4 should be unmanaged");
+}
+
+static void
+test_new_connection ()
+{
+ GError **error = NULL;
+ NMConnection *connection;
+
+ connection = ifnet_update_connection_from_config_block ("eth2", error);
+ ASSERT (connection != NULL, "new connection",
+ "new connection failed: %s",
+ error == NULL ? "None" : (*error)->message);
+ g_object_unref (connection);
+ connection =
+ ifnet_update_connection_from_config_block ("qiaomuf", error);
+ ASSERT (connection != NULL, "new connection",
+ "new connection failed: %s", error
+ && (*error) ? (*error)->message : "NONE");
+ g_object_unref (connection);
+ connection =
+ ifnet_update_connection_from_config_block ("myxjtu2", error);
+ ASSERT (connection != NULL, "new connection",
+ "new connection failed: %s", error
+ && (*error) ? (*error)->message : "NONE");
+ g_object_unref (connection);
+}
+
+#define NET_GEN_NAME "net.generate"
+#define SUP_GEN_NAME "wpa_supplicant.conf.generate"
+
+static void
+test_update_connection ()
+{
+ GError **error = NULL;
+ NMConnection *connection;
+ gboolean success;
+
+ connection = ifnet_update_connection_from_config_block ("eth0", error);
+ ASSERT (connection != NULL, "get connection",
+ "get connection failed: %s",
+ error == NULL ? "None" : (*error)->message);
+
+ success = ifnet_update_parsers_by_connection (connection, "eth0",
+ NET_GEN_NAME,
+ SUP_GEN_NAME,
+ NULL,
+ error);
+ ASSERT (success, "update connection", "update connection failed %s", "eth0");
+ g_object_unref (connection);
+
+ connection = ifnet_update_connection_from_config_block ("0xab3ace", error);
+ ASSERT (connection != NULL, "get connection", "get connection failed: %s",
+ error == NULL ? "None" : (*error)->message);
+
+ success = ifnet_update_parsers_by_connection (connection, "0xab3ace",
+ NET_GEN_NAME,
+ SUP_GEN_NAME,
+ NULL,
+ error);
+ ASSERT (success, "update connection", "update connection failed %s", "0xab3ace");
+ g_object_unref (connection);
+
+ unlink (NET_GEN_NAME);
+ unlink (SUP_GEN_NAME);
+}
+
+static void
+test_add_connection ()
+{
+ NMConnection *connection;
+
+ connection = ifnet_update_connection_from_config_block ("eth0", NULL);
+ ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL),
+ "add connection", "add connection failed: %s", "eth0");
+ g_object_unref (connection);
+ connection = ifnet_update_connection_from_config_block ("myxjtu2", NULL);
+ ASSERT (ifnet_add_new_connection (connection, NET_GEN_NAME, SUP_GEN_NAME, NULL),
+ "add connection", "add connection failed: %s", "myxjtu2");
+ g_object_unref (connection);
+
+ unlink (NET_GEN_NAME);
+ unlink (SUP_GEN_NAME);
+}
+
+static void
+test_delete_connection ()
+{
+ GError *error = NULL;
+ NMConnection *connection;
+
+ connection = ifnet_update_connection_from_config_block ("eth7", &error);
+ ASSERT (connection != NULL, "get connection",
+ "get connection failed: %s",
+ error ? error->message : "None");
+ ASSERT (ifnet_delete_connection_in_parsers ("eth7", NET_GEN_NAME, SUP_GEN_NAME),
+ "delete connection", "delete connection failed: %s", "eth7");
+ g_object_unref (connection);
+ connection = ifnet_update_connection_from_config_block ("qiaomuf", &error);
+ ASSERT (connection != NULL, "get connection",
+ "get connection failed: %s",
+ error ? error->message : "None");
+ ASSERT (ifnet_delete_connection_in_parsers ("qiaomuf", NET_GEN_NAME, SUP_GEN_NAME),
+ "delete connection", "delete connection failed: %s", "qiaomuf");
+ g_object_unref (connection);
+
+ unlink (NET_GEN_NAME);
+ unlink (SUP_GEN_NAME);
+}
+
+static void
+run_all (gboolean run)
+{
+ if (run) {
+ test_strip_string ();
+ test_is_static ();
+ test_has_ip6_address ();
+ test_has_default_route ();
+ test_getdata ();
+ test_read_hostname ();
+ test_write_hostname ();
+ test_is_ip4_address ();
+ test_is_ip6_address ();
+ test_convert_ipv4_config_block ();
+ test_convert_ipv4_routes_block ();
+ test_is_unmanaged ();
+ test_wpa_parser ();
+ test_convert_ipv4_routes_block ();
+ test_new_connection ();
+ test_update_connection ();
+ test_add_connection ();
+ test_delete_connection ();
+ }
+}
+
+int
+main (void)
+{
+// g_mem_set_vtable(glib_mem_profiler_table);
+// g_atexit(g_mem_profile);
+ g_type_init ();
+ ifnet_destroy ();
+ wpa_parser_destroy ();
+ ifnet_init ("net");
+ wpa_parser_init ("wpa_supplicant.conf");
+ printf ("Initialization complete\n");
+ run_all (TRUE);
+ ifnet_destroy ();
+ wpa_parser_destroy ();
+ return 0;
+}
diff --git a/src/settings/plugins/ifnet/tests/wpa_supplicant.conf b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
new file mode 100644
index 000000000..a2595d42c
--- /dev/null
+++ b/src/settings/plugins/ifnet/tests/wpa_supplicant.conf
@@ -0,0 +1,864 @@
+##### Example wpa_supplicant configuration file ###############################
+#
+# This file describes configuration file format and lists all available option.
+# Please also take a look at simpler configuration examples in 'examples'
+# subdirectory.
+#
+# Empty lines and lines starting with # are ignored
+
+# NOTE! This file may contain password information and should probably be made
+# readable only by root user on multiuser systems.
+
+# Note: All file paths in this configuration file should use full (absolute,
+# not relative to working directory) path in order to allow working directory
+# to be changed. This can happen if wpa_supplicant is run in the background.
+
+# Whether to allow wpa_supplicant to update (overwrite) configuration
+#
+# This option can be used to allow wpa_supplicant to overwrite configuration
+# file whenever configuration is changed (e.g., new network block is added with
+# wpa_cli or wpa_gui, or a password is changed). This is required for
+# wpa_cli/wpa_gui to be able to store the configuration changes permanently.
+# Please note that overwriting configuration file will remove the comments from
+# it.
+#update_config=1
+
+# global configuration (shared by all network blocks)
+#
+# Parameters for the control interface. If this is specified, wpa_supplicant
+# will open a control interface that is available for external programs to
+# manage wpa_supplicant. The meaning of this string depends on which control
+# interface mechanism is used. For all cases, the existance of this parameter
+# in configuration is used to determine whether the control interface is
+# enabled.
+#
+# For UNIX domain sockets (default on Linux and BSD): This is a directory that
+# will be created for UNIX domain sockets for listening to requests from
+# external programs (CLI/GUI, etc.) for status information and configuration.
+# The socket file will be named based on the interface name, so multiple
+# wpa_supplicant processes can be run at the same time if more than one
+# interface is used.
+# /var/run/wpa_supplicant is the recommended directory for sockets and by
+# default, wpa_cli will use it when trying to connect with wpa_supplicant.
+#
+# Access control for the control interface can be configured by setting the
+# directory to allow only members of a group to use sockets. This way, it is
+# possible to run wpa_supplicant as root (since it needs to change network
+# configuration and open raw sockets) and still allow GUI/CLI components to be
+# run as non-root users. However, since the control interface can be used to
+# change the network configuration, this access needs to be protected in many
+# cases. By default, wpa_supplicant is configured to use gid 0 (root). If you
+# want to allow non-root users to use the control interface, add a new group
+# and change this value to match with that group. Add users that should have
+# control interface access to this group. If this variable is commented out or
+# not included in the configuration file, group will not be changed from the
+# value it got by default when the directory or socket was created.
+#
+# When configuring both the directory and group, use following format:
+# DIR=/var/run/wpa_supplicant GROUP=wheel
+# DIR=/var/run/wpa_supplicant GROUP=0
+# (group can be either group name or gid)
+#
+# For UDP connections (default on Windows): The value will be ignored. This
+# variable is just used to select that the control interface is to be created.
+# The value can be set to, e.g., udp (ctrl_interface=udp)
+#
+# For Windows Named Pipe: This value can be used to set the security descriptor
+# for controlling access to the control interface. Security descriptor can be
+# set using Security Descriptor String Format (see http://msdn.microsoft.com/
+# library/default.asp?url=/library/en-us/secauthz/security/
+# security_descriptor_string_format.asp). The descriptor string needs to be
+# prefixed with SDDL=. For example, ctrl_interface=SDDL=D: would set an empty
+# DACL (which will reject all connections). See README-Windows.txt for more
+# information about SDDL string format.
+#
+ctrl_interface=/var/run/wpa_supplicant
+
+# IEEE 802.1X/EAPOL version
+# wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which defines
+# EAPOL version 2. However, there are many APs that do not handle the new
+# version number correctly (they seem to drop the frames completely). In order
+# to make wpa_supplicant interoperate with these APs, the version number is set
+# to 1 by default. This configuration value can be used to set it to the new
+# version (2).
+eapol_version=1
+
+# AP scanning/selection
+# By default, wpa_supplicant requests driver to perform AP scanning and then
+# uses the scan results to select a suitable AP. Another alternative is to
+# allow the driver to take care of AP scanning and selection and use
+# wpa_supplicant just to process EAPOL frames based on IEEE 802.11 association
+# information from the driver.
+# 1: wpa_supplicant initiates scanning and AP selection
+# 0: driver takes care of scanning, AP selection, and IEEE 802.11 association
+# parameters (e.g., WPA IE generation); this mode can also be used with
+# non-WPA drivers when using IEEE 802.1X mode; do not try to associate with
+# APs (i.e., external program needs to control association). This mode must
+# also be used when using wired Ethernet drivers.
+# 2: like 0, but associate with APs using security policy and SSID (but not
+# BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to
+# enable operation with hidden SSIDs and optimized roaming; in this mode,
+# the network blocks in the configuration file are tried one by one until
+# the driver reports successful association; each network block should have
+# explicit security policy (i.e., only one option in the lists) for
+# key_mgmt, pairwise, group, proto variables
+ap_scan=1
+
+# EAP fast re-authentication
+# By default, fast re-authentication is enabled for all EAP methods that
+# support it. This variable can be used to disable fast re-authentication.
+# Normally, there is no need to disable this.
+fast_reauth=1
+
+# OpenSSL Engine support
+# These options can be used to load OpenSSL engines.
+# The two engines that are supported currently are shown below:
+# They are both from the opensc project (http://www.opensc.org/)
+# By default no engines are loaded.
+# make the opensc engine available
+#opensc_engine_path=/usr/lib64/engine_opensc.so
+# make the pkcs11 engine available
+#pkcs11_engine_path=/usr/lib64/engine_pkcs11.so
+# configure the path to the pkcs11 module required by the pkcs11 engine
+#pkcs11_module_path=/usr/lib64/opensc-pkcs11.so
+
+# Dynamic EAP methods
+# If EAP methods were built dynamically as shared object files, they need to be
+# loaded here before being used in the network blocks. By default, EAP methods
+# are included statically in the build, so these lines are not needed
+#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_tls.so
+#load_dynamic_eap=/usr/lib/wpa_supplicant/eap_md5.so
+
+# Driver interface parameters
+# This field can be used to configure arbitrary driver interace parameters. The
+# format is specific to the selected driver interface. This field is not used
+# in most cases.
+#driver_param="field=value"
+
+# Country code
+# The ISO/IEC alpha2 country code for the country in which this device is
+# currently operating.
+#country=US
+
+# Maximum lifetime for PMKSA in seconds; default 43200
+#dot11RSNAConfigPMKLifetime=43200
+# Threshold for reauthentication (percentage of PMK lifetime); default 70
+#dot11RSNAConfigPMKReauthThreshold=70
+# Timeout for security association negotiation in seconds; default 60
+#dot11RSNAConfigSATimeout=60
+
+# Wi-Fi Protected Setup (WPS) parameters
+
+# Universally Unique IDentifier (UUID; see RFC 4122) of the device
+# If not configured, UUID will be generated based on the local MAC address.
+#uuid=12345678-9abc-def0-1234-56789abcdef0
+
+# Device Name
+# User-friendly description of device; up to 32 octets encoded in UTF-8
+#device_name=Wireless Client
+
+# Manufacturer
+# The manufacturer of the device (up to 64 ASCII characters)
+#manufacturer=Company
+
+# Model Name
+# Model of the device (up to 32 ASCII characters)
+#model_name=cmodel
+
+# Model Number
+# Additional device description (up to 32 ASCII characters)
+#model_number=123
+
+# Serial Number
+# Serial number of the device (up to 32 characters)
+#serial_number=12345
+
+# Primary Device Type
+# Used format: <categ>-<OUI>-<subcateg>
+# categ = Category as an integer value
+# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
+# default WPS OUI
+# subcateg = OUI-specific Sub Category as an integer value
+# Examples:
+# 1-0050F204-1 (Computer / PC)
+# 1-0050F204-2 (Computer / Server)
+# 5-0050F204-1 (Storage / NAS)
+# 6-0050F204-1 (Network Infrastructure / AP)
+#device_type=1-0050F204-1
+
+# OS Version
+# 4-octet operating system version number (hex string)
+#os_version=01020300
+
+# Credential processing
+# 0 = process received credentials internally (default)
+# 1 = do not process received credentials; just pass them over ctrl_iface to
+# external program(s)
+# 2 = process received credentials internally and pass them over ctrl_iface
+# to external program(s)
+#wps_cred_processing=0
+
+# network block
+#
+# Each network (usually AP's sharing the same SSID) is configured as a separate
+# block in this configuration file. The network blocks are in preference order
+# (the first match is used).
+#
+# network block fields:
+#
+# disabled:
+# 0 = this network can be used (default)
+# 1 = this network block is disabled (can be enabled through ctrl_iface,
+# e.g., with wpa_cli or wpa_gui)
+#
+# id_str: Network identifier string for external scripts. This value is passed
+# to external action script through wpa_cli as WPA_ID_STR environment
+# variable to make it easier to do network specific configuration.
+#
+# ssid: SSID (mandatory); either as an ASCII string with double quotation or
+# as hex string; network name
+#
+# scan_ssid:
+# 0 = do not scan this SSID with specific Probe Request frames (default)
+# 1 = scan with SSID-specific Probe Request frames (this can be used to
+# find APs that do not accept broadcast SSID or use multiple SSIDs;
+# this will add latency to scanning, so enable this only when needed)
+#
+# bssid: BSSID (optional); if set, this network block is used only when
+# associating with the AP using the configured BSSID
+#
+# priority: priority group (integer)
+# By default, all networks will get same priority group (0). If some of the
+# networks are more desirable, this field can be used to change the order in
+# which wpa_supplicant goes through the networks when selecting a BSS. The
+# priority groups will be iterated in decreasing priority (i.e., the larger the
+# priority value, the sooner the network is matched against the scan results).
+# Within each priority group, networks will be selected based on security
+# policy, signal strength, etc.
+# Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are not
+# using this priority to select the order for scanning. Instead, they try the
+# networks in the order that used in the configuration file.
+#
+# mode: IEEE 802.11 operation mode
+# 0 = infrastructure (Managed) mode, i.e., associate with an AP (default)
+# 1 = IBSS (ad-hoc, peer-to-peer)
+# Note: IBSS can only be used with key_mgmt NONE (plaintext and static WEP)
+# and key_mgmt=WPA-NONE (fixed group key TKIP/CCMP). In addition, ap_scan has
+# to be set to 2 for IBSS. WPA-None requires following network block options:
+# proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or CCMP, but not
+# both), and psk must also be set.
+#
+# frequency: Channel frequency in megahertz (MHz) for IBSS, e.g.,
+# 2412 = IEEE 802.11b/g channel 1. This value is used to configure the initial
+# channel for IBSS (adhoc) networks. It is ignored in the infrastructure mode.
+# In addition, this value is only used by the station that creates the IBSS. If
+# an IBSS network with the configured SSID is already present, the frequency of
+# the network will be used instead of this configured value.
+#
+# proto: list of accepted protocols
+# WPA = WPA/IEEE 802.11i/D3.0
+# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)
+# If not set, this defaults to: WPA RSN
+#
+# key_mgmt: list of accepted authenticated key management protocols
+# WPA-PSK = WPA pre-shared key (this requires 'psk' field)
+# WPA-EAP = WPA using EAP authentication
+# IEEE8021X = IEEE 802.1X using EAP authentication and (optionally) dynamically
+# generated WEP keys
+# NONE = WPA is not used; plaintext or static WEP could be used
+# WPA-PSK-SHA256 = Like WPA-PSK but using stronger SHA256-based algorithms
+# WPA-EAP-SHA256 = Like WPA-EAP but using stronger SHA256-based algorithms
+# If not set, this defaults to: WPA-PSK WPA-EAP
+#
+# auth_alg: list of allowed IEEE 802.11 authentication algorithms
+# OPEN = Open System authentication (required for WPA/WPA2)
+# SHARED = Shared Key authentication (requires static WEP keys)
+# LEAP = LEAP/Network EAP (only used with LEAP)
+# If not set, automatic selection is used (Open System with LEAP enabled if
+# LEAP is allowed as one of the EAP methods).
+#
+# pairwise: list of accepted pairwise (unicast) ciphers for WPA
+# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
+# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
+# NONE = Use only Group Keys (deprecated, should not be included if APs support
+# pairwise keys)
+# If not set, this defaults to: CCMP TKIP
+#
+# group: list of accepted group (broadcast/multicast) ciphers for WPA
+# CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
+# TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
+# WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
+# WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key [IEEE 802.11]
+# If not set, this defaults to: CCMP TKIP WEP104 WEP40
+#
+# psk: WPA preshared key; 256-bit pre-shared key
+# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e.,
+# 32 bytes or as an ASCII passphrase (in which case, the real PSK will be
+# generated using the passphrase and SSID). ASCII passphrase must be between
+# 8 and 63 characters (inclusive).
+# This field is not needed, if WPA-EAP is used.
+# Note: Separate tool, wpa_passphrase, can be used to generate 256-bit keys
+# from ASCII passphrase. This process uses lot of CPU and wpa_supplicant
+# startup and reconfiguration time can be optimized by generating the PSK only
+# only when the passphrase or SSID has actually changed.
+#
+# eapol_flags: IEEE 802.1X/EAPOL options (bit field)
+# Dynamic WEP key required for non-WPA mode
+# bit0 (1): require dynamically generated unicast WEP key
+# bit1 (2): require dynamically generated broadcast WEP key
+# (3 = require both keys; default)
+# Note: When using wired authentication, eapol_flags must be set to 0 for the
+# authentication to be completed successfully.
+#
+# mixed_cell: This option can be used to configure whether so called mixed
+# cells, i.e., networks that use both plaintext and encryption in the same
+# SSID, are allowed when selecting a BSS form scan results.
+# 0 = disabled (default)
+# 1 = enabled
+#
+# proactive_key_caching:
+# Enable/disable opportunistic PMKSA caching for WPA2.
+# 0 = disabled (default)
+# 1 = enabled
+#
+# wep_key0..3: Static WEP key (ASCII in double quotation, e.g. "abcde" or
+# hex without quotation, e.g., 0102030405)
+# wep_tx_keyidx: Default WEP key index (TX) (0..3)
+#
+# peerkey: Whether PeerKey negotiation for direct links (IEEE 802.11e DLS) is
+# allowed. This is only used with RSN/WPA2.
+# 0 = disabled (default)
+# 1 = enabled
+#peerkey=1
+#
+# wpa_ptk_rekey: Maximum lifetime for PTK in seconds. This can be used to
+# enforce rekeying of PTK to mitigate some attacks against TKIP deficiencies.
+#
+# Following fields are only used with internal EAP implementation.
+# eap: space-separated list of accepted EAP methods
+# MD5 = EAP-MD5 (unsecure and does not generate keying material ->
+# cannot be used with WPA; to be used as a Phase 2 method
+# with EAP-PEAP or EAP-TTLS)
+# MSCHAPV2 = EAP-MSCHAPv2 (cannot be used separately with WPA; to be used
+# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
+# OTP = EAP-OTP (cannot be used separately with WPA; to be used
+# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
+# GTC = EAP-GTC (cannot be used separately with WPA; to be used
+# as a Phase 2 method with EAP-PEAP or EAP-TTLS)
+# TLS = EAP-TLS (client and server certificate)
+# PEAP = EAP-PEAP (with tunnelled EAP authentication)
+# TTLS = EAP-TTLS (with tunnelled EAP or PAP/CHAP/MSCHAP/MSCHAPV2
+# authentication)
+# If not set, all compiled in methods are allowed.
+#
+# identity: Identity string for EAP
+# This field is also used to configure user NAI for
+# EAP-PSK/PAX/SAKE/GPSK.
+# anonymous_identity: Anonymous identity string for EAP (to be used as the
+# unencrypted identity with EAP types that support different tunnelled
+# identity, e.g., EAP-TTLS)
+# password: Password string for EAP. This field can include either the
+# plaintext password (using ASCII or hex string) or a NtPasswordHash
+# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
+# NtPasswordHash can only be used when the password is for MSCHAPv2 or
+# MSCHAP (EAP-MSCHAPv2, EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
+# EAP-PSK (128-bit PSK), EAP-PAX (128-bit PSK), and EAP-SAKE (256-bit
+# PSK) is also configured using this field. For EAP-GPSK, this is a
+# variable length PSK.
+# ca_cert: File path to CA certificate file (PEM/DER). This file can have one
+# or more trusted CA certificates. If ca_cert and ca_path are not
+# included, server certificate will not be verified. This is insecure and
+# a trusted CA certificate should always be configured when using
+# EAP-TLS/TTLS/PEAP. Full path should be used since working directory may
+# change when wpa_supplicant is run in the background.
+# On Windows, trusted CA certificates can be loaded from the system
+# certificate store by setting this to cert_store://<name>, e.g.,
+# ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
+# Note that when running wpa_supplicant as an application, the user
+# certificate store (My user account) is used, whereas computer store
+# (Computer account) is used when running wpasvc as a service.
+# ca_path: Directory path for CA certificate files (PEM). This path may
+# contain multiple CA certificates in OpenSSL format. Common use for this
+# is to point to system trusted CA list which is often installed into
+# directory like /etc/ssl/certs. If configured, these certificates are
+# added to the list of trusted CAs. ca_cert may also be included in that
+# case, but it is not required.
+# client_cert: File path to client certificate file (PEM/DER)
+# Full path should be used since working directory may change when
+# wpa_supplicant is run in the background.
+# Alternatively, a named configuration blob can be used by setting this
+# to blob://<blob name>.
+# private_key: File path to client private key file (PEM/DER/PFX)
+# When PKCS#12/PFX file (.p12/.pfx) is used, client_cert should be
+# commented out. Both the private key and certificate will be read from
+# the PKCS#12 file in this case. Full path should be used since working
+# directory may change when wpa_supplicant is run in the background.
+# Windows certificate store can be used by leaving client_cert out and
+# configuring private_key in one of the following formats:
+# cert://substring_to_match
+# hash://certificate_thumbprint_in_hex
+# for example: private_key="hash://63093aa9c47f56ae88334c7b65a4"
+# Note that when running wpa_supplicant as an application, the user
+# certificate store (My user account) is used, whereas computer store
+# (Computer account) is used when running wpasvc as a service.
+# Alternatively, a named configuration blob can be used by setting this
+# to blob://<blob name>.
+# private_key_passwd: Password for private key file (if left out, this will be
+# asked through control interface)
+# dh_file: File path to DH/DSA parameters file (in PEM format)
+# This is an optional configuration file for setting parameters for an
+# ephemeral DH key exchange. In most cases, the default RSA
+# authentication does not use this configuration. However, it is possible
+# setup RSA to use ephemeral DH key exchange. In addition, ciphers with
+# DSA keys always use ephemeral DH keys. This can be used to achieve
+# forward secrecy. If the file is in DSA parameters format, it will be
+# automatically converted into DH params.
+# subject_match: Substring to be matched against the subject of the
+# authentication server certificate. If this string is set, the server
+# sertificate is only accepted if it contains this string in the subject.
+# The subject string is in following format:
+# /C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com
+# altsubject_match: Semicolon separated string of entries to be matched against
+# the alternative subject name of the authentication server certificate.
+# If this string is set, the server sertificate is only accepted if it
+# contains one of the entries in an alternative subject name extension.
+# altSubjectName string is in following format: TYPE:VALUE
+# Example: EMAIL:server@example.com
+# Example: DNS:server.example.com;DNS:server2.example.com
+# Following types are supported: EMAIL, DNS, URI
+# phase1: Phase1 (outer authentication, i.e., TLS tunnel) parameters
+# (string with field-value pairs, e.g., "peapver=0" or
+# "peapver=1 peaplabel=1")
+# 'peapver' can be used to force which PEAP version (0 or 1) is used.
+# 'peaplabel=1' can be used to force new label, "client PEAP encryption",
+# to be used during key derivation when PEAPv1 or newer. Most existing
+# PEAPv1 implementation seem to be using the old label, "client EAP
+# encryption", and wpa_supplicant is now using that as the default value.
+# Some servers, e.g., Radiator, may require peaplabel=1 configuration to
+# interoperate with PEAPv1; see eap_testing.txt for more details.
+# 'peap_outer_success=0' can be used to terminate PEAP authentication on
+# tunneled EAP-Success. This is required with some RADIUS servers that
+# implement draft-josefsson-pppext-eap-tls-eap-05.txt (e.g.,
+# Lucent NavisRadius v4.4.0 with PEAP in "IETF Draft 5" mode)
+# include_tls_length=1 can be used to force wpa_supplicant to include
+# TLS Message Length field in all TLS messages even if they are not
+# fragmented.
+# sim_min_num_chal=3 can be used to configure EAP-SIM to require three
+# challenges (by default, it accepts 2 or 3)
+# result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
+# protected result indication.
+# 'crypto_binding' option can be used to control PEAPv0 cryptobinding
+# behavior:
+# * 0 = do not use cryptobinding (default)
+# * 1 = use cryptobinding if server supports it
+# * 2 = require cryptobinding
+# EAP-WSC (WPS) uses following options: pin=<Device Password> or
+# pbc=1.
+# phase2: Phase2 (inner authentication with TLS tunnel) parameters
+# (string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
+# "autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS)
+# Following certificate/private key fields are used in inner Phase2
+# authentication when using EAP-TTLS or EAP-PEAP.
+# ca_cert2: File path to CA certificate file. This file can have one or more
+# trusted CA certificates. If ca_cert2 and ca_path2 are not included,
+# server certificate will not be verified. This is insecure and a trusted
+# CA certificate should always be configured.
+# ca_path2: Directory path for CA certificate files (PEM)
+# client_cert2: File path to client certificate file
+# private_key2: File path to client private key file
+# private_key2_passwd: Password for private key file
+# dh_file2: File path to DH/DSA parameters file (in PEM format)
+# subject_match2: Substring to be matched against the subject of the
+# authentication server certificate.
+# altsubject_match2: Substring to be matched against the alternative subject
+# name of the authentication server certificate.
+#
+# fragment_size: Maximum EAP fragment size in bytes (default 1398).
+# This value limits the fragment size for EAP methods that support
+# fragmentation (e.g., EAP-TLS and EAP-PEAP). This value should be set
+# small enough to make the EAP messages fit in MTU of the network
+# interface used for EAPOL. The default value is suitable for most
+# cases.
+#
+# EAP-FAST variables:
+# pac_file: File path for the PAC entries. wpa_supplicant will need to be able
+# to create this file and write updates to it when PAC is being
+# provisioned or refreshed. Full path to the file should be used since
+# working directory may change when wpa_supplicant is run in the
+# background. Alternatively, a named configuration blob can be used by
+# setting this to blob://<blob name>
+# phase1: fast_provisioning option can be used to enable in-line provisioning
+# of EAP-FAST credentials (PAC):
+# 0 = disabled,
+# 1 = allow unauthenticated provisioning,
+# 2 = allow authenticated provisioning,
+# 3 = allow both unauthenticated and authenticated provisioning
+# fast_max_pac_list_len=<num> option can be used to set the maximum
+# number of PAC entries to store in a PAC list (default: 10)
+# fast_pac_format=binary option can be used to select binary format for
+# storing PAC entries in order to save some space (the default
+# text format uses about 2.5 times the size of minimal binary
+# format)
+#
+# wpa_supplicant supports number of "EAP workarounds" to work around
+# interoperability issues with incorrectly behaving authentication servers.
+# These are enabled by default because some of the issues are present in large
+# number of authentication servers. Strict EAP conformance mode can be
+# configured by disabling workarounds with eap_workaround=0.
+
+# Example blocks:
+
+# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
+network={
+ ssid="simple"
+ psk="very secret passphrase"
+ priority=5
+}
+
+# Same as previous, but request SSID-specific scanning (for APs that reject
+# broadcast SSID)
+network={
+ ssid="second ssid"
+ scan_ssid=1
+ psk="very secret passphrase"
+ priority=2
+}
+
+# Only WPA-PSK is used. Any valid cipher combination is accepted.
+network={
+ ssid="example"
+ proto=WPA
+ key_mgmt=WPA-PSK
+ pairwise=CCMP TKIP
+ group=CCMP TKIP WEP104 WEP40
+ psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
+ priority=2
+}
+
+# WPA-Personal(PSK) with TKIP and enforcement for frequent PTK rekeying
+network={
+ ssid="example"
+ proto=WPA
+ key_mgmt=WPA-PSK
+ pairwise=TKIP
+ group=TKIP
+ psk="not so secure passphrase"
+ wpa_ptk_rekey=600
+}
+
+# Only WPA-EAP is used. Both CCMP and TKIP is accepted. An AP that used WEP104
+# or WEP40 as the group cipher will not be accepted.
+network={
+ ssid="example"
+ proto=RSN
+ key_mgmt=WPA-EAP
+ pairwise=CCMP TKIP
+ group=CCMP TKIP
+ eap=TLS
+ identity="user@example.com"
+ ca_cert="/etc/cert/ca.pem"
+ client_cert="/etc/cert/user.pem"
+ private_key="/etc/cert/user.prv"
+ private_key_passwd="password"
+ priority=1
+}
+
+# EAP-PEAP/MSCHAPv2 configuration for RADIUS servers that use the new peaplabel
+# (e.g., Radiator)
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=PEAP
+ identity="user@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ phase1="peaplabel=1"
+ phase2="auth=MSCHAPV2"
+ priority=10
+}
+
+# EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the
+# unencrypted use. Real identity is sent only within an encrypted TLS tunnel.
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ identity="user@example.com"
+ anonymous_identity="anonymous@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ priority=2
+}
+
+# EAP-TTLS/MSCHAPv2 configuration with anonymous identity for the unencrypted
+# use. Real identity is sent only within an encrypted TLS tunnel.
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ identity="user@example.com"
+ anonymous_identity="anonymous@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ phase2="auth=MSCHAPV2"
+}
+
+# WPA-EAP, EAP-TTLS with different CA certificate used for outer and inner
+# authentication.
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ # Phase1 / outer authentication
+ anonymous_identity="anonymous@example.com"
+ ca_cert="/etc/cert/ca.pem"
+ # Phase 2 / inner authentication
+ phase2="autheap=TLS"
+ ca_cert2="/etc/cert/ca2.pem"
+ client_cert2="/etc/cer/user.pem"
+ private_key2="/etc/cer/user.prv"
+ private_key2_passwd="password"
+ priority=2
+}
+
+# Both WPA-PSK and WPA-EAP is accepted. Only CCMP is accepted as pairwise and
+# group cipher.
+network={
+ ssid="example"
+ bssid=00:11:22:33:44:55
+ proto=WPA RSN
+ key_mgmt=WPA-PSK WPA-EAP
+ pairwise=CCMP
+ group=CCMP
+ psk=06b4be19da289f475aa46a33cb793029d4ab3db7a23ee92382eb0106c72ac7bb
+}
+
+# Special characters in SSID, so use hex string. Default to WPA-PSK, WPA-EAP
+# and all valid ciphers.
+network={
+ ssid=00010203
+ psk=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
+}
+
+
+# EAP-SIM with a GSM SIM or USIM
+network={
+ ssid="eap-sim-test"
+ key_mgmt=WPA-EAP
+ eap=SIM
+ pin="1234"
+ pcsc=""
+}
+
+
+# EAP-PSK
+network={
+ ssid="eap-psk-test"
+ key_mgmt=WPA-EAP
+ eap=PSK
+ anonymous_identity="eap_psk_user"
+ password=06b4be19da289f475aa46a33cb793029
+ identity="eap_psk_user@example.com"
+}
+
+
+# IEEE 802.1X/EAPOL with dynamically generated WEP keys (i.e., no WPA) using
+# EAP-TLS for authentication and key generation; require both unicast and
+# broadcast WEP keys.
+network={
+ ssid="1xtest"
+ key_mgmt=IEEE8021X
+ eap=TLS
+ identity="user@example.com"
+ ca_cert="/etc/cert/ca.pem"
+ client_cert="/etc/cert/user.pem"
+ private_key="/etc/cert/user.prv"
+ private_key_passwd="password"
+ eapol_flags=3
+}
+
+
+# LEAP with dynamic WEP keys
+network={
+ ssid="leap-example"
+ key_mgmt=IEEE8021X
+ eap=LEAP
+ identity="user"
+ password="foobar"
+}
+
+# EAP-IKEv2 using shared secrets for both server and peer authentication
+network={
+ ssid="ikev2-example"
+ key_mgmt=WPA-EAP
+ eap=IKEV2
+ identity="user"
+ password="foobar"
+}
+
+# EAP-FAST with WPA (WPA or WPA2)
+network={
+ ssid="eap-fast-test"
+ key_mgmt=WPA-EAP
+ eap=FAST
+ anonymous_identity="FAST-000102030405"
+ identity="username"
+ password="password"
+ phase1="fast_provisioning=1"
+ pac_file="/etc/wpa_supplicant.eap-fast-pac"
+}
+
+network={
+ ssid="eap-fast-test"
+ key_mgmt=WPA-EAP
+ eap=FAST
+ anonymous_identity="FAST-000102030405"
+ identity="username"
+ password="password"
+ phase1="fast_provisioning=1"
+ pac_file="blob://eap-fast-pac"
+}
+
+# Plaintext connection (no WPA, no IEEE 802.1X)
+network={
+ ssid="plaintext-test"
+ key_mgmt=NONE
+}
+
+
+# Shared WEP key connection (no WPA, no IEEE 802.1X)
+network={
+ ssid="static-wep-test"
+ key_mgmt=NONE
+ wep_key0="abcde"
+ wep_key1=0102030405
+ wep_key2="1234567890123"
+ wep_tx_keyidx=0
+ priority=5
+}
+
+
+# Shared WEP key connection (no WPA, no IEEE 802.1X) using Shared Key
+# IEEE 802.11 authentication
+network={
+ ssid="static-wep-test2"
+ key_mgmt=NONE
+ wep_key0="abcde"
+ wep_key1=0102030405
+ wep_key2="1234567890123"
+ wep_tx_keyidx=0
+ priority=5
+ auth_alg=SHARED
+}
+
+
+# IBSS/ad-hoc network with WPA-None/TKIP.
+network={
+ ssid="test adhoc"
+ mode=1
+ frequency=2412
+ proto=WPA
+ key_mgmt=WPA-NONE
+ pairwise=NONE
+ group=TKIP
+ psk="secret passphrase"
+}
+
+
+# Catch all example that allows more or less all configuration modes
+network={
+ ssid="example"
+ scan_ssid=1
+ key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
+ pairwise=CCMP TKIP
+ group=CCMP TKIP WEP104 WEP40
+ psk="very secret passphrase"
+ eap=TTLS PEAP TLS
+ identity="user@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ client_cert="/etc/cert/user.pem"
+ private_key="/etc/cert/user.prv"
+ private_key_passwd="password"
+ phase1="peaplabel=0"
+}
+
+# Example of EAP-TLS with smartcard (openssl engine)
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=TLS
+ proto=RSN
+ pairwise=CCMP TKIP
+ group=CCMP TKIP
+ identity="user@example.com"
+ ca_cert="/etc/cert/ca.pem"
+ client_cert="/etc/cert/user.pem"
+
+ engine=1
+
+ # The engine configured here must be available. Look at
+ # OpenSSL engine support in the global section.
+ # The key available through the engine must be the private key
+ # matching the client certificate configured above.
+
+ # use the opensc engine
+ #engine_id="opensc"
+ #key_id="45"
+
+ # use the pkcs11 engine
+ engine_id="pkcs11"
+ key_id="id_45"
+
+ # Optional PIN configuration; this can be left out and PIN will be
+ # asked through the control interface
+ pin="1234"
+}
+
+# Example configuration showing how to use an inlined blob as a CA certificate
+# data instead of using external file
+network={
+ ssid="example"
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ identity="user@example.com"
+ anonymous_identity="anonymous@example.com"
+ password="foobar"
+ ca_cert="blob://exampleblob"
+ priority=20
+}
+
+blob-base64-exampleblob={
+SGVsbG8gV29ybGQhCg==
+}
+
+
+# Wildcard match for SSID (plaintext APs only). This example select any
+# open AP regardless of its SSID.
+network={
+ key_mgmt=NONE
+}
+network={
+ ssid="myxjtu2"
+ scan_ssid=1
+ key_mgmt=WPA-PSK
+ psk="xjtudlc3731"
+ disabled=0
+ key_mgmt=NONE
+ wep_key0="12345"
+ wep_key1=1234567890
+ wep_key2="zxcvb"
+ wep_tx_keyidx=1
+ auth_alg=OPEN
+ mode=1
+}
+network={
+ ssid=ab3ace
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ identity="user@example.com"
+ anonymous_identity="anonymous@example.com"
+ password="foobar"
+ ca_cert="blob://exampleblob"
+ priority=20
+}
diff --git a/src/settings/plugins/ifnet/wpa_parser.c b/src/settings/plugins/ifnet/wpa_parser.c
new file mode 100644
index 000000000..da2bc3bb9
--- /dev/null
+++ b/src/settings/plugins/ifnet/wpa_parser.c
@@ -0,0 +1,566 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <nm-system-config-interface.h>
+#include "wpa_parser.h"
+#include "net_parser.h"
+#include "net_utils.h"
+
+/* Security information */
+static GHashTable *wsec_table = NULL;
+
+/* Global information used for writing */
+static GHashTable *wsec_global_table = NULL;
+
+static gboolean wpa_parser_data_changed = FALSE;
+
+static long
+wpa_get_long (GHashTable *table, const char *key)
+{
+ return atol (g_hash_table_lookup (table, key));
+}
+
+static void
+destroy_security (GHashTable * network)
+{
+ gpointer key, value;
+ GHashTableIter iter;
+
+ g_return_if_fail (network);
+ g_hash_table_iter_init (&iter, network);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_free (key);
+ g_free (value);
+ }
+
+ g_hash_table_destroy (network);
+}
+
+static GHashTable *
+add_security (GHashTable *security)
+{
+ GHashTable *oldsecurity;
+ const char *ssid, *value;
+ char *ssid_key;
+ gboolean is_hex_ssid;
+
+ /* Every security information should have a ssid */
+ ssid = g_hash_table_lookup (security, "ssid");
+ if (!ssid) {
+ destroy_security (security);
+ return NULL;
+ }
+
+ /* Hex format begins with " */
+ is_hex_ssid = (ssid[0] != '"');
+ if ((value = g_hash_table_lookup (security, "disabled")) != NULL) {
+ if (strcmp (value, "1") == 0)
+ return NULL;
+ }
+
+ /* Default priority is 1 */
+ if (g_hash_table_lookup (security, "priority") == NULL)
+ g_hash_table_insert (security, g_strdup ("priority"),
+ g_strdup ("1"));
+
+ oldsecurity = g_hash_table_lookup (wsec_table, ssid);
+ /* Security with lower priority will be ignored */
+ if (oldsecurity != NULL) {
+ if (wpa_get_long (oldsecurity, "priority") >=
+ wpa_get_long (security, "priority")) {
+ destroy_security (security);
+ return NULL;
+ } else {
+ g_hash_table_remove (wsec_table, ssid);
+ destroy_security (oldsecurity);
+ }
+ }
+
+ /* format ssid */
+ ssid_key =
+ is_hex_ssid ? g_strdup_printf ("0x%s",
+ ssid) :
+ strip_string (g_strdup (ssid), '"');
+ g_hash_table_insert (wsec_table, ssid_key, security);
+ return security;
+}
+
+static void
+add_key_value (GHashTable * network, gchar * line)
+{
+ gchar **key_value;
+
+ if (g_str_has_prefix (line, "network={"))
+ line += 9;
+ strip_string (line, '{');
+ strip_string (line, '}');
+ if (line[0] == '\0')
+ return;
+ key_value = g_strsplit (line, "=", 2);
+ if (g_strv_length (key_value) != 2) {
+ g_strfreev (key_value);
+ return;
+ }
+ g_strstrip (key_value[0]);
+ g_strstrip (key_value[1]);
+
+ /* Reserve quotes for psk, wep_key, ssid
+ * Quotes will determine whether they are hex format */
+ if (strcmp (key_value[0], "psk") != 0
+ && !g_str_has_prefix (key_value[0], "wep_key")
+ && strcmp (key_value[0], "ssid") != 0)
+ strip_string (key_value[1], '"');
+ g_hash_table_insert (network, g_strdup (key_value[0]),
+ g_strdup (key_value[1]));
+ g_strfreev (key_value);
+}
+
+static void
+add_one_wep_key (GHashTable * table, int key_num, gchar * one_wep_key)
+{
+ if (one_wep_key[0] == 's') {
+ //asc key
+ g_hash_table_insert (table,
+ g_strdup_printf ("wep_key%d", key_num - 1),
+ g_strdup_printf ("\"%s\"",
+ one_wep_key + 2));
+ } else {
+ gchar buf[30];
+ int i = 0, j = 0;
+
+ //hex key
+ while (one_wep_key[i] != '\0') {
+ if (one_wep_key[i] != '-')
+ buf[j++] = one_wep_key[i];
+ i++;
+ }
+ buf[j] = '\0';
+ g_hash_table_insert (table,
+ g_strdup_printf ("wep_key%d", key_num - 1),
+ g_strdup (buf));
+
+ }
+}
+
+/* Reading wep security information from /etc/conf.d/net.
+ * This should not be used in futre, use wpa_supplicant instead. */
+static void
+add_keys_from_net ()
+{
+ GList *names = ifnet_get_connection_names ();
+ GList *iter = names;
+ gchar *wep_keys = "(\\[([1-4])\\]\\s+(s:\\w{5}|s:\\w{13}|"
+ "([\\da-fA-F]{4}\\-){2}[\\da-fA-F]{2}|"
+ "([\\da-fA-F]{4}\\-){6}[\\da-fA-F]{2})\\s+)";
+ gchar *key_method =
+ "\\s+key\\s+\\[([1-4])\\]\\s+enc\\s+(open|restricted)";
+ GRegex *regex_keys = g_regex_new (wep_keys, 0, 0, NULL);
+ GRegex *regex_method = g_regex_new (key_method, 0, 0, NULL);
+ GMatchInfo *keys_info;
+ GMatchInfo *method_info;
+
+ while (iter) {
+ gchar *conn_name = iter->data;
+ GHashTable *table;
+ const char *key_str;
+
+ if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) {
+ iter = g_list_next (iter);
+ continue;
+ }
+
+ wpa_add_security (conn_name);
+ table = _get_hash_table (conn_name);
+ /* Give lowest priority */
+ wpa_set_data (conn_name, "priority", "0");
+ g_regex_match (regex_keys, key_str, 0, &keys_info);
+ /* add wep keys */
+ while (g_match_info_matches (keys_info)) {
+ gchar *key_num = g_match_info_fetch (keys_info, 2);
+ gchar *one_wep_key = g_match_info_fetch (keys_info, 3);
+
+ add_one_wep_key (table, atoi (key_num), one_wep_key);
+ g_free (key_num);
+ g_free (one_wep_key);
+ g_match_info_next (keys_info, NULL);
+ }
+ g_match_info_free (keys_info);
+
+ g_regex_match (regex_method, key_str, 0, &method_info);
+ /* set default key index and auth alg */
+ if (g_match_info_matches (method_info)) {
+ gchar *default_idx =
+ g_match_info_fetch (method_info, 1);
+ gchar *method = g_match_info_fetch (method_info, 2);
+
+ default_idx[0]--;
+ g_hash_table_insert (table, g_strdup ("wep_tx_keyidx"),
+ default_idx);
+ g_hash_table_insert (table, g_strdup ("auth_alg"),
+ g_ascii_strup (method, -1));
+ }
+ g_match_info_free (method_info);
+ add_security (table);
+ iter = g_list_next (iter);
+ }
+ g_list_free (names);
+ g_regex_unref (regex_keys);
+ g_regex_unref (regex_method);
+}
+
+static void
+add_global_data (gchar * line)
+{
+ gchar **key_value;
+
+ g_strstrip (line);
+ key_value = g_strsplit (line, "=", 2);
+ if (g_strv_length (key_value) != 2) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle this line: %s\n",
+ line);
+ g_strfreev (key_value);
+ return;
+ }
+ g_hash_table_insert (wsec_global_table,
+ g_strdup (g_strstrip (key_value[0])),
+ g_strdup (g_strstrip (key_value[1])));
+ g_strfreev (key_value);
+}
+
+void
+wpa_parser_init (const char *wpa_supplicant_conf)
+{
+ GIOChannel *channel = NULL;
+ gchar *line;
+ gboolean complete = FALSE;
+
+ wpa_parser_data_changed = FALSE;
+ wsec_table = g_hash_table_new (g_str_hash, g_str_equal);
+ wsec_global_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if (g_file_test (wpa_supplicant_conf, G_FILE_TEST_IS_REGULAR))
+ channel =
+ g_io_channel_new_file (wpa_supplicant_conf, "r", NULL);
+ if (channel == NULL) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Can't open %s for wireless security",
+ wpa_supplicant_conf);
+ return;
+ }
+
+ while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL)
+ != G_IO_STATUS_EOF) {
+ g_strstrip (line);
+ if (line[0] != '#' && line[0] != '\0') {
+ if (strstr (line, "network={") == NULL) {
+ add_global_data (line);
+ g_free (line);
+ continue;
+ } else {
+ GHashTable *network =
+ g_hash_table_new (g_str_hash, g_str_equal);
+ gchar *tmp;
+
+ do {
+ if (line[0] == '#' || line[0] == '\0') {
+ g_free (line);
+ continue;
+ }
+ /* ignore inline comments */
+ if ((tmp = strchr (line, '#')) != NULL)
+ *tmp = '\0';
+ if (strstr (line, "}") != NULL)
+ complete = TRUE;
+ add_key_value (network, line);
+ g_free (line);
+ } while (complete == FALSE
+ &&
+ g_io_channel_read_line
+ (channel, &line, NULL,
+ NULL, NULL) != G_IO_STATUS_EOF);
+ add_security (network);
+ //EOF in inner loop
+ if (complete == FALSE) {
+ g_free (line);
+ break;
+ }
+ complete = FALSE;
+ }
+ } else
+ g_free (line);
+ }
+
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+
+ add_keys_from_net ();
+}
+
+const char *
+wpa_get_value (const char *ssid, const char *key)
+{
+ GHashTable *target = g_hash_table_lookup (wsec_table, ssid);
+
+ if (target)
+ return g_hash_table_lookup (target, key);
+ return NULL;
+}
+
+gboolean
+exist_ssid (const char *ssid)
+{
+ return g_hash_table_lookup (wsec_table, ssid) != NULL;
+}
+
+GHashTable *
+_get_hash_table (const char *ssid)
+{
+ return g_hash_table_lookup (wsec_table, ssid);
+}
+
+static gchar *quoted_keys[] =
+ { "identity", "cert", "private", "phase", "password", NULL };
+
+/* tell whether the key needs quotes when writing is performed */
+static gboolean
+need_quote (gchar * key)
+{
+ int i = 0;
+
+ while (quoted_keys[i] != NULL) {
+ if (strstr (key, quoted_keys[i]))
+ return TRUE;
+ i++;
+ }
+ return FALSE;
+}
+
+gboolean
+wpa_flush_to_file (const char *config_file)
+{
+ GIOChannel *channel;
+ GError **error = NULL;
+ gpointer key, value, ssid, security;
+ GHashTableIter iter, iter_security;
+ gchar *out_line;
+ gsize bytes_written;
+ gboolean result = FALSE;
+
+ if (!wpa_parser_data_changed)
+ return TRUE;
+ if (!wsec_table || !wsec_global_table)
+ return FALSE;
+
+ channel = g_io_channel_new_file (config_file, "w", NULL);
+ if (!channel) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME,
+ "Can't open file %s for writing", config_file);
+ return FALSE;
+ }
+ g_hash_table_iter_init (&iter, wsec_global_table);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Writing to %s", config_file);
+ g_io_channel_write_chars (channel,
+ "#Generated by NetworkManager\n"
+ "###### Global Configuration ######\n",
+ -1, &bytes_written, error);
+
+ /* Writing global information */
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ out_line =
+ g_strdup_printf ("%s=%s\n", (gchar *) key, (gchar *) value);
+ g_io_channel_write_chars (channel, out_line, -1, &bytes_written,
+ error);
+ if (bytes_written == 0 || (error && *error))
+ break;
+ g_free (out_line);
+ }
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
+ (*error)->message);
+ goto done;
+ }
+ g_io_channel_write_chars (channel,
+ "\n###### Security Configuration ######\n",
+ -1, &bytes_written, error);
+
+ g_hash_table_iter_init (&iter, wsec_table);
+ /* Writing security */
+ while (g_hash_table_iter_next (&iter, &ssid, &security)) {
+ g_hash_table_iter_init (&iter_security,
+ (GHashTable *) security);
+ g_io_channel_write_chars (channel, "network={\n", -1,
+ &bytes_written, error);
+ while (g_hash_table_iter_next (&iter_security, &key, &value)) {
+ out_line =
+ g_strdup_printf (need_quote ((gchar *) key) ?
+ "\t%s=\"%s\"\n" : "\t%s=%s\n",
+ (gchar *) key, (gchar *) value);
+ g_io_channel_write_chars (channel, out_line, -1,
+ &bytes_written, error);
+ if (bytes_written == 0 || (error && *error))
+ break;
+ g_free (out_line);
+ }
+ g_io_channel_write_chars (channel,
+ "}\n\n", -1, &bytes_written, error);
+
+ }
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
+ (*error)->message);
+ goto done;
+ }
+ g_io_channel_flush (channel, error);
+
+ if (error && *error) {
+ PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s",
+ (*error)->message);
+ goto done;
+ }
+ wpa_parser_data_changed = FALSE;
+ result = TRUE;
+done:
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+ return result;
+}
+
+/* If value is NULL, this method will delete old key value pair */
+void
+wpa_set_data (const char *ssid, const char *key, const char *value)
+{
+ gpointer old_key = NULL, old_value = NULL;
+ GHashTable *security = g_hash_table_lookup (wsec_table, ssid);
+ gchar * stripped = NULL;
+
+ g_return_if_fail (security != NULL);
+
+ if (value){
+ stripped = g_strdup(value);
+ if (strcmp (key, "ssid") != 0 && strcmp (key, "psk") != 0
+ && !g_str_has_prefix (key, "wep_key"))
+ strip_string (stripped, '"');
+ }
+
+ /* Remove old key value pairs */
+ if (g_hash_table_lookup_extended
+ (security, key, &old_key, &old_value)) {
+ if (stripped && !strcmp(old_value, stripped)){
+ g_free (stripped);
+ return;
+ }
+ g_hash_table_remove (security, old_key);
+ g_free (old_key);
+ g_free (old_value);
+ } else if (!value)
+ return;
+
+ /* Add new key value */
+ if (stripped)
+ g_hash_table_insert (security, g_strdup (key), stripped);
+ wpa_parser_data_changed = TRUE;
+}
+
+gboolean
+wpa_has_security (const char *ssid)
+{
+ return g_hash_table_lookup (wsec_table, ssid) != NULL;
+}
+
+gboolean
+wpa_add_security (const char *ssid)
+{
+ if (wpa_has_security (ssid))
+ return TRUE;
+ else {
+ GHashTable *security =
+ g_hash_table_new (g_str_hash, g_str_equal);
+ gchar *ssid_i;
+
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding security for %s",
+ ssid);
+ if (g_str_has_prefix (ssid, "0x")) {
+ /* hex ssid */
+ ssid_i = g_strdup (ssid + 2);
+ } else {
+ /* ascii ssid requires quotes */
+ ssid_i = g_strdup_printf ("\"%s\"", ssid);
+ }
+ g_hash_table_insert (security, strdup ("ssid"), ssid_i);
+ g_hash_table_insert (security, strdup ("priority"),
+ strdup ("1"));
+ g_hash_table_insert (wsec_table, g_strdup (ssid), security);
+ wpa_parser_data_changed = TRUE;
+ return TRUE;
+ }
+}
+
+gboolean
+wpa_delete_security (const char *ssid)
+{
+ gpointer old_key, old_value;
+
+ g_return_val_if_fail (wsec_table != NULL && ssid != NULL, FALSE);
+ PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Deleting security for %s", ssid);
+ if (!g_hash_table_lookup_extended
+ (wsec_table, ssid, &old_key, &old_value))
+ return FALSE;
+ g_hash_table_remove (wsec_table, old_key);
+ g_free (old_key);
+ destroy_security ((GHashTable *) old_value);
+ wpa_parser_data_changed = TRUE;
+ return TRUE;
+
+}
+
+void
+wpa_parser_destroy (void)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ /* Destroy security */
+ if (wsec_table) {
+ g_hash_table_iter_init (&iter, wsec_table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ destroy_security ((GHashTable *) value);
+ g_free (key);
+ }
+
+ g_hash_table_destroy (wsec_table);
+ wsec_table = NULL;
+ }
+
+ /* Destroy global data */
+ if (wsec_global_table) {
+ g_hash_table_iter_init (&iter, wsec_global_table);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_free (key);
+ g_free (value);
+ }
+
+ g_hash_table_destroy (wsec_global_table);
+ wsec_global_table = NULL;
+ }
+}
diff --git a/src/settings/plugins/ifnet/wpa_parser.h b/src/settings/plugins/ifnet/wpa_parser.h
new file mode 100644
index 000000000..7fd77a056
--- /dev/null
+++ b/src/settings/plugins/ifnet/wpa_parser.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Mu Qiao <qiaomuf@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 1999-2010 Gentoo Foundation, Inc.
+ */
+
+#ifndef _WPA_PARSER_H
+#define _WPA_PARSER_H
+#define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant/wpa_supplicant.conf"
+#include <glib.h>
+void wpa_parser_init (const char *wpa_supplicant_conf);
+void wpa_parser_destroy (void);
+
+/* reader functions */
+const char *wpa_get_value (const char *ssid, const char *key);
+gboolean exist_ssid (const char *ssid);
+GHashTable *_get_hash_table (const char *ssid);
+gboolean wpa_has_security (const char *ssid);
+
+/* writer functions */
+gboolean wpa_flush_to_file (const char *config_file);
+void wpa_set_data (const char *ssid, const char *key, const char *value);
+gboolean wpa_add_security (const char *ssid);
+gboolean wpa_delete_security (const char *ssid);
+#endif
diff --git a/src/settings/plugins/ifupdown/Makefile.am b/src/settings/plugins/ifupdown/Makefile.am
new file mode 100644
index 000000000..9f9d02182
--- /dev/null
+++ b/src/settings/plugins/ifupdown/Makefile.am
@@ -0,0 +1,53 @@
+SUBDIRS=. tests
+
+INCLUDES = \
+ -I$(top_srcdir)/src/logging \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util
+
+noinst_LTLIBRARIES = libifupdown-io.la
+
+libifupdown_io_la_SOURCES = \
+ interface_parser.c \
+ interface_parser.h \
+ parser.c \
+ parser.h
+
+libifupdown_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libifupdown_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS)
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la
+
+libnm_settings_plugin_ifupdown_la_SOURCES = \
+ nm-ifupdown-connection.c \
+ nm-ifupdown-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifupdown_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifupdown_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/logging/libnm-logging.la \
+ libifupdown-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GUDEV_LIBS)
+
diff --git a/src/settings/plugins/ifupdown/Makefile.in b/src/settings/plugins/ifupdown/Makefile.in
new file mode 100644
index 000000000..af545df7d
--- /dev/null
+++ b/src/settings/plugins/ifupdown/Makefile.in
@@ -0,0 +1,898 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/ifupdown
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(pkglib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libifupdown_io_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libifupdown_io_la_OBJECTS = libifupdown_io_la-interface_parser.lo \
+ libifupdown_io_la-parser.lo
+libifupdown_io_la_OBJECTS = $(am_libifupdown_io_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnm_settings_plugin_ifupdown_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/logging/libnm-logging.la libifupdown-io.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libnm_settings_plugin_ifupdown_la_OBJECTS = \
+ libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo \
+ libnm_settings_plugin_ifupdown_la-plugin.lo
+libnm_settings_plugin_ifupdown_la_OBJECTS = \
+ $(am_libnm_settings_plugin_ifupdown_la_OBJECTS)
+libnm_settings_plugin_ifupdown_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libnm_settings_plugin_ifupdown_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libifupdown_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifupdown_la_SOURCES)
+DIST_SOURCES = $(libifupdown_io_la_SOURCES) \
+ $(libnm_settings_plugin_ifupdown_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = . tests
+INCLUDES = \
+ -I$(top_srcdir)/src/logging \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(top_srcdir)/libnm-util
+
+noinst_LTLIBRARIES = libifupdown-io.la
+libifupdown_io_la_SOURCES = \
+ interface_parser.c \
+ interface_parser.h \
+ parser.c \
+ parser.h
+
+libifupdown_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libifupdown_io_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS)
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-ifupdown.la
+libnm_settings_plugin_ifupdown_la_SOURCES = \
+ nm-ifupdown-connection.c \
+ nm-ifupdown-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_ifupdown_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -DSYSCONFDIR=\"$(sysconfdir)\"
+
+libnm_settings_plugin_ifupdown_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_ifupdown_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/logging/libnm-logging.la \
+ libifupdown-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GUDEV_LIBS)
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)"
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
+ }
+
+uninstall-pkglibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+ done
+
+clean-pkglibLTLIBRARIES:
+ -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
+ @list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libifupdown-io.la: $(libifupdown_io_la_OBJECTS) $(libifupdown_io_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libifupdown_io_la_OBJECTS) $(libifupdown_io_la_LIBADD) $(LIBS)
+libnm-settings-plugin-ifupdown.la: $(libnm_settings_plugin_ifupdown_la_OBJECTS) $(libnm_settings_plugin_ifupdown_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnm_settings_plugin_ifupdown_la_LINK) -rpath $(pkglibdir) $(libnm_settings_plugin_ifupdown_la_OBJECTS) $(libnm_settings_plugin_ifupdown_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifupdown_io_la-interface_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libifupdown_io_la-parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libifupdown_io_la-interface_parser.lo: interface_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifupdown_io_la-interface_parser.lo -MD -MP -MF $(DEPDIR)/libifupdown_io_la-interface_parser.Tpo -c -o libifupdown_io_la-interface_parser.lo `test -f 'interface_parser.c' || echo '$(srcdir)/'`interface_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifupdown_io_la-interface_parser.Tpo $(DEPDIR)/libifupdown_io_la-interface_parser.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='interface_parser.c' object='libifupdown_io_la-interface_parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifupdown_io_la-interface_parser.lo `test -f 'interface_parser.c' || echo '$(srcdir)/'`interface_parser.c
+
+libifupdown_io_la-parser.lo: parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libifupdown_io_la-parser.lo -MD -MP -MF $(DEPDIR)/libifupdown_io_la-parser.Tpo -c -o libifupdown_io_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libifupdown_io_la-parser.Tpo $(DEPDIR)/libifupdown_io_la-parser.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='parser.c' object='libifupdown_io_la-parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libifupdown_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libifupdown_io_la-parser.lo `test -f 'parser.c' || echo '$(srcdir)/'`parser.c
+
+libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo: nm-ifupdown-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Tpo -c -o libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo `test -f 'nm-ifupdown-connection.c' || echo '$(srcdir)/'`nm-ifupdown-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Tpo $(DEPDIR)/libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-ifupdown-connection.c' object='libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifupdown_la-nm-ifupdown-connection.lo `test -f 'nm-ifupdown-connection.c' || echo '$(srcdir)/'`nm-ifupdown-connection.c
+
+libnm_settings_plugin_ifupdown_la-plugin.lo: plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_ifupdown_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Tpo -c -o libnm_settings_plugin_ifupdown_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_ifupdown_la-plugin.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_ifupdown_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_ifupdown_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_ifupdown_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkglibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pkglibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-pkglibLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkglibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-pkglibLTLIBRARIES ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pkglibLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-pkglibLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c
new file mode 100644
index 000000000..b7c642423
--- /dev/null
+++ b/src/settings/plugins/ifupdown/interface_parser.c
@@ -0,0 +1,307 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * Tom Parker <palfrey@tevp.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2004 Tom Parker
+ */
+
+#include "config.h"
+#include "interface_parser.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "nm-utils.h"
+
+if_block* first;
+if_block* last;
+
+if_data* last_data;
+
+void add_block(const char *type, const char* name)
+{
+ if_block *ret = (if_block*)calloc(1,sizeof(struct _if_block));
+ ret->name = g_strdup(name);
+ ret->type = g_strdup(type);
+ if (first == NULL)
+ first = last = ret;
+ else
+ {
+ last->next = ret;
+ last = ret;
+ }
+ last_data = NULL;
+ //printf("added block '%s' with type '%s'\n",name,type);
+}
+
+void add_data(const char *key,const char *data)
+{
+ if_data *ret;
+ char *idx;
+
+ // Check if there is a block where we can attach our data
+ if (first == NULL)
+ return;
+
+ ret = (if_data*) calloc(1,sizeof(struct _if_data));
+ ret->key = g_strdup(key);
+ // Normalize keys. Convert '_' to '-', as ifupdown accepts both variants.
+ // When querying keys via ifparser_getkey(), use '-'.
+ while ((idx = strrchr(ret->key, '_'))) {
+ *idx = '-';
+ }
+ ret->data = g_strdup(data);
+
+ if (last->info == NULL)
+ {
+ last->info = ret;
+ last_data = ret;
+ }
+ else
+ {
+ last_data->next = ret;
+ last_data = last_data->next;
+ }
+ //printf("added data '%s' with key '%s'\n",data,key);
+}
+
+// join values in src with spaces into dst; dst needs to be large enough
+static char *join_values_with_spaces(char *dst, char **src)
+{
+ if (dst != NULL) {
+ *dst = '\0';
+ if (src != NULL && *src != NULL) {
+ strcat(dst, *src);
+
+ for (src++; *src != NULL; src++) {
+ strcat(dst, " ");
+ strcat(dst, *src);
+ }
+ }
+ }
+ return(dst);
+}
+
+void ifparser_init (const char *eni_file, int quiet)
+{
+ FILE *inp = fopen (eni_file, "r");
+ char line[255];
+ int skip_to_block = 1;
+ int skip_long_line = 0;
+ int offs = 0;
+
+ if (inp == NULL) {
+ if (!quiet)
+ g_warning ("Error: Can't open %s\n", eni_file);
+ return;
+ }
+
+ first = last = NULL;
+ while (!feof(inp))
+ {
+ char *token[128]; // 255 chars can only be split into 127 tokens
+ char value[255]; // large enough to join previously split tokens
+ char *safeptr;
+ int toknum;
+ int len = 0;
+
+ char *ptr = fgets(line+offs, 255-offs, inp);
+ if (ptr == NULL)
+ break;
+
+ len = strlen(line);
+ // skip over-long lines
+ if (!feof(inp) && len > 0 && line[len-1] != '\n') {
+ if (!skip_long_line) {
+ if (!quiet)
+ g_message ("Error: Skipping over-long-line '%s...'\n", line);
+ }
+ skip_long_line = 1;
+ continue;
+ }
+
+ // trailing '\n' found: remove it & reset offset to 0
+ if (len > 0 && line[len-1] == '\n') {
+ line[--len] = '\0';
+ offs = 0;
+ }
+
+ // if we're in long_line_skip mode, terminate it for real next line
+ if (skip_long_line) {
+ if (len == 0 || line[len-1] != '\\')
+ skip_long_line = 0;
+ continue;
+ }
+
+ // unwrap wrapped lines
+ if (len > 0 && line[len-1] == '\\') {
+ offs = len - 1;
+ continue;
+ }
+
+ //printf(">>%s<<\n", line);
+
+#define SPACES " \t"
+ // tokenize input;
+ for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr);
+ token[toknum] != NULL;
+ toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr))
+ ;
+
+ // ignore comments and empty lines
+ if (toknum == 0 || *token[0]=='#')
+ continue;
+
+ if (toknum < 2) {
+ if (!quiet) {
+ g_message ("Error: Can't parse interface line '%s'\n",
+ join_values_with_spaces(value, token));
+ }
+ skip_to_block = 1;
+ continue;
+ }
+
+ // There are four different stanzas:
+ // iface, mapping, auto and allow-*. Create a block for each of them.
+
+ // iface stanza takes at least 3 parameters
+ if (strcmp(token[0], "iface") == 0) {
+ if (toknum < 4) {
+ if (!quiet) {
+ g_message ("Error: Can't parse iface line '%s'\n",
+ join_values_with_spaces(value, token));
+ }
+ continue;
+ }
+ add_block(token[0], token[1]);
+ skip_to_block = 0;
+ add_data(token[2], join_values_with_spaces(value, token + 3));
+ }
+ // auto and allow-auto stanzas are equivalent,
+ // both can take multiple interfaces as parameters: add one block for each
+ else if (strcmp(token[0], "auto") == 0 ||
+ strcmp(token[0], "allow-auto") == 0) {
+ int i;
+ for (i = 1; i < toknum; i++)
+ add_block("auto", token[i]);
+ skip_to_block = 0;
+ }
+ else if (strcmp(token[0], "mapping") == 0) {
+ add_block(token[0], join_values_with_spaces(value, token + 1));
+ skip_to_block = 0;
+ }
+ // allow-* can take multiple interfaces as parameters: add one block for each
+ else if (strncmp(token[0],"allow-",6) == 0) {
+ int i;
+ for (i = 1; i < toknum; i++)
+ add_block(token[0], token[i]);
+ skip_to_block = 0;
+ }
+ else {
+ if (skip_to_block) {
+ if (!quiet) {
+ g_message ("Error: ignoring out-of-block data '%s'\n",
+ join_values_with_spaces(value, token));
+ }
+ } else
+ add_data(token[0], join_values_with_spaces(value, token + 1));
+ }
+ }
+ fclose(inp);
+}
+
+void _destroy_data(if_data *ifd)
+{
+ if (ifd == NULL)
+ return;
+ _destroy_data(ifd->next);
+ free(ifd->key);
+ free(ifd->data);
+ free(ifd);
+ return;
+}
+
+void _destroy_block(if_block* ifb)
+{
+ if (ifb == NULL)
+ return;
+ _destroy_block(ifb->next);
+ _destroy_data(ifb->info);
+ free(ifb->name);
+ free(ifb->type);
+ free(ifb);
+ return;
+}
+
+void ifparser_destroy(void)
+{
+ _destroy_block(first);
+ first = last = NULL;
+}
+
+if_block *ifparser_getfirst(void)
+{
+ return first;
+}
+
+int ifparser_get_num_blocks(void)
+{
+ int i = 0;
+ if_block *iter = first;
+
+ while (iter) {
+ i++;
+ iter = iter->next;
+ }
+ return i;
+}
+
+if_block *ifparser_getif(const char* iface)
+{
+ if_block *curr = first;
+ while(curr!=NULL)
+ {
+ if (strcmp(curr->type,"iface")==0 && strcmp(curr->name,iface)==0)
+ return curr;
+ curr = curr->next;
+ }
+ return NULL;
+}
+
+const char *ifparser_getkey(if_block* iface, const char *key)
+{
+ if_data *curr = iface->info;
+ while(curr!=NULL)
+ {
+ if (strcmp(curr->key,key)==0)
+ return curr->data;
+ curr = curr->next;
+ }
+ return NULL;
+}
+
+int ifparser_get_num_info(if_block* iface)
+{
+ int i = 0;
+ if_data *iter = iface->info;
+
+ while (iter) {
+ i++;
+ iter = iter->next;
+ }
+ return i;
+}
diff --git a/src/settings/plugins/ifupdown/interface_parser.h b/src/settings/plugins/ifupdown/interface_parser.h
new file mode 100644
index 000000000..0c1de23a5
--- /dev/null
+++ b/src/settings/plugins/ifupdown/interface_parser.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * Tom Parker <palfrey@tevp.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2004 Tom Parker
+ */
+
+
+#ifndef _INTERFACE_PARSER_H
+#define _INTERFACE_PARSER_H
+
+typedef struct _if_data
+{
+ char *key;
+ char *data;
+ struct _if_data *next;
+} if_data;
+
+typedef struct _if_block
+{
+ char *type;
+ char *name;
+ if_data *info;
+ struct _if_block *next;
+} if_block;
+
+void ifparser_init(const char *eni_file, int quiet);
+void ifparser_destroy(void);
+
+if_block *ifparser_getif(const char* iface);
+if_block *ifparser_getfirst(void);
+const char *ifparser_getkey(if_block* iface, const char *key);
+int ifparser_get_num_blocks(void);
+int ifparser_get_num_info(if_block* iface);
+
+void add_block(const char *type, const char* name);
+void add_data(const char *key,const char *data);
+void _destroy_data(if_data *ifd);
+void _destroy_block(if_block* ifb);
+#endif
diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.c b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c
new file mode 100644
index 000000000..0cc73b34f
--- /dev/null
+++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007,2008 Canonical Ltd.
+ */
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <NetworkManager.h>
+#include <nm-utils.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-settings-connection.h>
+#include <nm-system-config-interface.h>
+#include <nm-settings-error.h>
+#include "nm-ifupdown-connection.h"
+#include "parser.h"
+
+G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SETTINGS_CONNECTION)
+
+#define NM_IFUPDOWN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionPrivate))
+
+typedef struct {
+ if_block *ifblock;
+} NMIfupdownConnectionPrivate;
+
+enum {
+ PROP_ZERO,
+ PROP_IFBLOCK,
+ _PROP_END,
+};
+
+
+NMIfupdownConnection*
+nm_ifupdown_connection_new (if_block *block)
+{
+ g_return_val_if_fail (block != NULL, NULL);
+
+ return (NMIfupdownConnection *) g_object_new (NM_TYPE_IFUPDOWN_CONNECTION,
+ NM_IFUPDOWN_CONNECTION_IFBLOCK, block,
+ NULL);
+}
+
+static gboolean
+supports_secrets (NMSettingsConnection *connection, const char *setting_name)
+{
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "supports_secrets() for setting_name: '%s'", setting_name);
+
+ return (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0);
+}
+
+static void
+nm_ifupdown_connection_init (NMIfupdownConnection *connection)
+{
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMIfupdownConnectionPrivate *priv;
+ GError *error = NULL;
+
+ object = G_OBJECT_CLASS (nm_ifupdown_connection_parent_class)->constructor (type, n_construct_params, construct_params);
+ g_return_val_if_fail (object, NULL);
+
+ priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object);
+ if (!priv) {
+ g_warning ("%s.%d - no private instance.", __FILE__, __LINE__);
+ goto err;
+ }
+ if (!priv->ifblock) {
+ g_warning ("(ifupdown) ifblock not provided to constructor.");
+ goto err;
+ }
+
+ if (!ifupdown_update_connection_from_if_block (NM_CONNECTION (object), priv->ifblock, &error)) {
+ g_warning ("%s.%d - invalid connection read from /etc/network/interfaces: (%d) %s",
+ __FILE__,
+ __LINE__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ goto err;
+ }
+
+ return object;
+
+ err:
+ g_object_unref (object);
+ return NULL;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMIfupdownConnectionPrivate *priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object);
+ g_return_if_fail (priv);
+
+ switch (prop_id) {
+ case PROP_IFBLOCK:
+ priv->ifblock = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMIfupdownConnectionPrivate *priv = NM_IFUPDOWN_CONNECTION_GET_PRIVATE (object);
+ g_return_if_fail (priv);
+
+ switch (prop_id) {
+ case PROP_IFBLOCK:
+ g_value_set_pointer (value, priv->ifblock);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class);
+ NMSettingsConnectionClass *connection_class = NM_SETTINGS_CONNECTION_CLASS (ifupdown_connection_class);
+
+ g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->constructor = constructor;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+
+ connection_class->supports_secrets = supports_secrets;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_IFBLOCK,
+ g_param_spec_pointer (NM_IFUPDOWN_CONNECTION_IFBLOCK,
+ "ifblock",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
diff --git a/src/settings/plugins/ifupdown/nm-ifupdown-connection.h b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h
new file mode 100644
index 000000000..510a4d56a
--- /dev/null
+++ b/src/settings/plugins/ifupdown/nm-ifupdown-connection.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Canonical Ltd.
+ */
+
+#ifndef NM_IFUPDOWN_CONNECTION_H
+#define NM_IFUPDOWN_CONNECTION_H
+
+#include <nm-settings-connection.h>
+#include "interface_parser.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_IFUPDOWN_CONNECTION (nm_ifupdown_connection_get_type ())
+#define NM_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnection))
+#define NM_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass))
+#define NM_IS_IFUPDOWN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFUPDOWN_CONNECTION))
+#define NM_IS_IFUPDOWN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFUPDOWN_CONNECTION))
+#define NM_IFUPDOWN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionClass))
+
+#define NM_IFUPDOWN_CONNECTION_IFBLOCK "ifblock"
+
+typedef struct {
+ NMSettingsConnection parent;
+} NMIfupdownConnection;
+
+typedef struct {
+ NMSettingsConnectionClass parent;
+} NMIfupdownConnectionClass;
+
+GType nm_ifupdown_connection_get_type (void);
+
+NMIfupdownConnection *nm_ifupdown_connection_new (if_block *block);
+
+G_END_DECLS
+
+#endif /* NM_IFUPDOWN_CONNECTION_H */
diff --git a/src/settings/plugins/ifupdown/parser.c b/src/settings/plugins/ifupdown/parser.c
new file mode 100644
index 000000000..dc2f8abf6
--- /dev/null
+++ b/src/settings/plugins/ifupdown/parser.c
@@ -0,0 +1,577 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Canonical Ltd.
+ */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <nm-connection.h>
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-8021x.h>
+#include <nm-system-config-interface.h>
+#include <nm-utils.h>
+
+#include "parser.h"
+#include "plugin.h"
+
+
+#define WPA_PMK_LEN 32
+
+#include "parser.h"
+
+static const gchar*
+_ifupdownplugin_guess_connection_type (if_block *block)
+{
+ if_data *curr = block->info;
+ const gchar* ret_type = NULL;
+ const gchar* value = ifparser_getkey(block, "inet");
+ if(value && !strcmp("ppp", value)) {
+ ret_type = NM_SETTING_PPP_SETTING_NAME;
+ }
+
+ while(!ret_type && curr) {
+ if(!strncmp("wireless-", curr->key, strlen("wireless-")) ||
+ !strncmp("wpa-", curr->key, strlen("wpa-"))) {
+ ret_type = NM_SETTING_WIRELESS_SETTING_NAME;
+ }
+ curr = curr->next;
+ }
+
+ if(!ret_type)
+ ret_type = NM_SETTING_WIRED_SETTING_NAME;
+
+ PLUGIN_PRINT("SCPluginIfupdown",
+ "guessed connection type (%s) = %s",
+ block->name, ret_type);
+ return ret_type;
+}
+
+
+struct _Mapping {
+ const gchar *domain;
+ const gpointer target;
+};
+
+static gpointer
+map_by_mapping(struct _Mapping *mapping, const gchar *key)
+{
+ struct _Mapping *curr = mapping;
+ while(curr->domain) {
+ if(!strcmp(curr->domain, key))
+ return curr->target;
+ curr++;
+ }
+ return NULL;
+}
+
+static void
+update_wireless_setting_from_if_block(NMConnection *connection,
+ if_block *block)
+{
+ gint wpa_l= strlen("wpa-");
+ gint wireless_l= strlen("wireless-");
+
+ if_data *curr = block->info;
+ const gchar* value = ifparser_getkey (block, "inet");
+ struct _Mapping mapping[] = {
+ {"ssid", "ssid"},
+ { NULL, NULL}
+ };
+
+ NMSettingWireless *wireless_setting = NULL;
+
+ if(value && !strcmp("ppp", value)) {
+ return;
+ }
+
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "update wireless settings (%s).", block->name);
+ wireless_setting = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+
+ while(curr) {
+ if(strlen(curr->key) > wireless_l &&
+ !strncmp("wireless-", curr->key, wireless_l)) {
+ const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "wireless setting key: %s='%s'",
+ newkey, curr->data);
+ if(newkey && !strcmp("ssid", newkey)) {
+ GByteArray *ssid;
+ gint len = strlen(curr->data);
+
+ ssid = g_byte_array_sized_new (len);
+ g_byte_array_append (ssid, (const guint8 *) curr->data, len);
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+ g_byte_array_free (ssid, TRUE);
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "setting wireless ssid = %d", len);
+ } else {
+ g_object_set(wireless_setting,
+ newkey, curr->data,
+ NULL);
+ }
+ } else if(strlen(curr->key) > wpa_l &&
+ !strncmp("wpa-", curr->key, wpa_l)) {
+ const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l);
+
+ if(newkey && !strcmp("ssid", newkey)) {
+ GByteArray *ssid;
+ gint len = strlen(curr->data);
+
+ ssid = g_byte_array_sized_new (len);
+ g_byte_array_append (ssid, (const guint8 *) curr->data, len);
+ g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+ g_byte_array_free (ssid, TRUE);
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "setting wpa ssid = %d", len);
+ } else if(newkey) {
+
+ g_object_set(wireless_setting,
+ newkey, curr->data,
+ NULL);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wpa newkey(%s)=data(%s)", newkey, curr->data);
+ }
+ }
+ curr = curr->next;
+ }
+ nm_connection_add_setting(connection, (NMSetting*) wireless_setting);
+}
+
+typedef gchar* (*IfupdownStrDupeFunc) (gpointer value, gpointer data);
+typedef gpointer (*IfupdownStrToTypeFunc) (const gchar* value);
+
+static char*
+normalize_dupe_wireless_key (gpointer value, gpointer data) {
+ char* valuec = value;
+ char* endc = valuec + strlen (valuec);
+ char* delim = valuec;
+ char* next = delim;
+ char* result = malloc (strlen (valuec) + 1);
+ char* result_cur = result;
+
+ while (*delim && (next = strchr (delim, '-')) != NULL) {
+ if (next == delim) {
+ delim++;
+ continue;
+ }
+ strncpy (result_cur, delim, next - delim);
+ result_cur += next - delim;
+ delim = next + 1;
+ }
+ if (*delim && strlen (valuec) > GPOINTER_TO_UINT(delim - valuec)) {
+ strncpy (result_cur, delim, endc - delim);
+ result_cur += endc - delim;
+ }
+ *result_cur = '\0';
+ return result;
+}
+
+static char*
+normalize_dupe (gpointer value, gpointer data) {
+ return g_strdup(value);
+}
+
+static char*
+normalize_tolower (gpointer value, gpointer data) {
+ return g_ascii_strdown(value, -1);
+}
+
+static char *normalize_psk (gpointer value, gpointer data)
+{
+ if (strlen (value) >= 8 && strlen (value) <= 64)
+ return g_strdup (value);
+ return NULL;
+}
+
+static gpointer
+string_to_gpointerint(const gchar* data)
+{
+ gint result = (gint) strtol (data, NULL, 10);
+ return GINT_TO_POINTER(result);
+}
+
+static gpointer
+string_to_glist_of_strings(const gchar* data)
+{
+ GSList *ret = NULL;
+ gchar *string = (gchar*) data;
+ while(string) {
+ gchar* next = NULL;
+ if( (next = strchr(string, ' ')) ||
+ (next = strchr(string, '\t')) ||
+ (next = strchr(string, '\0')) ) {
+
+ gchar *part = g_strndup(string, (next - string));
+ ret = g_slist_append(ret, part);
+ if (*next)
+ string = next+1;
+ else
+ string = NULL;
+ } else {
+ string = NULL;
+ }
+ }
+ return ret;
+}
+
+static void
+slist_free_all(gpointer slist)
+{
+ GSList *list = (GSList *) slist;
+ g_slist_foreach (list, (GFunc) g_free, NULL);
+ g_slist_free (list);
+}
+
+static void
+update_wireless_security_setting_from_if_block(NMConnection *connection,
+ if_block *block)
+{
+ gint wpa_l= strlen("wpa-");
+ gint wireless_l= strlen("wireless-");
+ if_data *curr = block->info;
+ const gchar* value = ifparser_getkey (block, "inet");
+ struct _Mapping mapping[] = {
+ {"psk", "psk"},
+ {"identity", "leap-username"},
+ {"password", "leap-password"},
+ {"key", "wep-key0"},
+ {"key-mgmt", "key-mgmt"},
+ {"group", "group"},
+ {"pairwise", "pairwise"},
+ {"proto", "proto"},
+ {"pin", "pin"},
+ {"wep-key0", "wep-key0"},
+ {"wep-key1", "wep-key1"},
+ {"wep-key2", "wep-key2"},
+ {"wep-key3", "wep-key3"},
+ {"wep-tx-keyidx", "wep-tx-keyidx"},
+ { NULL, NULL}
+ };
+
+ struct _Mapping dupe_mapping[] = {
+ {"psk", normalize_psk},
+ {"identity", normalize_dupe},
+ {"password", normalize_dupe},
+ {"key", normalize_dupe_wireless_key},
+ {"key-mgmt", normalize_tolower},
+ {"group", normalize_tolower},
+ {"pairwise", normalize_tolower},
+ {"proto", normalize_tolower},
+ {"pin", normalize_dupe},
+ {"wep-key0", normalize_dupe_wireless_key},
+ {"wep-key1", normalize_dupe_wireless_key},
+ {"wep-key2", normalize_dupe_wireless_key},
+ {"wep-key3", normalize_dupe_wireless_key},
+ {"wep-tx-keyidx", normalize_dupe},
+ { NULL, NULL}
+ };
+
+ struct _Mapping type_mapping[] = {
+ {"group", string_to_glist_of_strings},
+ {"pairwise", string_to_glist_of_strings},
+ {"proto", string_to_glist_of_strings},
+ {"wep-tx-keyidx", string_to_gpointerint},
+ { NULL, NULL}
+ };
+
+ struct _Mapping free_type_mapping[] = {
+ {"group", slist_free_all},
+ {"pairwise", slist_free_all},
+ {"proto", slist_free_all},
+ { NULL, NULL}
+ };
+
+ NMSettingWirelessSecurity *wireless_security_setting;
+ NMSettingWireless *s_wireless;
+ gboolean security = FALSE;
+
+ if(value && !strcmp("ppp", value)) {
+ return;
+ }
+
+ s_wireless = NM_SETTING_WIRELESS(nm_connection_get_setting(connection,
+ NM_TYPE_SETTING_WIRELESS));
+ g_return_if_fail(s_wireless);
+
+ PLUGIN_PRINT ("SCPlugin-Ifupdown","update wireless security settings (%s).", block->name);
+ wireless_security_setting =
+ NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new());
+
+ while(curr) {
+ if(strlen(curr->key) > wireless_l &&
+ !strncmp("wireless-", curr->key, wireless_l)) {
+
+ gchar *property_value = NULL;
+ gpointer typed_property_value = NULL;
+ const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l);
+ IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wireless_l);
+ IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wireless_l);
+ GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wireless_l);
+ if(!newkey || !dupe_func) {
+ g_warning("no (wireless) mapping found for key: %s", curr->key);
+ goto next;
+ }
+ property_value = (*dupe_func) (curr->data, connection);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wireless security key: %s=%s",
+ newkey, property_value);
+
+ if (type_map_func) {
+ errno = 0;
+ typed_property_value = (*type_map_func) (property_value);
+ if(errno)
+ goto wireless_next;
+ }
+
+ g_object_set(wireless_security_setting,
+ newkey, typed_property_value ? typed_property_value : property_value,
+ NULL);
+ security = TRUE;
+
+ wireless_next:
+ g_free(property_value);
+ if (typed_property_value && free_func)
+ (*free_func) (typed_property_value);
+
+ } else if(strlen(curr->key) > wpa_l &&
+ !strncmp("wpa-", curr->key, wpa_l)) {
+
+ gchar *property_value = NULL;
+ gpointer typed_property_value = NULL;
+ const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l);
+ IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wpa_l);
+ IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wpa_l);
+ GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wpa_l);
+ if(!newkey || !dupe_func) {
+ goto next;
+ }
+ property_value = (*dupe_func) (curr->data, connection);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "setting wpa security key: %s=%s",
+ newkey,
+#ifdef DEBUG_SECRETS
+ property_value
+#else // DEBUG_SECRETS
+ !strcmp("key", newkey) ||
+ !strcmp("leap-password", newkey) ||
+ !strcmp("pin", newkey) ||
+ !strcmp("psk", newkey) ||
+ !strcmp("wep-key0", newkey) ||
+ !strcmp("wep-key1", newkey) ||
+ !strcmp("wep-key2", newkey) ||
+ !strcmp("wep-key3", newkey) ||
+ NULL ?
+ "<omitted>" : property_value
+#endif // DEBUG_SECRETS
+ );
+
+ if (type_map_func) {
+ errno = 0;
+ typed_property_value = (*type_map_func) (property_value);
+ if(errno)
+ goto wpa_next;
+ }
+
+ g_object_set(wireless_security_setting,
+ newkey, typed_property_value ? typed_property_value : property_value,
+ NULL);
+ security = TRUE;
+
+ wpa_next:
+ g_free(property_value);
+ if (free_func && typed_property_value)
+ (*free_func) (typed_property_value);
+ }
+ next:
+ curr = curr->next;
+ }
+
+
+ if(security) {
+ nm_connection_add_setting(connection, NM_SETTING(wireless_security_setting));
+ g_object_set(s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+ }
+
+}
+
+static void
+update_wired_setting_from_if_block(NMConnection *connection,
+ if_block *block)
+{
+ NMSettingWired *s_wired = NULL;
+ s_wired = NM_SETTING_WIRED(nm_setting_wired_new());
+ nm_connection_add_setting(connection, NM_SETTING(s_wired));
+}
+
+static GQuark
+eni_plugin_error_quark() {
+ static GQuark error_quark = 0;
+
+ if(!error_quark) {
+ error_quark = g_quark_from_static_string ("eni-plugin-error-quark");
+ }
+
+ return error_quark;
+}
+
+
+static void
+update_ip4_setting_from_if_block(NMConnection *connection,
+ if_block *block)
+{
+
+ NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new());
+ const char *type = ifparser_getkey(block, "inet");
+ gboolean is_static = type && !strcmp("static", type);
+
+ if(!is_static) {
+ g_object_set(ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+ } else {
+ struct in_addr tmp_ip4_addr;
+ NMIP4Address *ip4_addr = nm_ip4_address_new ();
+
+ const char *address_v = ifparser_getkey(block, "address");
+ const char *netmask_v = ifparser_getkey(block, "netmask");
+ const char *gateway_v = ifparser_getkey(block, "gateway");
+ const char *nameserver_v = ifparser_getkey(block, "dns-nameserver");
+ const char *nameservers_v = ifparser_getkey(block, "dns-nameservers");
+ GSList* nameservers_list = NULL;
+ GSList* nameservers_list_i = NULL;
+ GError *error = NULL;
+
+ if(nameservers_v)
+ nameservers_list_i = nameservers_list = string_to_glist_of_strings (nameservers_v);
+ if(nameserver_v)
+ nameservers_list_i = nameservers_list = g_slist_append(nameservers_list, g_strdup(nameserver_v));
+
+ if (!address_v)
+ address_v = g_strdup ("0.0.0.0");
+
+ if (inet_pton (AF_INET, address_v, &tmp_ip4_addr))
+ nm_ip4_address_set_address (ip4_addr, tmp_ip4_addr.s_addr);
+ else
+ g_set_error (&error, eni_plugin_error_quark (), 0,
+ "Invalid %s IP4 address '%s'", "address", address_v);
+ if (!netmask_v)
+ netmask_v = g_strdup( "255.255.255.255");
+
+ if (inet_pton (AF_INET, netmask_v, &tmp_ip4_addr))
+ nm_ip4_address_set_prefix (ip4_addr, nm_utils_ip4_netmask_to_prefix(tmp_ip4_addr.s_addr));
+ else
+ g_set_error (&error, eni_plugin_error_quark (), 0,
+ "Invalid %s IP4 address '%s'", "netmask", netmask_v);
+
+ if (!gateway_v)
+ gateway_v = g_strdup (address_v);
+
+ if (inet_pton (AF_INET, gateway_v, &tmp_ip4_addr))
+ nm_ip4_address_set_gateway (ip4_addr, tmp_ip4_addr.s_addr);
+ else
+ g_set_error (&error, eni_plugin_error_quark (), 0,
+ "Invalid %s IP4 address '%s'", "gateway", gateway_v);
+
+ if (nm_setting_ip4_config_add_address (ip4_setting, ip4_addr)) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "addresses count: %d",
+ nm_setting_ip4_config_get_num_addresses (ip4_setting));
+ } else {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate IP4 address");
+ }
+
+ while(nameservers_list_i) {
+ gchar *dns = nameservers_list_i->data;
+ nameservers_list_i = nameservers_list_i -> next;
+ if(!dns)
+ continue;
+ if (inet_pton (AF_INET, dns, &tmp_ip4_addr)) {
+ if (!nm_setting_ip4_config_add_dns (ip4_setting, tmp_ip4_addr.s_addr))
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "ignoring duplicate DNS server '%s'", dns);
+ } else
+ g_set_error (&error, eni_plugin_error_quark (), 0,
+ "Invalid %s IP4 address nameserver '%s'", "nameserver", dns);
+ }
+ if (!nm_setting_ip4_config_get_num_dns (ip4_setting))
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "No dns-nameserver configured in /etc/network/interfaces");
+
+ g_object_set(ip4_setting,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ g_slist_foreach (nameservers_list, (GFunc) g_free, NULL);
+ g_slist_free (nameservers_list);
+ }
+
+ nm_connection_add_setting(connection, NM_SETTING(ip4_setting));
+}
+
+gboolean
+ifupdown_update_connection_from_if_block (NMConnection *connection,
+ if_block *block,
+ GError **error)
+{
+ const char *type = NULL;
+ char *idstr = NULL;
+ char *uuid_base = NULL;
+ char *uuid = NULL;
+ NMSettingConnection *s_con;
+ gboolean success = FALSE;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if(!s_con) {
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new());
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+ }
+
+ type = _ifupdownplugin_guess_connection_type (block);
+ idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL);
+ uuid_base = idstr;
+
+ uuid = nm_utils_uuid_generate_from_string (uuid_base);
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_TYPE, type,
+ NM_SETTING_CONNECTION_ID, idstr,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_READ_ONLY, TRUE,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NULL);
+ g_free (uuid);
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s",
+ block->name, type, idstr, nm_setting_connection_get_uuid (s_con));
+
+ if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type))
+ update_wired_setting_from_if_block (connection, block);
+ else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) {
+ update_wireless_setting_from_if_block (connection, block);
+ update_wireless_security_setting_from_if_block (connection, block);
+ }
+
+ update_ip4_setting_from_if_block (connection, block);
+
+ success = nm_connection_verify (connection, error);
+
+ g_free (idstr);
+ return success;
+}
diff --git a/src/settings/plugins/ifupdown/parser.h b/src/settings/plugins/ifupdown/parser.h
new file mode 100644
index 000000000..6aebb8c71
--- /dev/null
+++ b/src/settings/plugins/ifupdown/parser.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Canonical Ltd.
+ */
+
+#include <nm-connection.h>
+#include "interface_parser.h"
+
+G_BEGIN_DECLS
+
+gboolean
+ifupdown_update_connection_from_if_block (NMConnection *connection,
+ if_block *block,
+ GError **error);
+
+G_END_DECLS
diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c
new file mode 100644
index 000000000..9679edeac
--- /dev/null
+++ b/src/settings/plugins/ifupdown/plugin.c
@@ -0,0 +1,727 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007,2008 Canonical Ltd.
+ * (C) Copyright 2009 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <sys/inotify.h>
+
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+
+#include <gmodule.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <nm-setting-connection.h>
+
+#include "interface_parser.h"
+
+#include "NetworkManager.h"
+#include "nm-system-config-interface.h"
+#include "nm-setting-ip4-config.h"
+#include "nm-setting-wireless.h"
+#include "nm-setting-wired.h"
+#include "nm-setting-ppp.h"
+
+#include "nm-ifupdown-connection.h"
+#include "plugin.h"
+#include "parser.h"
+#include "nm-inotify-helper.h"
+
+#include "nm-logging.h"
+
+#include <arpa/inet.h>
+
+#include <gudev/gudev.h>
+
+#define ENI_INTERFACES_FILE "/etc/network/interfaces"
+
+#define IFUPDOWN_PLUGIN_NAME "ifupdown"
+#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list."
+#define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname"
+
+#define IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
+#define IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
+
+#define IFUPDOWN_KEY_FILE_GROUP "ifupdown"
+#define IFUPDOWN_KEY_FILE_KEY_MANAGED "managed"
+#define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE
+
+/* #define ALWAYS_UNMANAGE TRUE */
+#ifndef ALWAYS_UNMANAGE
+# define ALWAYS_UNMANAGE FALSE
+#endif
+
+typedef struct {
+ GUdevClient *client;
+
+ GHashTable *iface_connections;
+ gchar* hostname;
+
+ GHashTable *well_known_interfaces;
+ GHashTable *well_known_ifaces;
+ gboolean unmanage_well_known;
+ const char *conf_file;
+
+ gulong inotify_event_id;
+ int inotify_system_hostname_wd;
+} SCPluginIfupdownPrivate;
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginIfupdown, sc_plugin_ifupdown, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+ system_config_interface_init))
+
+#define SC_PLUGIN_IFUPDOWN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownPrivate))
+
+static void
+sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class);
+
+static void
+SCPluginIfupdown_init (NMSystemConfigInterface *config);
+
+/* Returns the plugins currently known list of connections. The returned
+ * list is freed by the system settings service.
+ */
+static GSList*
+SCPluginIfupdown_get_connections (NMSystemConfigInterface *config);
+
+/*
+ * Return a list of device specifications which NetworkManager should not
+ * manage. Returned list will be freed by the system settings service, and
+ * each element must be allocated using g_malloc() or its variants.
+ */
+static GSList*
+SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config);
+
+
+/* GObject */
+static void
+GObject__get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+static void
+GObject__set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+
+static void
+GObject__dispose (GObject *object);
+
+/* other helpers */
+static const char *
+get_hostname (NMSystemConfigInterface *config);
+
+
+static void
+update_system_hostname(NMInotifyHelper *inotify_helper,
+ struct inotify_event *evt,
+ const char *path,
+ NMSystemConfigInterface *config);
+
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+ system_config_interface_class->init = SCPluginIfupdown_init;
+ system_config_interface_class->get_connections = SCPluginIfupdown_get_connections;
+ system_config_interface_class->get_unmanaged_specs = SCPluginIfupdown_get_unmanaged_specs;
+}
+
+static void
+sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginIfupdownPrivate));
+
+ object_class->dispose = GObject__dispose;
+ object_class->get_property = GObject__get_property;
+ object_class->set_property = GObject__set_property;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+ NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+ignore_cb (NMSettingsConnection *connection,
+ GError *error,
+ gpointer user_data)
+{
+}
+
+static void
+bind_device_to_connection (SCPluginIfupdown *self,
+ GUdevDevice *device,
+ NMIfupdownConnection *exported)
+{
+ GByteArray *mac_address;
+ NMSetting *s_wired = NULL;
+ NMSetting *s_wifi = NULL;
+ const char *iface, *address;
+ struct ether_addr *tmp_mac;
+
+ iface = g_udev_device_get_name (device);
+ if (!iface) {
+ PLUGIN_WARN ("SCPluginIfupdown", "failed to get ifname for device.");
+ return;
+ }
+
+ address = g_udev_device_get_sysfs_attr (device, "address");
+ if (!address || !strlen (address)) {
+ PLUGIN_WARN ("SCPluginIfupdown", "failed to get MAC address for %s", iface);
+ return;
+ }
+
+ tmp_mac = ether_aton (address);
+ if (!tmp_mac) {
+ PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s",
+ address, iface);
+ return;
+ }
+
+ mac_address = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN);
+
+ s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED);
+ s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS);
+ if (s_wired) {
+ PLUGIN_PRINT ("SCPluginIfupdown", "locking wired connection setting");
+ g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac_address, NULL);
+ } else if (s_wifi) {
+ PLUGIN_PRINT ("SCPluginIfupdown", "locking wireless connection setting");
+ g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, mac_address, NULL);
+ }
+ g_byte_array_free (mac_address, TRUE);
+
+ nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL);
+}
+
+static void
+udev_device_added (SCPluginIfupdown *self, GUdevDevice *device)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
+ const char *iface, *path;
+ NMIfupdownConnection *exported;
+
+ iface = g_udev_device_get_name (device);
+ path = g_udev_device_get_sysfs_path (device);
+ if (!iface || !path)
+ return;
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown",
+ "devices added (path: %s, iface: %s)", path, iface);
+
+ /* if we have a configured connection for this particular iface
+ * we want to either unmanage the device or lock it
+ */
+ exported = (NMIfupdownConnection *) g_hash_table_lookup (priv->iface_connections, iface);
+ if (!exported && !g_hash_table_lookup (priv->well_known_interfaces, iface)) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown",
+ "device added (path: %s, iface: %s): no ifupdown configuration found.", path, iface);
+ return;
+ }
+
+ g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device));
+
+ if (exported)
+ bind_device_to_connection (self, device, exported);
+
+ if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
+ g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
+ const char *iface, *path;
+
+ iface = g_udev_device_get_name (device);
+ path = g_udev_device_get_sysfs_path (device);
+ if (!iface || !path)
+ return;
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown",
+ "devices removed (path: %s, iface: %s)", path, iface);
+
+ if (!g_hash_table_remove (priv->well_known_ifaces, iface))
+ return;
+
+ if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
+ g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+}
+
+static void
+handle_uevent (GUdevClient *client,
+ const char *action,
+ GUdevDevice *device,
+ gpointer user_data)
+{
+ SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (user_data);
+ const char *subsys;
+
+ g_return_if_fail (action != NULL);
+
+ /* A bit paranoid */
+ subsys = g_udev_device_get_subsystem (device);
+ g_return_if_fail (subsys != NULL);
+ g_return_if_fail (strcmp (subsys, "net") == 0);
+
+ if (!strcmp (action, "add"))
+ udev_device_added (self, device);
+ else if (!strcmp (action, "remove"))
+ udev_device_removed (self, device);
+}
+
+static void
+SCPluginIfupdown_init (NMSystemConfigInterface *config)
+{
+ SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config);
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self);
+ GHashTable *auto_ifaces;
+ if_block *block = NULL;
+ NMInotifyHelper *inotify_helper;
+ GKeyFile* keyfile;
+ GError *error = NULL;
+ GList *keys, *iter;
+ const char *subsys[2] = { "net", NULL };
+
+ auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if(!priv->iface_connections)
+ priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal);
+
+ if(!priv->well_known_ifaces)
+ priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+ if(!priv->well_known_interfaces)
+ priv->well_known_interfaces = g_hash_table_new (g_str_hash, g_str_equal);
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "init!");
+
+ priv->client = g_udev_client_new (subsys);
+ if (!priv->client) {
+ PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev");
+ } else
+ g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self);
+
+ priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT;
+
+ inotify_helper = nm_inotify_helper_get ();
+ priv->inotify_event_id = g_signal_connect (inotify_helper,
+ "event",
+ G_CALLBACK (update_system_hostname),
+ config);
+
+ priv->inotify_system_hostname_wd =
+ nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE);
+
+ update_system_hostname (inotify_helper, NULL, NULL, config);
+
+ /* Read in all the interfaces */
+ ifparser_init (ENI_INTERFACES_FILE, 0);
+ block = ifparser_getfirst ();
+ while (block) {
+ if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type))
+ g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1));
+ else if (!strcmp ("iface", block->type)) {
+ NMIfupdownConnection *exported;
+
+ /* Bridge configuration */
+ if(!strncmp ("br", block->name, 2)) {
+ /* Try to find bridge ports */
+ const char *ports = ifparser_getkey (block, "bridge-ports");
+ if (ports) {
+ int i;
+ int state = 0;
+ char **port_ifaces;
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "found bridge ports %s for %s", ports, block->name);
+
+ port_ifaces = g_strsplit_set (ports, " \t", -1);
+ for (i = 0; i < g_strv_length (port_ifaces); i++) {
+ char *token = port_ifaces[i];
+ /* Skip crazy stuff like regex or all */
+ if (!strcmp ("all", token)) {
+ continue;
+ }
+ /* Small SM to skip everything inside regex */
+ if (!strcmp ("regex", token)) {
+ state++;
+ continue;
+ }
+ if (!strcmp ("noregex", token)) {
+ state--;
+ continue;
+ }
+ if (state == 0 && strlen (token) > 0) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "adding bridge port %s to well_known_interfaces", token);
+ g_hash_table_insert (priv->well_known_interfaces, g_strdup (token), "known");
+ }
+ }
+ g_strfreev (port_ifaces);
+ }
+ goto next;
+ }
+
+ /* Skip loopback configuration */
+ if(!strcmp ("lo", block->name)) {
+ goto next;
+ }
+
+ /* Remove any connection for this block that was previously found */
+ exported = g_hash_table_lookup (priv->iface_connections, block->name);
+ if (exported) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name);
+ nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL);
+ g_hash_table_remove (priv->iface_connections, block->name);
+ }
+
+ /* add the new connection */
+ exported = nm_ifupdown_connection_new (block);
+ if (exported) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "adding %s to iface_connections", block->name);
+ g_hash_table_insert (priv->iface_connections, block->name, exported);
+ }
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "adding iface %s to well_known_interfaces", block->name);
+ g_hash_table_insert (priv->well_known_interfaces, block->name, "known");
+ } else if (!strcmp ("mapping", block->type)) {
+ g_hash_table_insert (priv->well_known_interfaces, block->name, "known");
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name);
+ }
+ next:
+ block = block->next;
+ }
+
+ /* Make 'auto' interfaces autoconnect=TRUE */
+ keys = g_hash_table_get_keys (priv->iface_connections);
+ for (iter = keys; iter; iter = g_list_next (iter)) {
+ NMIfupdownConnection *exported;
+ NMSetting *setting;
+
+ if (!g_hash_table_lookup (auto_ifaces, iter->data))
+ continue;
+
+ exported = g_hash_table_lookup (priv->iface_connections, iter->data);
+ setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION));
+ g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
+
+ nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL);
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect");
+ }
+ g_list_free (keys);
+ g_hash_table_destroy (auto_ifaces);
+
+ /* Find the config file */
+ if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS))
+ priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE;
+ else
+ priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE;
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile,
+ priv->conf_file,
+ G_KEY_FILE_NONE,
+ &error)) {
+ nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s",
+ priv->conf_file,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ } else {
+ gboolean manage_well_known;
+ error = NULL;
+
+ manage_well_known = g_key_file_get_boolean (keyfile,
+ IFUPDOWN_KEY_FILE_GROUP,
+ IFUPDOWN_KEY_FILE_KEY_MANAGED,
+ &error);
+ if (error) {
+ nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s",
+ IFUPDOWN_KEY_FILE_GROUP,
+ IFUPDOWN_KEY_FILE_KEY_MANAGED,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ } else
+ priv->unmanage_well_known = !manage_well_known;
+ }
+ PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed");
+ if (keyfile)
+ g_key_file_free (keyfile);
+
+ /* Add well-known interfaces */
+ keys = g_udev_client_query_by_subsystem (priv->client, "net");
+ for (iter = keys; iter; iter = g_list_next (iter)) {
+ udev_device_added (self, G_UDEV_DEVICE (iter->data));
+ g_object_unref (G_UDEV_DEVICE (iter->data));
+ }
+ g_list_free (keys);
+
+ /* Now if we're running in managed mode, let NM know there are new connections */
+ if (!priv->unmanage_well_known) {
+ GList *con_list = g_hash_table_get_values (priv->iface_connections);
+ GList *cl_iter;
+
+ for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) {
+ g_signal_emit_by_name (self,
+ NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
+ NM_SETTINGS_CONNECTION (cl_iter->data));
+ }
+ g_list_free (con_list);
+ }
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init.");
+}
+
+
+/* Returns the plugins currently known list of connections. The returned
+ * list is freed by the system settings service.
+ */
+static GSList*
+SCPluginIfupdown_get_connections (NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ GSList *connections = NULL;
+ GHashTableIter iter;
+ gpointer value;
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) ... get_connections.", GPOINTER_TO_UINT(config));
+
+ if(priv->unmanage_well_known) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) ... get_connections (managed=false): return empty list.", GPOINTER_TO_UINT(config));
+ return NULL;
+ }
+
+ g_hash_table_iter_init (&iter, priv->iface_connections);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ connections = g_slist_prepend (connections, value);
+
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections));
+ return connections;
+}
+
+/*
+ * Return a list of device specifications which NetworkManager should not
+ * manage. Returned list will be freed by the system settings service, and
+ * each element must be allocated using g_malloc() or its variants.
+ */
+static GSList*
+SCPluginIfupdown_get_unmanaged_specs (NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ GSList *specs = NULL;
+ GHashTableIter iter;
+ gpointer value;
+
+ if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known)
+ return NULL;
+
+ PLUGIN_PRINT("Ifupdown", "get unmanaged devices count: %d",
+ g_hash_table_size (priv->well_known_ifaces));
+
+ g_hash_table_iter_init (&iter, priv->well_known_ifaces);
+ while (g_hash_table_iter_next (&iter, NULL, &value)) {
+ GUdevDevice *device = G_UDEV_DEVICE (value);
+ const char *address;
+
+ address = g_udev_device_get_sysfs_attr (device, "address");
+ if (address)
+ specs = g_slist_append (specs, g_strdup_printf ("mac:%s", address));
+ }
+ return specs;
+}
+
+
+static const char *
+get_hostname (NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ return priv->hostname;
+}
+
+static void
+update_system_hostname(NMInotifyHelper *inotify_helper,
+ struct inotify_event *evt,
+ const char *path,
+ NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ gchar *hostname_file = NULL;
+ gsize hostname_file_len = 0;
+ GError *error = NULL;
+
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "update_system_hostname");
+
+ if (evt && evt->wd != priv->inotify_system_hostname_wd)
+ return;
+
+ if(!g_file_get_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
+ &hostname_file,
+ &hostname_file_len,
+ &error)) {
+ nm_log_warn (LOGD_SETTINGS, "update_system_hostname() - couldn't read "
+ IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
+ error->code, error->message);
+ return;
+ }
+
+ g_free(priv->hostname);
+ priv->hostname = g_strstrip(hostname_file);
+
+ /* We shouldn't return a zero-length hostname, but NULL */
+ if (priv->hostname && !strlen (priv->hostname)) {
+ g_free (priv->hostname);
+ priv->hostname = NULL;
+ }
+
+ g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+write_system_hostname(NMSystemConfigInterface *config,
+ const char *newhostname)
+{
+ GError *error = NULL;
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "write_system_hostname: %s", newhostname);
+
+ g_return_if_fail (newhostname);
+
+ if(!g_file_set_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
+ newhostname,
+ -1,
+ &error)) {
+ nm_log_warn (LOGD_SETTINGS, "update_system_hostname() - couldn't write hostname (%s) to "
+ IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
+ newhostname, error->code, error->message);
+ } else {
+ priv->hostname = g_strdup (newhostname);
+ }
+ g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+
+static void
+sc_plugin_ifupdown_init (SCPluginIfupdown *plugin)
+{
+}
+
+static void
+GObject__get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object);
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, IFUPDOWN_PLUGIN_NAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, IFUPDOWN_PLUGIN_INFO);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+ g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ {
+ g_value_set_string (value, get_hostname(self));
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+GObject__set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ {
+ const gchar *hostname = g_value_get_string (value);
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ write_system_hostname(NM_SYSTEM_CONFIG_INTERFACE(object),
+ hostname);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+GObject__dispose (GObject *object)
+{
+ SCPluginIfupdown *plugin = SC_PLUGIN_IFUPDOWN (object);
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
+ NMInotifyHelper *inotify_helper = nm_inotify_helper_get ();
+
+ g_signal_handler_disconnect (inotify_helper, priv->inotify_event_id);
+
+ if (priv->inotify_system_hostname_wd >= 0)
+ nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd);
+
+ if (priv->well_known_ifaces)
+ g_hash_table_destroy(priv->well_known_ifaces);
+
+ if (priv->well_known_interfaces)
+ g_hash_table_destroy(priv->well_known_interfaces);
+
+ if (priv->client)
+ g_object_unref (priv->client);
+
+ G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object);
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+ static SCPluginIfupdown *singleton = NULL;
+
+ if (!singleton)
+ singleton = SC_PLUGIN_IFUPDOWN (g_object_new (SC_TYPE_PLUGIN_IFUPDOWN, NULL));
+ else
+ g_object_ref (singleton);
+
+ return G_OBJECT (singleton);
+}
+
diff --git a/src/settings/plugins/ifupdown/plugin.h b/src/settings/plugins/ifupdown/plugin.h
new file mode 100644
index 000000000..09f8767a0
--- /dev/null
+++ b/src/settings/plugins/ifupdown/plugin.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager system settings service (ifupdown)
+ *
+ * Alexander Sack <asac@ubuntu.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Canonical Ltd.
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define PLUGIN_NAME "ifupdown"
+
+#define SC_TYPE_PLUGIN_IFUPDOWN (sc_plugin_ifupdown_get_type ())
+#define SC_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdown))
+#define SC_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownClass))
+#define SC_IS_PLUGIN_IFUPDOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_IFUPDOWN))
+#define SC_IS_PLUGIN_IFUPDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_IFUPDOWN))
+#define SC_PLUGIN_IFUPDOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_IFUPDOWN, SCPluginIfupdownClass))
+
+typedef struct _SCPluginIfupdown SCPluginIfupdown;
+typedef struct _SCPluginIfupdownClass SCPluginIfupdownClass;
+
+struct _SCPluginIfupdown {
+ GObject parent;
+};
+
+struct _SCPluginIfupdownClass {
+ GObjectClass parent;
+};
+
+GType sc_plugin_ifupdown_get_type (void);
+
+GQuark ifupdown_plugin_error_quark (void);
+
+#endif /* _PLUGIN_H_ */
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.am b/src/settings/plugins/ifupdown/tests/Makefile.am
new file mode 100644
index 000000000..aed861973
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/Makefile.am
@@ -0,0 +1,32 @@
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+noinst_PROGRAMS = test-ifupdown
+
+test_ifupdown_SOURCES = \
+ test-ifupdown.c
+
+test_ifupdown_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_ENI_DIR=\"$(abs_srcdir)\"
+
+test_ifupdown_LDADD = \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifupdown-io.la \
+ $(DBUS_LIBS)
+
+if WITH_TESTS
+
+check-local: test-ifupdown
+ $(abs_builddir)/test-ifupdown
+
+endif
+
+EXTRA_DIST = \
+ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \
+ test13 test14 test15 test16
diff --git a/src/settings/plugins/ifupdown/tests/Makefile.in b/src/settings/plugins/ifupdown/tests/Makefile.in
new file mode 100644
index 000000000..8bd83a15e
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/Makefile.in
@@ -0,0 +1,632 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = test-ifupdown$(EXEEXT)
+subdir = src/settings/plugins/ifupdown/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_ifupdown_OBJECTS = test_ifupdown-test-ifupdown.$(OBJEXT)
+test_ifupdown_OBJECTS = $(am_test_ifupdown_OBJECTS)
+am__DEPENDENCIES_1 =
+test_ifupdown_DEPENDENCIES = $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifupdown-io.la $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(test_ifupdown_SOURCES)
+DIST_SOURCES = $(test_ifupdown_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+test_ifupdown_SOURCES = \
+ test-ifupdown.c
+
+test_ifupdown_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_ENI_DIR=\"$(abs_srcdir)\"
+
+test_ifupdown_LDADD = \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(builddir)/../libifupdown-io.la \
+ $(DBUS_LIBS)
+
+EXTRA_DIST = \
+ test1 test2 test3 test4 test5 test6 test7 test8 test9 test11 test12 \
+ test13 test14 test15 test16
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/ifupdown/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+test-ifupdown$(EXEEXT): $(test_ifupdown_OBJECTS) $(test_ifupdown_DEPENDENCIES)
+ @rm -f test-ifupdown$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ifupdown_OBJECTS) $(test_ifupdown_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ifupdown-test-ifupdown.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+test_ifupdown-test-ifupdown.o: test-ifupdown.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifupdown-test-ifupdown.o -MD -MP -MF $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o test_ifupdown-test-ifupdown.o `test -f 'test-ifupdown.c' || echo '$(srcdir)/'`test-ifupdown.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo $(DEPDIR)/test_ifupdown-test-ifupdown.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifupdown.c' object='test_ifupdown-test-ifupdown.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifupdown-test-ifupdown.o `test -f 'test-ifupdown.c' || echo '$(srcdir)/'`test-ifupdown.c
+
+test_ifupdown-test-ifupdown.obj: test-ifupdown.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_ifupdown-test-ifupdown.obj -MD -MP -MF $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo -c -o test_ifupdown-test-ifupdown.obj `if test -f 'test-ifupdown.c'; then $(CYGPATH_W) 'test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/test-ifupdown.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_ifupdown-test-ifupdown.Tpo $(DEPDIR)/test_ifupdown-test-ifupdown.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-ifupdown.c' object='test_ifupdown-test-ifupdown.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ifupdown_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_ifupdown-test-ifupdown.obj `if test -f 'test-ifupdown.c'; then $(CYGPATH_W) 'test-ifupdown.c'; else $(CYGPATH_W) '$(srcdir)/test-ifupdown.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+@WITH_TESTS_FALSE@check-local:
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+@WITH_TESTS_TRUE@check-local: test-ifupdown
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-ifupdown
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
new file mode 100644
index 000000000..164653645
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
@@ -0,0 +1,496 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "interface_parser.h"
+#include "parser.h"
+
+typedef struct {
+ char *key;
+ char *data;
+} ExpectedKey;
+
+typedef struct {
+ char *type;
+ char *name;
+ GSList *keys;
+} ExpectedBlock;
+
+typedef struct {
+ GSList *blocks;
+} Expected;
+
+static ExpectedKey *
+expected_key_new (const char *key, const char *data)
+{
+ ExpectedKey *k;
+
+ k = g_malloc0 (sizeof (ExpectedKey));
+ g_assert (k);
+ k->key = g_strdup (key);
+ g_assert (k->key);
+ k->data = g_strdup (data);
+ g_assert (k->data);
+ return k;
+}
+
+static void
+expected_key_free (ExpectedKey *k)
+{
+ g_assert (k);
+ g_free (k->key);
+ g_free (k->data);
+ memset (k, 0, sizeof (ExpectedKey));
+ g_free (k);
+}
+
+static ExpectedBlock *
+expected_block_new (const char *type, const char *name)
+{
+ ExpectedBlock *b;
+
+ g_assert (type);
+ g_assert (name);
+ b = g_malloc0 (sizeof (ExpectedBlock));
+ g_assert (b);
+ b->type = g_strdup (type);
+ b->name = g_strdup (name);
+ return b;
+}
+
+static void
+expected_block_free (ExpectedBlock *b)
+{
+ g_assert (b);
+ g_slist_foreach (b->keys, (GFunc) expected_key_free, NULL);
+ g_slist_free (b->keys);
+ g_free (b->type);
+ g_free (b->name);
+ memset (b, 0, sizeof (ExpectedBlock));
+ g_free (b);
+}
+
+static void
+expected_block_add_key (ExpectedBlock *b, ExpectedKey *k)
+{
+ g_assert (b);
+ g_assert (k);
+ b->keys = g_slist_append (b->keys, k);
+}
+
+static Expected *
+expected_new (void)
+{
+ Expected *e;
+
+ e = g_malloc0 (sizeof (Expected));
+ g_assert (e);
+ return e;
+}
+
+static void
+expected_add_block (Expected *e, ExpectedBlock *b)
+{
+ g_assert (e);
+ g_assert (b);
+ e->blocks = g_slist_append (e->blocks, b);
+}
+
+static void
+expected_free (Expected *e)
+{
+ g_assert (e);
+ g_slist_foreach (e->blocks, (GFunc) expected_block_free, NULL);
+ g_slist_free (e->blocks);
+ memset (e, 0, sizeof (Expected));
+ g_free (e);
+}
+
+static void
+compare_expected_to_ifparser (Expected *e)
+{
+ if_block *n;
+ GSList *biter, *kiter;
+
+ g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks ());
+
+ for (n = ifparser_getfirst (), biter = e->blocks;
+ n && biter;
+ n = n->next, biter = g_slist_next (biter)) {
+ if_data *m;
+ ExpectedBlock *b = biter->data;
+
+ g_assert (b->type && n->type);
+ g_assert_cmpstr (b->type, ==, n->type);
+ g_assert (b->name && n->name);
+ g_assert_cmpstr (b->name, ==, n->name);
+
+ g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n));
+
+ for (m = n->info, kiter = b->keys;
+ m && kiter;
+ m = m->next, kiter = g_slist_next (kiter)) {
+ ExpectedKey *k = kiter->data;
+
+ g_assert (k->key && m->key);
+ g_assert_cmpstr (k->key, ==, m->key);
+ g_assert (k->data && m->data);
+ g_assert_cmpstr (k->data, ==, m->data);
+ }
+ }
+}
+
+static void
+dump_blocks (void)
+{
+ if_block *n;
+
+ g_message ("\n***************************************************");
+ for (n = ifparser_getfirst (); n != NULL; n = n->next) {
+ if_data *m;
+
+ // each block start with its type & name
+ // (single quotes used to show typ & name baoundaries)
+ g_print("'%s' '%s'\n", n->type, n->name);
+
+ // each key-value pair within a block is indented & separated by a tab
+ // (single quotes used to show typ & name baoundaries)
+ for (m = n->info; m != NULL; m = m->next)
+ g_print("\t'%s'\t'%s'\n", m->key, m->data);
+
+ // blocks are separated by an empty line
+ g_print("\n");
+ }
+ g_message ("##################################################\n");
+}
+
+static void
+init_ifparser_with_file (const char *path, const char *file)
+{
+ char *tmp;
+
+ tmp = g_strdup_printf ("%s/%s", path, file);
+ ifparser_init (tmp, 1);
+ g_free (tmp);
+}
+
+static void
+test1_ignore_line_before_first_block (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("auto", "eth0");
+ expected_add_block (e, b);
+ b = expected_block_new ("iface", "eth0");
+ expected_add_block (e, b);
+ expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
+
+ init_ifparser_with_file (path, "test1");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test2_wrapped_line (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("auto", "lo");
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test2");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test3_wrapped_multiline_multiarg (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("allow-hotplug", "eth0");
+ expected_add_block (e, b);
+ b = expected_block_new ("allow-hotplug", "wlan0");
+ expected_add_block (e, b);
+ b = expected_block_new ("allow-hotplug", "bnep0");
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test3");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test4_allow_auto_is_auto (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("auto", "eth0");
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test4");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test5_allow_auto_multiarg (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("allow-hotplug", "eth0");
+ expected_add_block (e, b);
+ b = expected_block_new ("allow-hotplug", "wlan0");
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test5");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test6_mixed_whitespace (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "lo");
+ expected_block_add_key (b, expected_key_new ("inet", "loopback"));
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test6");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test7_long_line (const char *path)
+{
+ init_ifparser_with_file (path, "test7");
+ g_assert_cmpint (ifparser_get_num_blocks (), ==, 0);
+ ifparser_destroy ();
+}
+
+static void
+test8_long_line_wrapped (const char *path)
+{
+ init_ifparser_with_file (path, "test8");
+ g_assert_cmpint (ifparser_get_num_blocks (), ==, 0);
+ ifparser_destroy ();
+}
+
+static void
+test9_wrapped_lines_in_block (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "eth0");
+ expected_add_block (e, b);
+ expected_block_add_key (b, expected_key_new ("inet", "static"));
+ expected_block_add_key (b, expected_key_new ("address", "10.250.2.3"));
+ expected_block_add_key (b, expected_key_new ("netmask", "255.255.255.192"));
+ expected_block_add_key (b, expected_key_new ("broadcast", "10.250.2.63"));
+ expected_block_add_key (b, expected_key_new ("gateway", "10.250.2.50"));
+
+ init_ifparser_with_file (path, "test9");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test11_complex_wrap (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "pppoe");
+ expected_add_block (e, b);
+ expected_block_add_key (b, expected_key_new ("inet", "manual"));
+ expected_block_add_key (b, expected_key_new ("pre-up", "/sbin/ifconfig eth0 up"));
+
+ init_ifparser_with_file (path, "test11");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test12_complex_wrap_split_word (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "pppoe");
+ expected_add_block (e, b);
+ expected_block_add_key (b, expected_key_new ("inet", "manual"));
+ expected_block_add_key (b, expected_key_new ("up", "ifup ppp0=dsl"));
+
+ init_ifparser_with_file (path, "test12");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test13_more_mixed_whitespace (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "dsl");
+ expected_block_add_key (b, expected_key_new ("inet", "ppp"));
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test13");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test14_mixed_whitespace_block_start (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "wlan0");
+ expected_block_add_key (b, expected_key_new ("inet", "manual"));
+ expected_add_block (e, b);
+ b = expected_block_new ("iface", "wlan-adpm");
+ expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
+ expected_add_block (e, b);
+ b = expected_block_new ("iface", "wlan-default");
+ expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test14");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test15_trailing_space (const char *path)
+{
+ Expected *e;
+ ExpectedBlock *b;
+
+ e = expected_new ();
+ b = expected_block_new ("iface", "bnep0");
+ expected_block_add_key (b, expected_key_new ("inet", "static"));
+ expected_add_block (e, b);
+
+ init_ifparser_with_file (path, "test15");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+static void
+test16_missing_newline (const char *path)
+{
+ Expected *e;
+
+ e = expected_new ();
+ expected_add_block (e, expected_block_new ("mapping", "eth0"));
+
+ init_ifparser_with_file (path, "test16");
+ compare_expected_to_ifparser (e);
+
+ ifparser_destroy ();
+ expected_free (e);
+}
+
+#if GLIB_CHECK_VERSION(2,25,12)
+typedef GTestFixtureFunc TCFunc;
+#else
+typedef void (*TCFunc)(void);
+#endif
+
+#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL)
+
+int main (int argc, char **argv)
+{
+ GTestSuite *suite;
+
+ g_test_init (&argc, &argv, NULL);
+
+ suite = g_test_get_root ();
+
+ if (0)
+ dump_blocks ();
+
+ g_test_suite_add (suite, TESTCASE (test1_ignore_line_before_first_block, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test2_wrapped_line, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test3_wrapped_multiline_multiarg, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test4_allow_auto_is_auto, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test5_allow_auto_multiarg, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test6_mixed_whitespace, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test7_long_line, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test8_long_line_wrapped, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test9_wrapped_lines_in_block, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test11_complex_wrap, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test12_complex_wrap_split_word, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test13_more_mixed_whitespace, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test14_mixed_whitespace_block_start, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test15_trailing_space, TEST_ENI_DIR));
+ g_test_suite_add (suite, TESTCASE (test16_missing_newline, TEST_ENI_DIR));
+
+ return g_test_run ();
+}
+
diff --git a/src/settings/plugins/ifupdown/tests/test1 b/src/settings/plugins/ifupdown/tests/test1
new file mode 100644
index 000000000..74c23b457
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test1
@@ -0,0 +1,6 @@
+# case 1: line before 1st block (must be ignored)
+address 10.250.2.3
+
+auto eth0
+iface eth0 inet dhcp
+
diff --git a/src/settings/plugins/ifupdown/tests/test11 b/src/settings/plugins/ifupdown/tests/test11
new file mode 100644
index 000000000..89561dd7d
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test11
@@ -0,0 +1,5 @@
+iface pppoe inet manual
+# case 11: wrapped line (without leading space on the wrapped part, wrap within a multi-word value)
+ pre-up /sbin/ifconfig \
+eth0 up
+
diff --git a/src/settings/plugins/ifupdown/tests/test12 b/src/settings/plugins/ifupdown/tests/test12
new file mode 100644
index 000000000..6096842e1
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test12
@@ -0,0 +1,5 @@
+iface pppoe inet manual
+# case 12: wrapped line, splitting a word (must be joined again)
+ up ifup ppp0\
+=dsl
+
diff --git a/src/settings/plugins/ifupdown/tests/test13 b/src/settings/plugins/ifupdown/tests/test13
new file mode 100644
index 000000000..c001f7ef1
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test13
@@ -0,0 +1,3 @@
+# case 13: variations of tabs & spaces
+iface dsl inet ppp
+
diff --git a/src/settings/plugins/ifupdown/tests/test14 b/src/settings/plugins/ifupdown/tests/test14
new file mode 100644
index 000000000..4a153ab3b
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test14
@@ -0,0 +1,5 @@
+# case 14: variations of tabs and spaces (all must be recognized as lines starting an iface block)
+iface wlan0 inet manual
+ iface wlan-adpm inet dhcp
+iface wlan-default inet dhcp
+
diff --git a/src/settings/plugins/ifupdown/tests/test15 b/src/settings/plugins/ifupdown/tests/test15
new file mode 100644
index 000000000..c3ceca240
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test15
@@ -0,0 +1,3 @@
+# case 15: trailing space (must be ignored)
+iface bnep0 inet static
+
diff --git a/src/settings/plugins/ifupdown/tests/test16 b/src/settings/plugins/ifupdown/tests/test16
new file mode 100644
index 000000000..f4f74fb5a
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test16
@@ -0,0 +1,2 @@
+# case 16: last line that is not followed by LF (added with 'echo -n "mapping eth0" >> /e/n/i')
+mapping eth0 \ No newline at end of file
diff --git a/src/settings/plugins/ifupdown/tests/test2 b/src/settings/plugins/ifupdown/tests/test2
new file mode 100644
index 000000000..7462b3526
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test2
@@ -0,0 +1,4 @@
+# case 2: wrapped line
+auto \
+lo
+
diff --git a/src/settings/plugins/ifupdown/tests/test3 b/src/settings/plugins/ifupdown/tests/test3
new file mode 100644
index 000000000..f6293bbdc
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test3
@@ -0,0 +1,5 @@
+# case 3: line wrapped over multiple lines & multi-argument allow-*
+allow-hotplug eth0 \
+ wlan0 \
+ bnep0
+
diff --git a/src/settings/plugins/ifupdown/tests/test4 b/src/settings/plugins/ifupdown/tests/test4
new file mode 100644
index 000000000..46a40bc9c
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test4
@@ -0,0 +1,3 @@
+# case 4: 'allow-auto' is synonymous to 'auto'
+allow-auto eth0
+
diff --git a/src/settings/plugins/ifupdown/tests/test5 b/src/settings/plugins/ifupdown/tests/test5
new file mode 100644
index 000000000..b69fc42bd
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test5
@@ -0,0 +1,3 @@
+# case 5: multi-argument allow-* (even worse: trailing space)
+allow-hotplug eth0 wlan0
+
diff --git a/src/settings/plugins/ifupdown/tests/test6 b/src/settings/plugins/ifupdown/tests/test6
new file mode 100644
index 000000000..50ac69bd9
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test6
@@ -0,0 +1,3 @@
+# case 6: mix between tabs and spaces
+ iface lo inet loopback
+
diff --git a/src/settings/plugins/ifupdown/tests/test7 b/src/settings/plugins/ifupdown/tests/test7
new file mode 100644
index 000000000..03cb131a9
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test7
@@ -0,0 +1,3 @@
+# case 7: over-long line (must be ignored completely)
+123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
+
diff --git a/src/settings/plugins/ifupdown/tests/test8 b/src/settings/plugins/ifupdown/tests/test8
new file mode 100644
index 000000000..311f7e15a
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test8
@@ -0,0 +1,5 @@
+# case 8: over-long line that wraps to consecutive lines (must be ignored completely)
+123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 \
+allow-test eth0 \
+eth0
+
diff --git a/src/settings/plugins/ifupdown/tests/test9 b/src/settings/plugins/ifupdown/tests/test9
new file mode 100644
index 000000000..7d94563af
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test9
@@ -0,0 +1,10 @@
+iface eth0 inet static
+# case 9: wrapped lines inside a block (to be on the safe side)
+ address \
+ 10.250.2.3
+ netmask \
+ 255.255.255.192
+
+ broadcast 10.250.2.63
+ gateway 10.250.2.50
+
diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am
new file mode 100644
index 000000000..3b2421422
--- /dev/null
+++ b/src/settings/plugins/keyfile/Makefile.am
@@ -0,0 +1,61 @@
+SUBDIRS=. tests
+
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util
+
+noinst_LTLIBRARIES = \
+ libkeyfile-io.la \
+ libnm-settings-plugin-keyfile.la
+
+##### I/O library for testcases #####
+
+libkeyfile_io_la_SOURCES = \
+ reader.c \
+ reader.h \
+ writer.c \
+ writer.h \
+ errors.c \
+ utils.c \
+ utils.h \
+ common.h
+
+libkeyfile_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DG_DISABLE_DEPRECATED
+
+libkeyfile_io_la_LIBADD = $(GLIB_LIBS)
+
+#####################################
+
+libnm_settings_plugin_keyfile_la_SOURCES = \
+ nm-keyfile-connection.c \
+ nm-keyfile-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_keyfile_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DG_DISABLE_DEPRECATED
+
+libnm_settings_plugin_keyfile_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ libkeyfile-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(DBUS_LIBS) \
+ $(GIO_LIBS)
+
+libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic
+
+keyfiledir=$(sysconfdir)/NetworkManager/system-connections
+
+install-data-hook:
+ $(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir)
+
diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in
new file mode 100644
index 000000000..409499d78
--- /dev/null
+++ b/src/settings/plugins/keyfile/Makefile.in
@@ -0,0 +1,865 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/keyfile
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libkeyfile_io_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libkeyfile_io_la_OBJECTS = libkeyfile_io_la-reader.lo \
+ libkeyfile_io_la-writer.lo libkeyfile_io_la-errors.lo \
+ libkeyfile_io_la-utils.lo
+libkeyfile_io_la_OBJECTS = $(am_libkeyfile_io_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libnm_settings_plugin_keyfile_la_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la libkeyfile-io.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libnm_settings_plugin_keyfile_la_OBJECTS = \
+ libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo \
+ libnm_settings_plugin_keyfile_la-plugin.lo
+libnm_settings_plugin_keyfile_la_OBJECTS = \
+ $(am_libnm_settings_plugin_keyfile_la_OBJECTS)
+libnm_settings_plugin_keyfile_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) \
+ $(libnm_settings_plugin_keyfile_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libkeyfile_io_la_SOURCES) \
+ $(libnm_settings_plugin_keyfile_la_SOURCES)
+DIST_SOURCES = $(libkeyfile_io_la_SOURCES) \
+ $(libnm_settings_plugin_keyfile_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = . tests
+INCLUDES = \
+ -I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util
+
+noinst_LTLIBRARIES = \
+ libkeyfile-io.la \
+ libnm-settings-plugin-keyfile.la
+
+
+##### I/O library for testcases #####
+libkeyfile_io_la_SOURCES = \
+ reader.c \
+ reader.h \
+ writer.c \
+ writer.h \
+ errors.c \
+ utils.c \
+ utils.h \
+ common.h
+
+libkeyfile_io_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DG_DISABLE_DEPRECATED
+
+libkeyfile_io_la_LIBADD = $(GLIB_LIBS)
+
+#####################################
+libnm_settings_plugin_keyfile_la_SOURCES = \
+ nm-keyfile-connection.c \
+ nm-keyfile-connection.h \
+ plugin.c \
+ plugin.h
+
+libnm_settings_plugin_keyfile_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DG_DISABLE_DEPRECATED
+
+libnm_settings_plugin_keyfile_la_LIBADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ libkeyfile-io.la \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(DBUS_LIBS) \
+ $(GIO_LIBS)
+
+libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic
+keyfiledir = $(sysconfdir)/NetworkManager/system-connections
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libkeyfile-io.la: $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libkeyfile_io_la_OBJECTS) $(libkeyfile_io_la_LIBADD) $(LIBS)
+libnm-settings-plugin-keyfile.la: $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libnm_settings_plugin_keyfile_la_LINK) $(libnm_settings_plugin_keyfile_la_OBJECTS) $(libnm_settings_plugin_keyfile_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-errors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-reader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyfile_io_la-writer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libkeyfile_io_la-reader.lo: reader.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-reader.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-reader.Tpo -c -o libkeyfile_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-reader.Tpo $(DEPDIR)/libkeyfile_io_la-reader.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='reader.c' object='libkeyfile_io_la-reader.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-reader.lo `test -f 'reader.c' || echo '$(srcdir)/'`reader.c
+
+libkeyfile_io_la-writer.lo: writer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-writer.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-writer.Tpo -c -o libkeyfile_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-writer.Tpo $(DEPDIR)/libkeyfile_io_la-writer.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='writer.c' object='libkeyfile_io_la-writer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-writer.lo `test -f 'writer.c' || echo '$(srcdir)/'`writer.c
+
+libkeyfile_io_la-errors.lo: errors.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-errors.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-errors.Tpo -c -o libkeyfile_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-errors.Tpo $(DEPDIR)/libkeyfile_io_la-errors.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='errors.c' object='libkeyfile_io_la-errors.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-errors.lo `test -f 'errors.c' || echo '$(srcdir)/'`errors.c
+
+libkeyfile_io_la-utils.lo: utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libkeyfile_io_la-utils.lo -MD -MP -MF $(DEPDIR)/libkeyfile_io_la-utils.Tpo -c -o libkeyfile_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libkeyfile_io_la-utils.Tpo $(DEPDIR)/libkeyfile_io_la-utils.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='utils.c' object='libkeyfile_io_la-utils.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyfile_io_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libkeyfile_io_la-utils.lo `test -f 'utils.c' || echo '$(srcdir)/'`utils.c
+
+libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo: nm-keyfile-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Tpo -c -o libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo `test -f 'nm-keyfile-connection.c' || echo '$(srcdir)/'`nm-keyfile-connection.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Tpo $(DEPDIR)/libnm_settings_plugin_keyfile_la-nm-keyfile-connection.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-keyfile-connection.c' object='libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_keyfile_la-nm-keyfile-connection.lo `test -f 'nm-keyfile-connection.c' || echo '$(srcdir)/'`nm-keyfile-connection.c
+
+libnm_settings_plugin_keyfile_la-plugin.lo: plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libnm_settings_plugin_keyfile_la-plugin.lo -MD -MP -MF $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Tpo -c -o libnm_settings_plugin_keyfile_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Tpo $(DEPDIR)/libnm_settings_plugin_keyfile_la-plugin.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugin.c' object='libnm_settings_plugin_keyfile_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libnm_settings_plugin_keyfile_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libnm_settings_plugin_keyfile_la-plugin.lo `test -f 'plugin.c' || echo '$(srcdir)/'`plugin.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-data-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-data-hook install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am
+
+
+install-data-hook:
+ $(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h
new file mode 100644
index 000000000..6c8f9cebb
--- /dev/null
+++ b/src/settings/plugins/keyfile/common.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include <glib.h>
+
+#define SWP_TAG ".swp"
+#define SWPX_TAG ".swpx"
+
+#define KEYFILE_PLUGIN_NAME "keyfile"
+#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
+
+#define KEYFILE_DIR SYSCONFDIR "/NetworkManager/system-connections"
+
+#define VPN_SECRETS_GROUP "vpn-secrets"
+
+#define KEYFILE_PLUGIN_ERROR (keyfile_plugin_error_quark ())
+GQuark keyfile_plugin_error_quark (void);
+
+#endif /* __COMMON_H__ */
+
diff --git a/src/settings/plugins/keyfile/errors.c b/src/settings/plugins/keyfile/errors.c
new file mode 100644
index 000000000..e2e97690f
--- /dev/null
+++ b/src/settings/plugins/keyfile/errors.c
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 - 2010 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include "common.h"
+
+GQuark
+keyfile_plugin_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (G_UNLIKELY (error_quark == 0))
+ error_quark = g_quark_from_static_string ("keyfile-plugin-error-quark");
+
+ return error_quark;
+}
+
+
diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c
new file mode 100644
index 000000000..23618f7c2
--- /dev/null
+++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <glib/gstdio.h>
+#include <NetworkManager.h>
+#include <nm-setting-connection.h>
+#include <nm-utils.h>
+
+#include "nm-system-config-interface.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-keyfile-connection.h"
+#include "reader.h"
+#include "writer.h"
+#include "common.h"
+
+G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION)
+
+#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate))
+
+typedef struct {
+ char *path;
+} NMKeyfileConnectionPrivate;
+
+NMKeyfileConnection *
+nm_keyfile_connection_new (const char *full_path,
+ NMConnection *source,
+ GError **error)
+{
+ GObject *object;
+ NMKeyfileConnectionPrivate *priv;
+ NMConnection *tmp;
+ const char *uuid;
+
+ g_return_val_if_fail (full_path != NULL, NULL);
+
+ /* If we're given a connection already, prefer that instead of re-reading */
+ if (source)
+ tmp = g_object_ref (source);
+ else {
+ tmp = nm_keyfile_plugin_connection_from_file (full_path, error);
+ if (!tmp)
+ return NULL;
+ }
+
+ object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL);
+ if (!object)
+ goto out;
+
+ priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
+ priv->path = g_strdup (full_path);
+
+ /* Update our settings with what was read from the file */
+ if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) {
+ g_object_unref (object);
+ object = NULL;
+ goto out;
+ }
+
+ uuid = nm_connection_get_uuid (NM_CONNECTION (object));
+ if (!uuid) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "Connection in file %s had no UUID", full_path);
+ g_object_unref (object);
+ object = NULL;
+ }
+
+out:
+ g_object_unref (tmp);
+ return (NMKeyfileConnection *) object;
+}
+
+const char *
+nm_keyfile_connection_get_path (NMKeyfileConnection *self)
+{
+ g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL);
+
+ return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path;
+}
+
+static void
+commit_changes (NMSettingsConnection *connection,
+ NMSettingsConnectionCommitFunc callback,
+ gpointer user_data)
+{
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
+ char *path = NULL;
+ GError *error = NULL;
+
+ if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection),
+ priv->path,
+ &path,
+ &error)) {
+ callback (connection, error, user_data);
+ g_clear_error (&error);
+ return;
+ }
+
+ /* Update the filename if it changed */
+ if (path) {
+ g_free (priv->path);
+ priv->path = path;
+ }
+
+ NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection,
+ callback,
+ user_data);
+}
+
+static void
+do_delete (NMSettingsConnection *connection,
+ NMSettingsConnectionDeleteFunc callback,
+ gpointer user_data)
+{
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
+
+ g_unlink (priv->path);
+
+ NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection,
+ callback,
+ user_data);
+}
+
+/* GObject */
+
+static void
+nm_keyfile_connection_init (NMKeyfileConnection *connection)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
+
+ nm_connection_clear_secrets (NM_CONNECTION (object));
+
+ g_free (priv->path);
+
+ G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object);
+}
+
+static void
+nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class);
+ NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class);
+
+ g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->finalize = finalize;
+ settings_class->commit_changes = commit_changes;
+ settings_class->delete = do_delete;
+}
diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h
new file mode 100644
index 000000000..bf64e69a3
--- /dev/null
+++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef NM_KEYFILE_CONNECTION_H
+#define NM_KEYFILE_CONNECTION_H
+
+#include <nm-settings-connection.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_KEYFILE_CONNECTION (nm_keyfile_connection_get_type ())
+#define NM_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnection))
+#define NM_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass))
+#define NM_IS_KEYFILE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION))
+#define NM_IS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION))
+#define NM_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass))
+
+typedef struct {
+ NMSettingsConnection parent;
+} NMKeyfileConnection;
+
+typedef struct {
+ NMSettingsConnectionClass parent;
+} NMKeyfileConnectionClass;
+
+GType nm_keyfile_connection_get_type (void);
+
+NMKeyfileConnection *nm_keyfile_connection_new (const char *filename,
+ NMConnection *source,
+ GError **error);
+
+const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self);
+
+G_END_DECLS
+
+#endif /* NM_KEYFILE_CONNECTION_H */
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
new file mode 100644
index 000000000..ffc614bc5
--- /dev/null
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -0,0 +1,654 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/ether.h>
+#include <string.h>
+
+#include <gmodule.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+
+#include <nm-connection.h>
+#include <nm-setting.h>
+#include <nm-setting-connection.h>
+
+#include "plugin.h"
+#include "nm-system-config-interface.h"
+#include "nm-keyfile-connection.h"
+#include "writer.h"
+#include "common.h"
+#include "utils.h"
+
+#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
+#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
+
+static char *plugin_get_hostname (SCPluginKeyfile *plugin);
+static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+ system_config_interface_init))
+
+#define SC_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfilePrivate))
+
+typedef struct {
+ GHashTable *hash;
+
+ GFileMonitor *monitor;
+ guint monitor_id;
+
+ const char *conf_file;
+ GFileMonitor *conf_file_monitor;
+ guint conf_file_monitor_id;
+
+ char *hostname;
+
+ gboolean disposed;
+} SCPluginKeyfilePrivate;
+
+static NMSettingsConnection *
+_internal_new_connection (SCPluginKeyfile *self,
+ const char *full_path,
+ NMConnection *source,
+ GError **error)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+ NMKeyfileConnection *connection;
+
+ g_return_val_if_fail (full_path != NULL, NULL);
+
+ connection = nm_keyfile_connection_new (full_path, source, error);
+ if (connection) {
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_path (connection),
+ connection);
+ }
+
+ return (NMSettingsConnection *) connection;
+}
+
+static void
+read_connections (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+ GDir *dir;
+ GError *error = NULL;
+ const char *item;
+
+ dir = g_dir_open (KEYFILE_DIR, 0, &error);
+ if (!dir) {
+ PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s",
+ KEYFILE_DIR,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ while ((item = g_dir_read_name (dir))) {
+ NMSettingsConnection *connection;
+ char *full_path;
+
+ if (nm_keyfile_plugin_utils_should_ignore_file (item))
+ continue;
+
+ full_path = g_build_filename (KEYFILE_DIR, item, NULL);
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item);
+
+ connection = _internal_new_connection (self, full_path, NULL, &error);
+ if (connection) {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'",
+ nm_connection_get_id (NM_CONNECTION (connection)));
+ } else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ }
+ g_clear_error (&error);
+ g_free (full_path);
+ }
+ g_dir_close (dir);
+}
+
+static void
+update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, gpointer user_data)
+{
+ if (error) {
+ g_warning ("%s: '%s' / '%s' invalid: %d",
+ __func__,
+ error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
+ (error && error->message) ? error->message : "(none)",
+ error ? error->code : -1);
+ g_clear_error (&error);
+
+ nm_settings_connection_signal_remove (orig);
+ }
+}
+
+static void
+update_connection_settings (NMKeyfileConnection *orig,
+ NMKeyfileConnection *new)
+{
+ nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (orig),
+ NM_CONNECTION (new),
+ update_connection_settings_commit_cb, NULL);
+}
+
+/* Monitoring */
+
+static void
+remove_connection (SCPluginKeyfile *self,
+ NMKeyfileConnection *connection,
+ const char *name)
+{
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (name != NULL);
+
+ /* Removing from the hash table should drop the last reference */
+ g_object_ref (connection);
+ g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name);
+ nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
+ g_object_unref (connection);
+}
+
+static NMKeyfileConnection *
+find_by_uuid (SCPluginKeyfile *self, const char *uuid)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer data = NULL;
+
+ g_return_val_if_fail (uuid != NULL, NULL);
+
+ g_hash_table_iter_init (&iter, priv->hash);
+ while (g_hash_table_iter_next (&iter, NULL, &data)) {
+ NMConnection *candidate = NM_CONNECTION (data);
+
+ if (strcmp (uuid, nm_connection_get_uuid (candidate)) == 0)
+ return NM_KEYFILE_CONNECTION (candidate);
+ }
+ return NULL;
+}
+
+static void
+dir_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data);
+ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+ char *full_path;
+ NMKeyfileConnection *connection;
+ GError *error = NULL;
+
+ full_path = g_file_get_path (file);
+ if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) {
+ g_free (full_path);
+ return;
+ }
+
+ connection = g_hash_table_lookup (priv->hash, full_path);
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ if (connection) {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", full_path);
+ remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path);
+ }
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ if (connection) {
+ /* Update */
+ NMKeyfileConnection *tmp;
+
+ tmp = nm_keyfile_connection_new (full_path, NULL, &error);
+ if (tmp) {
+ if (!nm_connection_compare (NM_CONNECTION (connection),
+ NM_CONNECTION (tmp),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path);
+ update_connection_settings (connection, tmp);
+ }
+ g_object_unref (tmp);
+ } else {
+ /* Error; remove the connection */
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path);
+ }
+ } else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path);
+
+ /* New */
+ connection = nm_keyfile_connection_new (full_path, NULL, &error);
+ if (connection) {
+ NMKeyfileConnection *found = NULL;
+
+ /* Connection renames will show up as different files but with
+ * the same UUID. Try to find the original connection.
+ * A connection rename is treated just like an update except
+ * there's a bit more housekeeping with the hash table.
+ */
+ found = find_by_uuid (self, nm_connection_get_uuid (NM_CONNECTION (connection)));
+ if (found) {
+ const char *old_path = nm_keyfile_connection_get_path (connection);
+
+ /* Removing from the hash table should drop the last reference,
+ * but of course we want to keep the connection around.
+ */
+ g_object_ref (found);
+ g_hash_table_remove (priv->hash, old_path);
+
+ /* Updating settings should update the NMKeyfileConnection's
+ * filename property too.
+ */
+ update_connection_settings (found, connection);
+
+ /* Re-insert the connection back into the hash with the new filename */
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_path (found),
+ found);
+
+ /* Get rid of the temporary connection */
+ g_object_unref (connection);
+ } else {
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_path (connection),
+ connection);
+ g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
+ }
+ } else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ g_free (full_path);
+}
+
+static void
+conf_file_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer data)
+{
+ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (data);
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+ char *tmp;
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+
+ /* hostname */
+ tmp = plugin_get_hostname (self);
+ if ((tmp && !priv->hostname)
+ || (!tmp && priv->hostname)
+ || (priv->hostname && tmp && strcmp (priv->hostname, tmp))) {
+
+ g_free (priv->hostname);
+ priv->hostname = tmp;
+ tmp = NULL;
+ g_object_notify (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+ }
+
+ g_free (tmp);
+
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+setup_monitoring (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ GFile *file;
+ GFileMonitor *monitor;
+
+ priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
+
+ file = g_file_new_for_path (KEYFILE_DIR);
+ monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config);
+ priv->monitor = monitor;
+ }
+
+ file = g_file_new_for_path (priv->conf_file);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
+ priv->conf_file_monitor = monitor;
+ }
+}
+
+/* Plugin */
+
+static GSList *
+get_connections (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ GHashTableIter iter;
+ gpointer data = NULL;
+ GSList *list = NULL;
+
+ if (!priv->hash) {
+ setup_monitoring (config);
+ read_connections (config);
+ }
+
+ g_hash_table_iter_init (&iter, priv->hash);
+ while (g_hash_table_iter_next (&iter, NULL, &data))
+ list = g_slist_prepend (list, data);
+ return list;
+}
+
+static NMSettingsConnection *
+add_connection (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ GError **error)
+{
+ SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+ NMSettingsConnection *added = NULL;
+ char *path = NULL;
+
+ /* Write it out first, then add the connection to our internal list */
+ if (nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) {
+ added = _internal_new_connection (self, path, connection, error);
+ g_free (path);
+ }
+ return added;
+}
+
+static GSList *
+get_unmanaged_specs (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ GKeyFile *key_file;
+ GSList *specs = NULL;
+ GError *error = NULL;
+
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) {
+ char *str;
+
+ str = g_key_file_get_value (key_file, "keyfile", "unmanaged-devices", NULL);
+ if (str) {
+ char **udis;
+ int i;
+
+ udis = g_strsplit (str, ";", -1);
+ g_free (str);
+
+ for (i = 0; udis[i] != NULL; i++) {
+ /* Verify unmanaged specification and add it to the list */
+ if (strlen (udis[i]) > 4 && !strncmp (udis[i], "mac:", 4) && ether_aton (udis[i] + 4)) {
+ char *p = udis[i];
+
+ /* To accept uppercase MACs in configuration file, we have to convert values to lowercase here.
+ * Unmanaged MACs in specs are always in lowercase. */
+ while (*p) {
+ *p = g_ascii_tolower (*p);
+ p++;
+ }
+ specs = g_slist_append (specs, udis[i]);
+ } else {
+ g_warning ("Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]);
+ g_free (udis[i]);
+ }
+ }
+
+ g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */
+ }
+ } else {
+ g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message);
+ g_error_free (error);
+ }
+
+ g_key_file_free (key_file);
+
+ return specs;
+}
+
+static char *
+plugin_get_hostname (SCPluginKeyfile *plugin)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
+ GKeyFile *key_file;
+ char *hostname = NULL;
+ GError *error = NULL;
+
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error))
+ hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL);
+ else {
+ g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message);
+ g_error_free (error);
+ }
+
+ g_key_file_free (key_file);
+
+ return hostname;
+}
+
+static gboolean
+plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
+ GKeyFile *key_file;
+ GError *error = NULL;
+ gboolean result = FALSE;
+
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) {
+ char *data;
+ gsize len;
+
+ g_key_file_set_string (key_file, "keyfile", "hostname", hostname);
+
+ data = g_key_file_to_data (key_file, &len, &error);
+ if (data) {
+ g_file_set_contents (priv->conf_file, data, len, &error);
+ g_free (data);
+
+ g_free (priv->hostname);
+ priv->hostname = g_strdup (hostname);
+ result = TRUE;
+ }
+
+ if (error) {
+ g_warning ("Error saving hostname: %s", error->message);
+ g_error_free (error);
+ }
+ } else {
+ g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message);
+ g_error_free (error);
+ }
+
+ g_key_file_free (key_file);
+
+ return result;
+}
+
+/* GObject */
+
+static void
+sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
+
+ if (g_file_test (CONF_FILE, G_FILE_TEST_EXISTS))
+ priv->conf_file = CONF_FILE;
+ else
+ priv->conf_file = OLD_CONF_FILE;
+
+ priv->hostname = plugin_get_hostname (plugin);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, KEYFILE_PLUGIN_NAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, KEYFILE_PLUGIN_INFO);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
+ g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS |
+ NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ g_value_set_string (value, SC_PLUGIN_KEYFILE_GET_PRIVATE (object)->hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ const char *hostname;
+
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ hostname = g_value_get_string (value);
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ plugin_set_hostname (SC_PLUGIN_KEYFILE (object), hostname);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (object);
+
+ if (priv->disposed)
+ return;
+
+ priv->disposed = TRUE;
+
+ if (priv->monitor) {
+ if (priv->monitor_id)
+ g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+
+ g_file_monitor_cancel (priv->monitor);
+ g_object_unref (priv->monitor);
+ }
+
+ if (priv->conf_file_monitor) {
+ if (priv->conf_file_monitor_id)
+ g_signal_handler_disconnect (priv->conf_file_monitor, priv->conf_file_monitor_id);
+
+ g_file_monitor_cancel (priv->conf_file_monitor);
+ g_object_unref (priv->conf_file_monitor);
+ }
+
+ g_free (priv->hostname);
+
+ if (priv->hash)
+ g_hash_table_destroy (priv->hash);
+
+ G_OBJECT_CLASS (sc_plugin_keyfile_parent_class)->dispose (object);
+}
+
+static void
+sc_plugin_keyfile_class_init (SCPluginKeyfileClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginKeyfilePrivate));
+
+ object_class->dispose = dispose;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
+ NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
+ NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+ /* interface implementation */
+ system_config_interface_class->get_connections = get_connections;
+ system_config_interface_class->add_connection = add_connection;
+ system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
+}
+
+GObject *
+nm_settings_keyfile_plugin_new (void)
+{
+ static SCPluginKeyfile *singleton = NULL;
+
+ if (!singleton)
+ singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
+ else
+ g_object_ref (singleton);
+
+ return G_OBJECT (singleton);
+}
diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h
new file mode 100644
index 000000000..af5147ef1
--- /dev/null
+++ b/src/settings/plugins/keyfile/plugin.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define SC_TYPE_PLUGIN_KEYFILE (sc_plugin_keyfile_get_type ())
+#define SC_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfile))
+#define SC_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass))
+#define SC_IS_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE))
+#define SC_IS_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE))
+#define SC_PLUGIN_KEYFILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass))
+
+typedef struct {
+ GObject parent;
+} SCPluginKeyfile;
+
+typedef struct {
+ GObjectClass parent;
+} SCPluginKeyfileClass;
+
+GType sc_plugin_keyfile_get_type (void);
+
+GQuark keyfile_plugin_error_quark (void);
+
+GObject *nm_settings_keyfile_plugin_new (void);
+
+#endif /* _PLUGIN_H_ */
diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c
new file mode 100644
index 000000000..a8eaaa8e2
--- /dev/null
+++ b/src/settings/plugins/keyfile/reader.c
@@ -0,0 +1,1266 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2009 Novell, Inc.
+ * Copyright (C) 2008 - 2010 Red Hat, Inc.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dbus/dbus-glib.h>
+#include <nm-setting.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-8021x.h>
+#include <arpa/inet.h>
+#include <netinet/ether.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "nm-dbus-glib-types.h"
+#include "reader.h"
+#include "common.h"
+
+static gboolean
+read_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key)
+{
+ GArray *array = NULL;
+ gsize length;
+ int i;
+ gint *tmp;
+
+ tmp = g_key_file_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL);
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
+ for (i = 0; i < length; i++)
+ g_array_append_val (array, tmp[i]);
+
+ if (array) {
+ g_object_set (setting, key, array, NULL);
+ g_array_free (array, TRUE);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *out)
+{
+ long tmp;
+
+ errno = 0;
+ tmp = strtol (str, NULL, 10);
+ if (errno || (tmp < 0) || (tmp > max_val)) {
+ g_warning ("%s: ignoring invalid IP %s item '%s'", __func__, key_name, str);
+ return FALSE;
+ }
+
+ *out = (guint32) tmp;
+ return TRUE;
+}
+
+static void
+free_one_ip4_address (gpointer data, gpointer user_data)
+{
+ g_array_free ((GArray *) data, TRUE);
+}
+
+static GPtrArray *
+read_ip4_addresses (GKeyFile *file,
+ const char *setting_name,
+ const char *key)
+{
+ GPtrArray *addresses;
+ int i = 0;
+
+ addresses = g_ptr_array_sized_new (3);
+
+ /* Look for individual addresses */
+ while (i++ < 1000) {
+ gchar **tmp, **iter;
+ char *key_name;
+ gsize length = 0;
+ int ret;
+ GArray *address;
+ guint32 empty = 0;
+ int j;
+
+ key_name = g_strdup_printf ("%s%d", key, i);
+ tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL);
+ g_free (key_name);
+
+ if (!tmp || !length)
+ break; /* all done */
+
+ if ((length < 2) || (length > 3)) {
+ g_warning ("%s: ignoring invalid IPv4 address item '%s'", __func__, key_name);
+ goto next;
+ }
+
+ /* convert the string array into IP addresses */
+ address = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+ for (iter = tmp, j = 0; *iter; iter++, j++) {
+ struct in_addr addr;
+
+ if (j == 1) {
+ guint32 prefix = 0;
+
+ /* prefix */
+ if (!get_one_int (*iter, 32, key_name, &prefix)) {
+ g_array_free (address, TRUE);
+ goto next;
+ }
+
+ g_array_append_val (address, prefix);
+ } else {
+ /* address and gateway */
+ ret = inet_pton (AF_INET, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter);
+ g_array_free (address, TRUE);
+ goto next;
+ }
+ g_array_append_val (address, addr.s_addr);
+ }
+ }
+
+ /* fill in blank gateway if not specified */
+ if (address->len == 2)
+ g_array_append_val (address, empty);
+
+ g_ptr_array_add (addresses, address);
+
+next:
+ g_strfreev (tmp);
+ }
+
+ if (addresses->len < 1) {
+ g_ptr_array_free (addresses, TRUE);
+ addresses = NULL;
+ }
+
+ return addresses;
+}
+
+static void
+ip4_addr_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ GPtrArray *addresses;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ addresses = read_ip4_addresses (keyfile, setting_name, key);
+
+ /* Work around for previous syntax */
+ if (!addresses && !strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+ addresses = read_ip4_addresses (keyfile, setting_name, "address");
+
+ if (addresses) {
+ g_object_set (setting, key, addresses, NULL);
+ g_ptr_array_foreach (addresses, free_one_ip4_address, NULL);
+ g_ptr_array_free (addresses, TRUE);
+ }
+}
+
+static void
+free_one_ip4_route (gpointer data, gpointer user_data)
+{
+ g_array_free ((GArray *) data, TRUE);
+}
+
+static GPtrArray *
+read_ip4_routes (GKeyFile *file,
+ const char *setting_name,
+ const char *key)
+{
+ GPtrArray *routes;
+ int i = 0;
+
+ routes = g_ptr_array_sized_new (3);
+
+ /* Look for individual routes */
+ while (i++ < 1000) {
+ gchar **tmp, **iter;
+ char *key_name;
+ gsize length = 0;
+ int ret;
+ GArray *route;
+ int j;
+
+ key_name = g_strdup_printf ("%s%d", key, i);
+ tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL);
+ g_free (key_name);
+
+ if (!tmp || !length)
+ break; /* all done */
+
+ if (length != 4) {
+ g_warning ("%s: ignoring invalid IPv4 route item '%s'", __func__, key_name);
+ goto next;
+ }
+
+ /* convert the string array into IP addresses */
+ route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
+ for (iter = tmp, j = 0; *iter; iter++, j++) {
+ struct in_addr addr;
+
+ if (j == 1) {
+ guint32 prefix = 0;
+
+ /* prefix */
+ if (!get_one_int (*iter, 32, key_name, &prefix)) {
+ g_array_free (route, TRUE);
+ goto next;
+ }
+
+ g_array_append_val (route, prefix);
+ } else if (j == 3) {
+ guint32 metric = 0;
+
+ /* metric */
+ if (!get_one_int (*iter, G_MAXUINT32, key_name, &metric)) {
+ g_array_free (route, TRUE);
+ goto next;
+ }
+
+ g_array_append_val (route, metric);
+ } else {
+ /* address and next hop */
+ ret = inet_pton (AF_INET, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter);
+ g_array_free (route, TRUE);
+ goto next;
+ }
+ g_array_append_val (route, addr.s_addr);
+ }
+ }
+ g_ptr_array_add (routes, route);
+
+next:
+ g_strfreev (tmp);
+ }
+
+ if (routes->len < 1) {
+ g_ptr_array_free (routes, TRUE);
+ routes = NULL;
+ }
+
+ return routes;
+}
+
+static void
+ip4_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ GPtrArray *routes;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ routes = read_ip4_routes (keyfile, setting_name, key);
+ if (routes) {
+ g_object_set (setting, key, routes, NULL);
+ g_ptr_array_foreach (routes, free_one_ip4_route, NULL);
+ g_ptr_array_free (routes, TRUE);
+ }
+}
+
+static void
+ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ GArray *array = NULL;
+ gsize length;
+ char **list, **iter;
+ int ret;
+
+ list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL);
+ if (!list || !g_strv_length (list))
+ return;
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
+ for (iter = list; *iter; iter++) {
+ struct in_addr addr;
+
+ ret = inet_pton (AF_INET, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid DNS server address '%s'", __func__, *iter);
+ continue;
+ }
+
+ g_array_append_val (array, addr.s_addr);
+ }
+ g_strfreev (list);
+
+ if (array) {
+ g_object_set (setting, key, array, NULL);
+ g_array_free (array, TRUE);
+ }
+}
+
+static void
+free_one_ip6_address (gpointer data, gpointer user_data)
+{
+ g_value_array_free ((GValueArray *) data);
+}
+
+static char *
+split_prefix (char *addr)
+{
+ char *slash;
+
+ g_return_val_if_fail (addr != NULL, NULL);
+
+ /* Find the prefix and split the string */
+ slash = strchr (addr, '/');
+ if (slash && slash > addr) {
+ slash++;
+ *(slash - 1) = '\0';
+ }
+
+ return slash;
+}
+
+static char *
+split_gw (char *str)
+{
+ char *comma;
+
+ g_return_val_if_fail (str != NULL, NULL);
+
+ /* Find the prefix and split the string */
+ comma = strchr (str, ',');
+ if (comma && comma > str) {
+ comma++;
+ *(comma - 1) = '\0';
+ return comma;
+ }
+ return NULL;
+}
+
+static GPtrArray *
+read_ip6_addresses (GKeyFile *file,
+ const char *setting_name,
+ const char *key)
+{
+ GPtrArray *addresses;
+ struct in6_addr addr, gw;
+ guint32 prefix;
+ int i = 0;
+
+ addresses = g_ptr_array_sized_new (3);
+
+ /* Look for individual addresses */
+ while (i++ < 1000) {
+ char *tmp, *key_name, *str_prefix, *str_gw;
+ int ret;
+ GValueArray *values;
+ GByteArray *address;
+ GByteArray *gateway;
+ GValue value = { 0 };
+
+ key_name = g_strdup_printf ("%s%d", key, i);
+ tmp = g_key_file_get_string (file, setting_name, key_name, NULL);
+ g_free (key_name);
+
+ if (!tmp)
+ break; /* all done */
+
+ /* convert the string array into IPv6 addresses */
+ values = g_value_array_new (2); /* NMIP6Address has 2 items */
+
+ /* Split the address and prefix */
+ str_prefix = split_prefix (tmp);
+
+ /* address */
+ ret = inet_pton (AF_INET6, tmp, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp);
+ g_value_array_free (values);
+ goto next;
+ }
+
+ address = g_byte_array_new ();
+ g_byte_array_append (address, (guint8 *) addr.s6_addr, 16);
+ g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&value, address);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ /* prefix */
+ prefix = 0;
+ if (str_prefix) {
+ if (!get_one_int (str_prefix, 128, key_name, &prefix)) {
+ g_value_array_free (values);
+ goto next;
+ }
+ } else {
+ /* Missing prefix defaults to /64 */
+ prefix = 64;
+ }
+
+ g_value_init (&value, G_TYPE_UINT);
+ g_value_set_uint (&value, prefix);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ /* Gateway (optional) */
+ str_gw = split_gw (str_prefix);
+ if (str_gw) {
+ ret = inet_pton (AF_INET6, str_gw, &gw);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv6 %s gateway '%s'", __func__, key_name, tmp);
+ g_value_array_free (values);
+ goto next;
+ }
+
+ if (!IN6_IS_ADDR_UNSPECIFIED (&gw)) {
+ gateway = g_byte_array_new ();
+ g_byte_array_append (gateway, (guint8 *) gw.s6_addr, 16);
+ g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&value, gateway);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+ }
+ }
+
+ g_ptr_array_add (addresses, values);
+
+next:
+ g_free (tmp);
+ }
+
+ if (addresses->len < 1) {
+ g_ptr_array_free (addresses, TRUE);
+ addresses = NULL;
+ }
+
+ return addresses;
+}
+
+static void
+ip6_addr_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ GPtrArray *addresses;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ addresses = read_ip6_addresses (keyfile, setting_name, key);
+ if (addresses) {
+ g_object_set (setting, key, addresses, NULL);
+ g_ptr_array_foreach (addresses, free_one_ip6_address, NULL);
+ g_ptr_array_free (addresses, TRUE);
+ }
+}
+
+static void
+free_one_ip6_route (gpointer data, gpointer user_data)
+{
+ g_value_array_free ((GValueArray *) data);
+}
+
+static GPtrArray *
+read_ip6_routes (GKeyFile *file,
+ const char *setting_name,
+ const char *key)
+{
+ GPtrArray *routes;
+ struct in6_addr addr;
+ guint32 prefix, metric;
+ int i = 0;
+
+ routes = g_ptr_array_sized_new (3);
+
+ /* Look for individual routes */
+ while (i++ < 1000) {
+ gchar **tmp;
+ char *key_name, *str_prefix;
+ gsize length = 0;
+ int ret;
+ GValueArray *values;
+ GByteArray *address;
+ GValue value = { 0 };
+
+ key_name = g_strdup_printf ("%s%d", key, i);
+ tmp = g_key_file_get_string_list (file, setting_name, key_name, &length, NULL);
+ g_free (key_name);
+
+ if (!tmp || !length)
+ break; /* all done */
+
+ if (length != 3) {
+ g_warning ("%s: ignoring invalid IPv6 address item '%s'", __func__, key_name);
+ goto next;
+ }
+
+ /* convert the string array into IPv6 routes */
+ values = g_value_array_new (4); /* NMIP6Route has 4 items */
+
+ /* Split the route and prefix */
+ str_prefix = split_prefix (tmp[0]);
+
+ /* destination address */
+ ret = inet_pton (AF_INET6, tmp[0], &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp[0]);
+ g_value_array_free (values);
+ goto next;
+ }
+ address = g_byte_array_new ();
+ g_byte_array_append (address, (guint8 *) addr.s6_addr, 16);
+ g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&value, address);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ /* prefix */
+ prefix = 0;
+ if (str_prefix) {
+ if (!get_one_int (str_prefix, 128, key_name, &prefix)) {
+ g_value_array_free (values);
+ goto next;
+ }
+ } else {
+ /* default to 64 if unspecified */
+ prefix = 64;
+ }
+ g_value_init (&value, G_TYPE_UINT);
+ g_value_set_uint (&value, prefix);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ /* next hop address */
+ ret = inet_pton (AF_INET6, tmp[1], &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv6 %s element '%s'", __func__, key_name, tmp[1]);
+ g_value_array_free (values);
+ goto next;
+ }
+ address = g_byte_array_new ();
+ g_byte_array_append (address, (guint8 *) addr.s6_addr, 16);
+ g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY);
+ g_value_take_boxed (&value, address);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ /* metric */
+ metric = 0;
+ if (!get_one_int (tmp[2], G_MAXUINT32, key_name, &metric)) {
+ g_value_array_free (values);
+ goto next;
+ }
+ g_value_init (&value, G_TYPE_UINT);
+ g_value_set_uint (&value, metric);
+ g_value_array_append (values, &value);
+ g_value_unset (&value);
+
+ g_ptr_array_add (routes, values);
+
+next:
+ g_strfreev (tmp);
+ }
+
+ if (routes->len < 1) {
+ g_ptr_array_free (routes, TRUE);
+ routes = NULL;
+ }
+
+ return routes;
+}
+
+static void
+ip6_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ GPtrArray *routes;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ routes = read_ip6_routes (keyfile, setting_name, key);
+
+ if (routes) {
+ g_object_set (setting, key, routes, NULL);
+ g_ptr_array_foreach (routes, free_one_ip6_route, NULL);
+ g_ptr_array_free (routes, TRUE);
+ }
+}
+
+static void
+free_one_ip6_dns (gpointer data, gpointer user_data)
+{
+ g_byte_array_free ((GByteArray *) data, TRUE);
+}
+
+static void
+ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ GPtrArray *array = NULL;
+ gsize length;
+ char **list, **iter;
+ int ret;
+
+ list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL);
+ if (!list || !g_strv_length (list))
+ return;
+
+ array = g_ptr_array_sized_new (length);
+ for (iter = list; *iter; iter++) {
+ GByteArray *byte_array;
+ struct in6_addr addr;
+
+ ret = inet_pton (AF_INET6, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter);
+ continue;
+ }
+ byte_array = g_byte_array_new ();
+ g_byte_array_append (byte_array, (guint8 *) addr.s6_addr, 16);
+
+ g_ptr_array_add (array, byte_array);
+ }
+ g_strfreev (list);
+
+ if (array) {
+ g_object_set (setting, key, array, NULL);
+ g_ptr_array_foreach (array, free_one_ip6_dns, NULL);
+ g_ptr_array_free (array, TRUE);
+ }
+}
+
+static void
+mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ struct ether_addr *eth;
+ char *tmp_string = NULL, *p;
+ gint *tmp_list;
+ GByteArray *array = NULL;
+ gsize length;
+ int i;
+
+ p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL);
+ if (tmp_string) {
+ /* Look for enough ':' characters to signify a MAC address */
+ i = 0;
+ while (*p) {
+ if (*p == ':')
+ i++;
+ p++;
+ }
+ if (i == 5) {
+ /* parse as a MAC address */
+ eth = ether_aton (tmp_string);
+ if (eth) {
+ g_free (tmp_string);
+ array = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN);
+ goto done;
+ }
+ }
+ }
+ g_free (tmp_string);
+
+ /* Old format; list of ints */
+ tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL);
+ array = g_byte_array_sized_new (length);
+ for (i = 0; i < length; i++) {
+ int val = tmp_list[i];
+ unsigned char v = (unsigned char) (val & 0xFF);
+
+ if (val < 0 || val > 255) {
+ g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not "
+ " between 0 and 255 inclusive)", __func__, setting_name,
+ key, val);
+ } else
+ g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+ }
+ g_free (tmp_list);
+
+done:
+ if (array->len == ETH_ALEN) {
+ g_object_set (setting, key, array, NULL);
+ } else {
+ g_warning ("%s: ignoring invalid MAC address for %s / %s",
+ __func__, setting_name, key);
+ }
+ g_byte_array_free (array, TRUE);
+}
+
+static void
+read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key)
+{
+ char **keys, **iter;
+ char *value;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ keys = g_key_file_get_keys (file, setting_name, NULL, NULL);
+ if (!keys || !*keys)
+ return;
+
+ for (iter = keys; *iter; iter++) {
+ value = g_key_file_get_string (file, setting_name, *iter, NULL);
+ if (!value)
+ continue;
+
+ if (NM_IS_SETTING_VPN (setting)) {
+ if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE))
+ nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value);
+ }
+ g_free (value);
+ }
+ g_strfreev (keys);
+}
+
+static GByteArray *
+get_uchar_array (GKeyFile *keyfile,
+ const char *setting_name,
+ const char *key)
+{
+ GByteArray *array = NULL;
+ char *p, *tmp_string;
+ gint *tmp_list;
+ gsize length;
+ int i;
+
+ /* New format: just a string. We try parsing the new format if there are
+ * no ';' in the string or it's not just numbers.
+ */
+ p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL);
+ if (tmp_string) {
+ gboolean new_format = FALSE;
+
+ if (strchr (p, ';') == NULL)
+ new_format = TRUE;
+ else {
+ new_format = TRUE;
+ while (p && *p) {
+ if (!isdigit (*p++)) {
+ new_format = FALSE;
+ break;
+ }
+ }
+ }
+
+ if (new_format) {
+ array = g_byte_array_sized_new (strlen (tmp_string));
+ g_byte_array_append (array, (guint8 *) tmp_string, strlen (tmp_string));
+ }
+ g_free (tmp_string);
+ }
+
+ if (!array) {
+ /* Old format; list of ints */
+ tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL);
+ array = g_byte_array_sized_new (length);
+ for (i = 0; i < length; i++) {
+ int val = tmp_list[i];
+ unsigned char v = (unsigned char) (val & 0xFF);
+
+ if (val < 0 || val > 255) {
+ g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not "
+ " between 0 and 255 inclusive)", __func__, setting_name,
+ key, val);
+ } else
+ g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+ }
+ g_free (tmp_list);
+ }
+
+ if (array->len == 0) {
+ g_byte_array_free (array, TRUE);
+ array = NULL;
+ }
+ return array;
+}
+
+static void
+ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ GByteArray *array;
+
+ array = get_uchar_array (keyfile, setting_name, key);
+ if (array) {
+ g_object_set (setting, key, array, NULL);
+ g_byte_array_free (array, TRUE);
+ } else {
+ g_warning ("%s: ignoring invalid SSID for %s / %s",
+ __func__, setting_name, key);
+ }
+}
+
+static char *
+get_cert_path (const char *keyfile_path, GByteArray *cert_path)
+{
+ const char *base;
+ char *p = NULL, *path, *dirname, *tmp;
+
+ g_return_val_if_fail (keyfile_path != NULL, NULL);
+ g_return_val_if_fail (cert_path != NULL, NULL);
+
+ base = path = g_malloc0 (cert_path->len + 1);
+ memcpy (path, cert_path->data, cert_path->len);
+
+ if (path[0] == '/')
+ return path;
+
+ p = strrchr (path, '/');
+ if (p)
+ base = p + 1;
+
+ dirname = g_path_get_dirname (keyfile_path);
+ tmp = g_build_path ("/", dirname, base, NULL);
+ g_free (dirname);
+ g_free (path);
+ return tmp;
+}
+
+#define SCHEME_PATH "file://"
+
+static void
+cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ GByteArray *array;
+ gboolean success = FALSE;
+
+ array = get_uchar_array (keyfile, setting_name, key);
+ if (array) {
+ /* Value could be either:
+ * 1) the raw key/cert data as a blob
+ * 2) a path scheme (ie, starts with "file://")
+ * 3) a plain path
+ */
+ if ( (array->len > strlen (SCHEME_PATH))
+ && g_str_has_prefix ((const char *) array->data, SCHEME_PATH)
+ && (array->data[array->len - 1] == '\0')) {
+ /* It's the PATH scheme, can just set plain data */
+ g_object_set (setting, key, array, NULL);
+ success = TRUE;
+ } else if ( (array->len < 500)
+ && g_utf8_validate ((const char *) array->data, array->len, NULL)) {
+ GByteArray *val;
+ char *path;
+
+ path = get_cert_path (keyfile_path, array);
+ if (g_file_test (path, G_FILE_TEST_EXISTS)) {
+ /* Construct the proper value as required for the PATH scheme */
+ val = g_byte_array_sized_new (strlen (SCHEME_PATH) + array->len + 1);
+ g_byte_array_append (val, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH));
+ g_byte_array_append (val, array->data, array->len);
+ g_byte_array_append (val, (const guint8 *) "\0", 1);
+ g_object_set (setting, key, val, NULL);
+ g_byte_array_free (val, TRUE);
+ success = TRUE;
+ }
+ g_free (path);
+ }
+
+ if (!success) {
+ /* Assume it's a simple blob value of the certificate or private key's data */
+ g_object_set (setting, key, array, NULL);
+ }
+
+ g_byte_array_free (array, TRUE);
+ } else {
+ g_warning ("%s: ignoring invalid SSID for %s / %s",
+ __func__, setting_name, key);
+ }
+}
+
+typedef struct {
+ const char *setting_name;
+ const char *key;
+ gboolean check_for_key;
+ void (*parser) (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path);
+} KeyParser;
+
+/* A table of keys that require further parsing/conversion because they are
+ * stored in a format that can't be automatically read using the key's type.
+ * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are
+ * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored
+ * in struct in6_addr internally, but as string in keyfiles.
+ */
+static KeyParser key_parsers[] = {
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES,
+ FALSE,
+ ip4_addr_parser },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES,
+ FALSE,
+ ip6_addr_parser },
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES,
+ FALSE,
+ ip4_route_parser },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES,
+ FALSE,
+ ip6_route_parser },
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS,
+ FALSE,
+ ip4_dns_parser },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS,
+ FALSE,
+ ip6_dns_parser },
+ { NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_BDADDR,
+ TRUE,
+ mac_address_parser },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID,
+ TRUE,
+ ssid_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT,
+ TRUE,
+ cert_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CLIENT_CERT,
+ TRUE,
+ cert_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ TRUE,
+ cert_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_CA_CERT,
+ TRUE,
+ cert_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ TRUE,
+ cert_parser },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ TRUE,
+ cert_parser },
+ { NULL, NULL, FALSE }
+};
+
+typedef struct {
+ GKeyFile *keyfile;
+ const char *keyfile_path;
+} ReadInfo;
+
+static void
+read_one_setting_value (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flags,
+ gpointer user_data)
+{
+ ReadInfo *info = user_data;
+ const char *setting_name;
+ GType type;
+ GError *err = NULL;
+ gboolean check_for_key = TRUE;
+ KeyParser *parser = &key_parsers[0];
+
+ /* Property is not writable */
+ if (!(flags & G_PARAM_WRITABLE))
+ return;
+
+ /* Setting name gets picked up from the keyfile's section name instead */
+ if (!strcmp (key, NM_SETTING_NAME))
+ return;
+
+ /* Don't read the NMSettingConnection object's 'read-only' property */
+ if ( NM_IS_SETTING_CONNECTION (setting)
+ && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY))
+ return;
+
+ setting_name = nm_setting_get_name (setting);
+
+ /* Look through the list of handlers for non-standard format key values */
+ while (parser->setting_name) {
+ if (!strcmp (parser->setting_name, setting_name) && !strcmp (parser->key, key)) {
+ check_for_key = parser->check_for_key;
+ break;
+ }
+ parser++;
+ }
+
+ /* VPN properties don't have the exact key name */
+ if (NM_IS_SETTING_VPN (setting))
+ check_for_key = FALSE;
+
+ /* Check for the exact key in the GKeyFile if required. Most setting
+ * properties map 1:1 to a key in the GKeyFile, but for those properties
+ * like IP addresses and routes where more than one value is actually
+ * encoded by the setting property, this won't be true.
+ */
+ if (check_for_key && !g_key_file_has_key (info->keyfile, setting_name, key, &err)) {
+ /* Key doesn't exist or an error ocurred, thus nothing to do. */
+ if (err) {
+ g_warning ("Error loading setting '%s' value: %s", setting_name, err->message);
+ g_error_free (err);
+ }
+ return;
+ }
+
+ /* If there's a custom parser for this key, handle that before the generic
+ * parsers below.
+ */
+ if (parser && parser->setting_name) {
+ (*parser->parser) (setting, key, info->keyfile, info->keyfile_path);
+ return;
+ }
+
+ type = G_VALUE_TYPE (value);
+
+ if (type == G_TYPE_STRING) {
+ char *str_val;
+
+ str_val = g_key_file_get_string (info->keyfile, setting_name, key, NULL);
+ g_object_set (setting, key, str_val, NULL);
+ g_free (str_val);
+ } else if (type == G_TYPE_UINT) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL);
+ if (int_val < 0)
+ g_warning ("Casting negative value (%i) to uint", int_val);
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_INT) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL);
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_BOOLEAN) {
+ gboolean bool_val;
+
+ bool_val = g_key_file_get_boolean (info->keyfile, setting_name, key, NULL);
+ g_object_set (setting, key, bool_val, NULL);
+ } else if (type == G_TYPE_CHAR) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL);
+ if (int_val < G_MININT8 || int_val > G_MAXINT8)
+ g_warning ("Casting value (%i) to char", int_val);
+
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_UINT64) {
+ char *tmp_str;
+ guint64 uint_val;
+
+ tmp_str = g_key_file_get_value (info->keyfile, setting_name, key, NULL);
+ uint_val = g_ascii_strtoull (tmp_str, NULL, 10);
+ g_free (tmp_str);
+ g_object_set (setting, key, uint_val, NULL);
+ } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
+ gint *tmp;
+ GByteArray *array;
+ gsize length;
+ int i;
+
+ tmp = g_key_file_get_integer_list (info->keyfile, setting_name, key, &length, NULL);
+
+ array = g_byte_array_sized_new (length);
+ for (i = 0; i < length; i++) {
+ int val = tmp[i];
+ unsigned char v = (unsigned char) (val & 0xFF);
+
+ if (val < 0 || val > 255) {
+ g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not "
+ " between 0 and 255 inclusive)", __func__, setting_name,
+ key, val);
+ } else
+ g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+ }
+
+ g_object_set (setting, key, array, NULL);
+ g_byte_array_free (array, TRUE);
+ g_free (tmp);
+ } else if (type == DBUS_TYPE_G_LIST_OF_STRING) {
+ gchar **sa;
+ gsize length;
+ int i;
+ GSList *list = NULL;
+
+ sa = g_key_file_get_string_list (info->keyfile, setting_name, key, &length, NULL);
+ for (i = 0; i < length; i++)
+ list = g_slist_prepend (list, sa[i]);
+
+ list = g_slist_reverse (list);
+ g_object_set (setting, key, list, NULL);
+
+ g_slist_free (list);
+ g_strfreev (sa);
+ } else if (type == DBUS_TYPE_G_MAP_OF_STRING) {
+ read_hash_of_string (info->keyfile, setting, key);
+ } else if (type == DBUS_TYPE_G_UINT_ARRAY) {
+ if (!read_array_of_uint (info->keyfile, setting, key)) {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting_name, key, G_VALUE_TYPE_NAME (value));
+ }
+ } else {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting_name, key, G_VALUE_TYPE_NAME (value));
+ }
+}
+
+static NMSetting *
+read_setting (GKeyFile *file, const char *keyfile_path, const char *setting_name)
+{
+ NMSetting *setting;
+ ReadInfo info = { file, keyfile_path };
+
+ setting = nm_connection_create_setting (setting_name);
+ if (setting)
+ nm_setting_enumerate_values (setting, read_one_setting_value, &info);
+ else
+ g_warning ("Invalid setting name '%s'", setting_name);
+
+ return setting;
+}
+
+static void
+read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn)
+{
+ char **keys, **iter;
+
+ keys = g_key_file_get_keys (file, VPN_SECRETS_GROUP, NULL, NULL);
+ for (iter = keys; *iter; iter++) {
+ char *secret;
+
+ secret = g_key_file_get_string (file, VPN_SECRETS_GROUP, *iter, NULL);
+ if (secret) {
+ nm_setting_vpn_add_secret (s_vpn, *iter, secret);
+ g_free (secret);
+ }
+ }
+ g_strfreev (keys);
+}
+
+NMConnection *
+nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
+{
+ GKeyFile *key_file;
+ struct stat statbuf;
+ gboolean bad_owner, bad_permissions;
+ NMConnection *connection = NULL;
+ NMSettingConnection *s_con;
+ NMSetting *setting;
+ gchar **groups;
+ gsize length;
+ int i;
+ gboolean vpn_secrets = FALSE;
+ const char *ctype;
+ GError *verify_error = NULL;
+
+ if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode)) {
+ g_set_error_literal (error, KEYFILE_PLUGIN_ERROR, 0,
+ "File did not exist or was not a regular file");
+ return NULL;
+ }
+
+ bad_owner = getuid () != statbuf.st_uid;
+ bad_permissions = statbuf.st_mode & 0077;
+
+ if (bad_owner || bad_permissions) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "File permissions (%o) or owner (%d) were insecure",
+ statbuf.st_mode, statbuf.st_uid);
+ return NULL;
+ }
+
+ key_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error))
+ goto out;
+
+ connection = nm_connection_new ();
+
+ groups = g_key_file_get_groups (key_file, &length);
+ for (i = 0; i < length; i++) {
+ /* Only read out secrets when needed */
+ if (!strcmp (groups[i], VPN_SECRETS_GROUP)) {
+ vpn_secrets = TRUE;
+ continue;
+ }
+
+ setting = read_setting (key_file, filename, groups[i]);
+ if (setting)
+ nm_connection_add_setting (connection, setting);
+ }
+
+ /* Make sure that we have the base device type setting even if
+ * the keyfile didn't include it, which can happen when the base
+ * device type setting is all default values (like ethernet).
+ */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if (s_con) {
+ ctype = nm_setting_connection_get_connection_type (s_con);
+ setting = nm_connection_get_setting_by_name (connection, ctype);
+ if (ctype) {
+ if (!setting && !strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME))
+ nm_connection_add_setting (connection, nm_setting_wired_new ());
+ }
+ }
+
+ /* Handle vpn secrets after the 'vpn' setting was read */
+ if (vpn_secrets) {
+ NMSettingVPN *s_vpn;
+
+ s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+ if (s_vpn)
+ read_vpn_secrets (key_file, s_vpn);
+ }
+
+ g_strfreev (groups);
+
+ /* Verify the connection */
+ if (!nm_connection_verify (connection, &verify_error)) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "invalid or missing connection property '%s'",
+ (verify_error && verify_error->message) ? verify_error->message : "(unknown)");
+ g_clear_error (&verify_error);
+ g_object_unref (connection);
+ connection = NULL;
+ }
+
+out:
+ g_key_file_free (key_file);
+ return connection;
+}
diff --git a/src/settings/plugins/keyfile/reader.h b/src/settings/plugins/keyfile/reader.h
new file mode 100644
index 000000000..55819630e
--- /dev/null
+++ b/src/settings/plugins/keyfile/reader.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef _KEYFILE_PLUGIN_READER_H
+#define _KEYFILE_PLUGIN_READER_H
+
+#include <glib.h>
+#include <nm-connection.h>
+
+NMConnection *nm_keyfile_plugin_connection_from_file (const char *filename, GError **error);
+
+#endif /* _KEYFILE_PLUGIN_READER_H */
diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am
new file mode 100644
index 000000000..affe8dcae
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/Makefile.am
@@ -0,0 +1,32 @@
+SUBDIRS=keyfiles
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+noinst_PROGRAMS = test-keyfile
+
+test_keyfile_SOURCES = \
+ test-keyfile.c
+
+test_keyfile_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \
+ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\"
+
+test_keyfile_LDADD = \
+ $(builddir)/../libkeyfile-io.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(DBUS_LIBS)
+
+if WITH_TESTS
+
+check-local: test-keyfile
+ $(abs_builddir)/test-keyfile
+
+endif
+
diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in
new file mode 100644
index 000000000..733b4916b
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/Makefile.in
@@ -0,0 +1,782 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = test-keyfile$(EXEEXT)
+subdir = src/settings/plugins/keyfile/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_keyfile_OBJECTS = test_keyfile-test-keyfile.$(OBJEXT)
+test_keyfile_OBJECTS = $(am_test_keyfile_OBJECTS)
+am__DEPENDENCIES_1 =
+test_keyfile_DEPENDENCIES = $(builddir)/../libkeyfile-io.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(test_keyfile_SOURCES)
+DIST_SOURCES = $(test_keyfile_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = keyfiles
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/libnm-glib \
+ -I$(srcdir)/../
+
+test_keyfile_SOURCES = \
+ test-keyfile.c
+
+test_keyfile_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \
+ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\"
+
+test_keyfile_LDADD = \
+ $(builddir)/../libkeyfile-io.la \
+ $(top_builddir)/libnm-glib/libnm-glib.la \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(DBUS_LIBS)
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+test-keyfile$(EXEEXT): $(test_keyfile_OBJECTS) $(test_keyfile_DEPENDENCIES)
+ @rm -f test-keyfile$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_keyfile_OBJECTS) $(test_keyfile_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_keyfile-test-keyfile.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+test_keyfile-test-keyfile.o: test-keyfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_keyfile-test-keyfile.o -MD -MP -MF $(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o test_keyfile-test-keyfile.o `test -f 'test-keyfile.c' || echo '$(srcdir)/'`test-keyfile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_keyfile-test-keyfile.Tpo $(DEPDIR)/test_keyfile-test-keyfile.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-keyfile.c' object='test_keyfile-test-keyfile.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_keyfile-test-keyfile.o `test -f 'test-keyfile.c' || echo '$(srcdir)/'`test-keyfile.c
+
+test_keyfile-test-keyfile.obj: test-keyfile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_keyfile-test-keyfile.obj -MD -MP -MF $(DEPDIR)/test_keyfile-test-keyfile.Tpo -c -o test_keyfile-test-keyfile.obj `if test -f 'test-keyfile.c'; then $(CYGPATH_W) 'test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/test-keyfile.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_keyfile-test-keyfile.Tpo $(DEPDIR)/test_keyfile-test-keyfile.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-keyfile.c' object='test_keyfile-test-keyfile.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_keyfile_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_keyfile-test-keyfile.obj `if test -f 'test-keyfile.c'; then $(CYGPATH_W) 'test-keyfile.c'; else $(CYGPATH_W) '$(srcdir)/test-keyfile.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+@WITH_TESTS_FALSE@check-local:
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+all-am: Makefile $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am check-local clean clean-generic \
+ clean-libtool clean-noinstPROGRAMS ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am
+
+
+@WITH_TESTS_TRUE@check-local: test-keyfile
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-keyfile
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT
new file mode 100644
index 000000000..cc8a9ee39
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT
@@ -0,0 +1,23 @@
+
+[connection]
+id=AT&T Data Connect BT
+uuid=089130ab-ce28-46e4-ad77-d44869b03d19
+type=bluetooth
+autoconnect=false
+
+[ipv4]
+method=auto
+
+[gsm]
+number=*99#
+username=ISP@CINGULARGPRS.COM
+password=CINGULAR1
+apn=ISP.CINGULAR
+
+[serial]
+baud=115200
+
+[bluetooth]
+bdaddr=00:11:22:33:44:55
+type=dun
+
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain
new file mode 100644
index 000000000..236cca0ed
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain
@@ -0,0 +1,20 @@
+
+[connection]
+id=AT&T Data Connect
+uuid=15d742f1-2b5a-421e-9f27-fcb1fc26d72c
+type=gsm
+autoconnect=false
+
+[ipv4]
+method=auto
+
+[gsm]
+number=*99#
+username=ISP@CINGULARGPRS.COM
+password=CINGULAR1
+apn=ISP.CINGULAR
+network-id=24005
+pin=2345
+
+[serial]
+baud=115200
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
new file mode 100644
index 000000000..0ce032096
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
@@ -0,0 +1,23 @@
+KEYFILES = \
+ Test_Wired_Connection \
+ Test_GSM_Connection \
+ Test_Wireless_Connection \
+ Test_Wired_Connection_MAC_Case \
+ Test_Wired_Connection_IP6 \
+ ATT_Data_Connect_BT \
+ ATT_Data_Connect_Plain \
+ Test_String_SSID \
+ Test_Wired_TLS_Old \
+ Test_Wired_TLS_New
+
+CERTS = \
+ test-ca-cert.pem \
+ test-key-and-cert.pem
+
+EXTRA_DIST = $(KEYFILES) $(CERTS)
+
+check-local:
+ @for f in $(KEYFILES); do \
+ chmod 0600 $(abs_srcdir)/$$f; \
+ done
+
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
new file mode 100644
index 000000000..0b0b35519
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
@@ -0,0 +1,475 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/settings/plugins/keyfile/tests/keyfiles
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+KEYFILES = \
+ Test_Wired_Connection \
+ Test_GSM_Connection \
+ Test_Wireless_Connection \
+ Test_Wired_Connection_MAC_Case \
+ Test_Wired_Connection_IP6 \
+ ATT_Data_Connect_BT \
+ ATT_Data_Connect_Plain \
+ Test_String_SSID \
+ Test_Wired_TLS_Old \
+ Test_Wired_TLS_New
+
+CERTS = \
+ test-ca-cert.pem \
+ test-key-and-cert.pem
+
+EXTRA_DIST = $(KEYFILES) $(CERTS)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/plugins/keyfile/tests/keyfiles/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-am check-local clean clean-generic \
+ clean-libtool distclean distclean-generic distclean-libtool \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am
+
+
+check-local:
+ @for f in $(KEYFILES); do \
+ chmod 0600 $(abs_srcdir)/$$f; \
+ done
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection
new file mode 100644
index 000000000..3d58fee04
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection
@@ -0,0 +1,41 @@
+
+[serial]
+baud=115200
+bits=8
+parity=110
+stopbits=1
+send-delay=0
+
+[connection]
+id=Test GSM Connection
+uuid=05a5ec81-fa72-4b7c-9f85-4a0dfd36c84f
+type=gsm
+autoconnect=false
+timestamp=0
+
+[gsm]
+number=*99#
+username=username
+apn=my.apn
+network-type=0
+band=0
+
+[ppp]
+noauth=false
+refuse-eap=false
+refuse-pap=false
+refuse-chap=false
+refuse-mschap=false
+refuse-mschapv2=false
+nobsdcomp=false
+nodeflate=false
+no-vj-comp=false
+require-mppe=false
+require-mppe-128=false
+mppe-stateful=false
+crtscts=false
+baud=0
+mru=0
+mtu=0
+lcp-echo-failure=5
+lcp-echo-interval=30
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID b/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID
new file mode 100644
index 000000000..4a3b56d24
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID
@@ -0,0 +1,11 @@
+[connection]
+id=Test
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+
+[802-11-wireless]
+ssid=blah blah ssid 1234
+
+[ipv4]
+method=auto
+
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection
new file mode 100644
index 000000000..5785dc248
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection
@@ -0,0 +1,32 @@
+
+[connection]
+id=Test Wired Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+mac-address=00:11:22:33:44:55
+speed=0
+duplex=full
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=manual
+dns=4.2.2.1;4.2.2.2;
+addresses1=192.168.0.5;24;192.168.0.1;
+addresses2=1.2.3.4;16;1.2.1.1;
+ignore-auto-routes=false
+ignore-auto-dns=false
+
+[ipv6]
+method=manual
+dns=1111:dddd::aaaa;1::cafe;
+dns-search=super-domain.com;redhat.com;gnu.org;
+addresses1=abcd:1234:ffff::cdde/64
+addresses2=1:2:3:4:5:6:7:8/96
+routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99;
+ignore-auto-routes=false
+ignore-auto-dns=false
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6 b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6
new file mode 100644
index 000000000..a42dd5d2a
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6
@@ -0,0 +1,20 @@
+
+[connection]
+id=Test Wired Connection IP6
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=disabled
+
+[ipv6]
+method=manual
+addresses1=abcd:1234:ffff::cdde/64,abcd:1234:ffff::cdd1
+dns=1111:dddd::aaaa;1::cafe;
+
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case
new file mode 100644
index 000000000..29aef4949
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case
@@ -0,0 +1,32 @@
+
+[connection]
+id=Test Wired Connection MAC Case
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+mac-address=00:11:aa:BB:CC:55
+speed=0
+duplex=full
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=manual
+dns=4.2.2.1;4.2.2.2;
+addresses1=192.168.0.5;24;192.168.0.1;
+addresses2=1.2.3.4;16;1.2.1.1;
+ignore-auto-routes=false
+ignore-auto-dns=false
+
+[ipv6]
+method=manual
+dns=1111:dddd::aaaa;1::cafe;
+dns-search=super-domain.com;redhat.com;gnu.org;
+addresses1=abcd:1234:ffff::cdde/64
+addresses2=1:2:3:4:5:6:7:8/96
+routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99;
+ignore-auto-routes=false
+ignore-auto-dns=false
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New
new file mode 100644
index 000000000..4cd866862
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=test-ca-cert.pem
+client-cert=test-key-and-cert.pem
+private-key=test-key-and-cert.pem
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old
new file mode 100644
index 000000000..61afdd91c
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;67;65;47;101;97;112;116;101;115;116;95;99;97;95;99;101;114;116;46;112;101;109;0;
+client-cert=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key=102;105;108;101;58;47;47;47;104;111;109;101;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection
new file mode 100644
index 000000000..b1949d0dd
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection
@@ -0,0 +1,22 @@
+[connection]
+id=Test Wireless Connection
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+autoconnect=false
+timestamp=1226604314
+
+[802-11-wireless]
+ssid=110;109;45;116;101;115;116;45;97;112;
+mode=infrastructure
+channel=0
+rate=0
+tx-power=0
+mtu=0
+bssid=00:1a:33:44:99:82
+
+[ipv4]
+method=auto
+ignore-auto-routes=false
+ignore-auto-dns=false
+never-default=false
+
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem b/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem
new file mode 100644
index 000000000..ef1be20d2
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw
+FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE
+AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx
+NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ
+QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55
+IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3
+DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU
+xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc
+Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3
+FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4
+HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm
+J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P
+T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF
+ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO
+BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL
+EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl
+c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
+AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc
+JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT
+p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t
+qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn
+B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp
+3nniskIjbH0xjgZf/nVMyLnjxg==
+-----END CERTIFICATE-----
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem b/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem
new file mode 100644
index 000000000..dec9aa1b8
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem
@@ -0,0 +1,118 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,4DE0615F23D82107
+
+QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz
+L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7
+zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU
+h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW
+ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv
+QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na
+eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo
+cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m
+RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8
+xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr
+T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI
+ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo
+RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ
+EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt
+lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5
+r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4
+aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W
+GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e
+DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE
+lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO
+8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3
+VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt
+G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ
+tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW
+QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1
+-----END RSA PRIVATE KEY-----
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 1 (0x1)
+ Signature Algorithm: md5WithRSAEncryption
+ Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com
+ Validity
+ Not Before: Mar 10 15:13:16 2009 GMT
+ Not After : Mar 8 15:13:16 2019 GMT
+ Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public Key: (2048 bit)
+ Modulus (2048 bit):
+ 00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a:
+ 82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48:
+ ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49:
+ c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8:
+ 03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14:
+ ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9:
+ c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c:
+ 60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d:
+ 44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b:
+ f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d:
+ c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75:
+ d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2:
+ 06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38:
+ ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba:
+ ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36:
+ 2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11:
+ a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f:
+ a3:43
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C
+ X509v3 Authority Key Identifier:
+ keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10
+ DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com
+ serial:EB:E7:64:FB:79:F7:22:19
+
+ Signature Algorithm: md5WithRSAEncryption
+ 7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82:
+ f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89:
+ b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b:
+ 12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76:
+ 1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48:
+ 32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02:
+ 85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1:
+ fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c:
+ cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43:
+ 8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71:
+ 1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19:
+ 07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69:
+ 7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62:
+ 8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7:
+ 3b:65:fe:f9
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx
+EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO
+TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx
+HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN
+MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl
+MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG
+A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR
+XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA
+vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9
+jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF
+TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX
+gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj
+ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
+YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww
+gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx
+FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD
+VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3
+IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/
+DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2
+8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr
+vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD
+T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa
+PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk=
+-----END CERTIFICATE-----
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c
new file mode 100644
index 000000000..bfe5aa43d
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/test-keyfile.c
@@ -0,0 +1,2353 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <netinet/ether.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include <nm-utils.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-serial.h>
+#include <nm-setting-ppp.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-8021x.h>
+
+#include "nm-test-helpers.h"
+
+#include "reader.h"
+#include "writer.h"
+
+#define TEST_WIRED_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection"
+#define TEST_WIRELESS_FILE TEST_KEYFILES_DIR"/Test_Wireless_Connection"
+
+static void
+test_read_valid_wired_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
+ const char *tmp;
+ const char *expected_id = "Test Wired Connection";
+ const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+ const guint64 expected_timestamp = 6654332;
+ guint64 timestamp;
+ const char *expected_dns1 = "4.2.2.1";
+ const char *expected_dns2 = "4.2.2.2";
+ struct in_addr addr;
+ const char *expected_address1 = "192.168.0.5";
+ const char *expected_address2 = "1.2.3.4";
+ const char *expected_address1_gw = "192.168.0.1";
+ const char *expected_address2_gw = "1.2.1.1";
+ NMIP4Address *ip4_addr;
+ const char *expected6_dns1 = "1111:dddd::aaaa";
+ const char *expected6_dns2 = "1::cafe";
+ const char *expected6_dnssearch1 = "super-domain.com";
+ const char *expected6_dnssearch2 = "redhat.com";
+ const char *expected6_dnssearch3 = "gnu.org";
+ struct in6_addr addr6;
+ const char *expected6_address1 = "abcd:1234:ffff::cdde";
+ const char *expected6_address2 = "1:2:3:4:5:6:7:8";
+ const char *expected6_route_dest = "a:b:c:d::";
+ const char *expected6_route_nh = "f:e:d:c:1:2:3:4";
+ NMIP6Address *ip6_addr;
+ NMIP6Route *ip6_route;
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_WIRED_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_WIRED_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID */
+ tmp = nm_setting_connection_get_uuid (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+ ASSERT (strcmp (tmp, expected_uuid) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+
+ /* Timestamp */
+ timestamp = nm_setting_connection_get_timestamp (s_con);
+ ASSERT (timestamp == expected_timestamp,
+ "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == TRUE,
+ "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "connection-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_WIRED_FILE,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "connection-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_WIRED_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ ASSERT (nm_setting_wired_get_mtu (s_wired) == 1400,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MTU);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "connection-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip4_config_get_num_dns (s_ip4) == 2,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns1, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET, expected_dns2, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 2,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* Address #1 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 0);
+ ASSERT (ip4_addr,
+ "connection-verify-wired", "failed to verify %s: missing IP4 address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 24,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1 prefix",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address1_gw, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1 gateway",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+ ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1 gateway",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ /* Address #2 */
+ ip4_addr = nm_setting_ip4_config_get_address (s_ip4, 1);
+ ASSERT (ip4_addr,
+ "connection-verify-wired", "failed to verify %s: missing IP4 address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip4_address_get_prefix (ip4_addr) == 16,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2 prefix",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address2, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+ ASSERT (nm_ip4_address_get_address (ip4_addr) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET, expected_address2_gw, &addr) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2 gateway",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+ ASSERT (nm_ip4_address_get_gateway (ip4_addr) == addr.s_addr,
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #2 gateway",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "connection-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ /* DNS Addresses */
+ ASSERT (nm_setting_ip6_config_get_num_dns (s_ip6) == 2,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected6_dns1, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP6 address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 0), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (inet_pton (AF_INET6, expected6_dns2, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert DNS IP address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_setting_ip6_config_get_dns (s_ip6, 1), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 2,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ /* DNS Searches */
+ ASSERT (nm_setting_ip6_config_get_num_dns_searches (s_ip6) == 3,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+ ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 0), expected6_dnssearch1),
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+ ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 1), expected6_dnssearch2),
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+ ASSERT (!strcmp (nm_setting_ip6_config_get_dns_search (s_ip6, 2), expected6_dnssearch3),
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #3",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS_SEARCH);
+
+ /* Address #1 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+ ASSERT (ip6_addr,
+ "connection-verify-wired", "failed to verify %s: missing IP6 address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64,
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 address #1 prefix",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ /* Address #2 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 1);
+ ASSERT (ip6_addr,
+ "connection-verify-wired", "failed to verify %s: missing IP6 address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 96,
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 address #2 prefix",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_address2, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 address #2",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ /* Route #1 */
+ ip6_route = nm_setting_ip6_config_get_route (s_ip6, 0);
+ ASSERT (ip6_route,
+ "connection-verify-wired", "failed to verify %s: missing IP6 route #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_route_dest, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP route dest #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_dest (ip6_route), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 route dest #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ ASSERT (nm_ip6_route_get_prefix (ip6_route) == 64,
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 route #1 prefix",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_route_nh, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP route next hop #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_route_get_next_hop (ip6_route), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 route dest #1",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ ASSERT (nm_ip6_route_get_metric (ip6_route) == 99,
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 route #1 metric",
+ TEST_WIRED_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES);
+
+ g_object_unref (connection);
+}
+
+static void
+add_one_ip4_address (NMSettingIP4Config *s_ip4,
+ const char *addr,
+ const char *gw,
+ guint32 prefix)
+{
+ struct in_addr tmp;
+ NMIP4Address *ip4_addr;
+
+ ip4_addr = nm_ip4_address_new ();
+ nm_ip4_address_set_prefix (ip4_addr, prefix);
+
+ inet_pton (AF_INET, addr, &tmp);
+ nm_ip4_address_set_address (ip4_addr, tmp.s_addr);
+
+ inet_pton (AF_INET, gw, &tmp);
+ nm_ip4_address_set_gateway (ip4_addr, tmp.s_addr);
+
+ nm_setting_ip4_config_add_address (s_ip4, ip4_addr);
+ nm_ip4_address_unref (ip4_addr);
+}
+
+static void
+add_one_ip4_route (NMSettingIP4Config *s_ip4,
+ const char *dest,
+ const char *nh,
+ guint32 prefix,
+ guint32 metric)
+{
+ struct in_addr addr;
+ NMIP4Route *route;
+
+ route = nm_ip4_route_new ();
+ nm_ip4_route_set_prefix (route, prefix);
+ nm_ip4_route_set_metric (route, metric);
+
+ inet_pton (AF_INET, dest, &addr);
+ nm_ip4_route_set_dest (route, addr.s_addr);
+
+ inet_pton (AF_INET, nh, &addr);
+ nm_ip4_route_set_next_hop (route, addr.s_addr);
+
+ nm_setting_ip4_config_add_route (s_ip4, route);
+ nm_ip4_route_unref (route);
+}
+
+static void
+add_one_ip6_address (NMSettingIP6Config *s_ip6,
+ const char *addr,
+ guint32 prefix,
+ const char *gw)
+{
+ struct in6_addr tmp;
+ NMIP6Address *ip6_addr;
+
+ ip6_addr = nm_ip6_address_new ();
+ nm_ip6_address_set_prefix (ip6_addr, prefix);
+
+ inet_pton (AF_INET6, addr, &tmp);
+ nm_ip6_address_set_address (ip6_addr, &tmp);
+
+ if (gw) {
+ inet_pton (AF_INET6, gw, &tmp);
+ nm_ip6_address_set_gateway (ip6_addr, &tmp);
+ }
+
+ nm_setting_ip6_config_add_address (s_ip6, ip6_addr);
+ nm_ip6_address_unref (ip6_addr);
+}
+
+static void
+add_one_ip6_route (NMSettingIP6Config *s_ip6,
+ const char *dest,
+ const char *nh,
+ guint32 prefix,
+ guint32 metric)
+{
+ struct in6_addr addr;
+ NMIP6Route *route;
+
+ route = nm_ip6_route_new ();
+ nm_ip6_route_set_prefix (route, prefix);
+ nm_ip6_route_set_metric (route, metric);
+
+ inet_pton (AF_INET6, dest, &addr);
+ nm_ip6_route_set_dest (route, &addr);
+
+ inet_pton (AF_INET6, nh, &addr);
+ nm_ip6_route_set_next_hop (route, &addr);
+
+ nm_setting_ip6_config_add_route (s_ip6, route);
+ nm_ip6_route_unref (route);
+}
+
+
+static void
+test_write_wired_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ GByteArray *mac;
+ unsigned char tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44 };
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ struct in_addr addr;
+ struct in6_addr addr6;
+ const char *dns1 = "4.2.2.1";
+ const char *dns2 = "4.2.2.2";
+ const char *address1 = "192.168.0.5";
+ const char *address1_gw = "192.168.0.1";
+ const char *address2 = "1.2.3.4";
+ const char *address2_gw = "1.2.1.1";
+ const char *route1 = "10.10.10.2";
+ const char *route1_nh = "10.10.10.1";
+ const char *route2 = "1.1.1.1";
+ const char *route2_nh = "1.2.1.1";
+ const char *dns6_1 = "1::cafe";
+ const char *dns6_2 = "2::cafe";
+ const char *address6_1 = "abcd::beef";
+ const char *address6_2 = "dcba::beef";
+ const char *route6_1 = "1:2:3:4:5:6:7:8";
+ const char *route6_1_nh = "8:7:6:5:4:3:2:1";
+ const char *route6_2 = "2001::1000";
+ const char *route6_2_nh = "2001::1111";
+ guint64 timestamp = 0x12345678L;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Work Wired",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+
+ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
+ ASSERT (s_wired != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+ g_object_set (s_wired,
+ NM_SETTING_WIRED_MAC_ADDRESS, mac,
+ NM_SETTING_WIRED_MTU, 900,
+ NULL);
+ g_byte_array_free (mac, TRUE);
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ /* Addresses */
+ add_one_ip4_address (s_ip4, address1, address1_gw, 24);
+ add_one_ip4_address (s_ip4, address2, address2_gw, 8);
+
+ /* Routes */
+ add_one_ip4_route (s_ip4, route1, route1_nh, 24, 3);
+ add_one_ip4_route (s_ip4, route2, route2_nh, 8, 1);
+
+ /* DNS servers */
+ inet_pton (AF_INET, dns1, &addr);
+ nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr);
+ inet_pton (AF_INET, dns2, &addr);
+ nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr);
+
+ /* IP6 setting */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
+ ASSERT (s_ip6 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ /* Addresses */
+ add_one_ip6_address (s_ip6, address6_1, 64, NULL);
+ add_one_ip6_address (s_ip6, address6_2, 56, NULL);
+
+ /* Routes */
+ add_one_ip6_route (s_ip6, route6_1, route6_1_nh, 64, 3);
+ add_one_ip6_route (s_ip6, route6_2, route6_2_nh, 56, 1);
+
+ /* DNS servers */
+ inet_pton (AF_INET6, dns6_1, &addr6);
+ nm_setting_ip6_config_add_dns (s_ip6, &addr6);
+ inet_pton (AF_INET6, dns6_2, &addr6);
+ nm_setting_ip6_config_add_dns (s_ip6, &addr6);
+
+ /* DNS searches */
+ nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com");
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_WIRED_IP6_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_IP6"
+
+static void
+test_read_ip6_wired_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "Test Wired Connection IP6";
+ const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+ struct in6_addr addr6;
+ const char *expected6_address1 = "abcd:1234:ffff::cdde";
+ const char *expected6_gw1 = "abcd:1234:ffff::cdd1";
+ NMIP6Address *ip6_addr;
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_IP6_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_WIRED_IP6_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_WIRED_IP6_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID */
+ tmp = nm_setting_connection_get_uuid (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+ ASSERT (strcmp (tmp, expected_uuid) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "connection-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "connection-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip4_config_get_num_addresses (s_ip4) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS);
+
+ /* ===== IPv6 SETTING ===== */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+ ASSERT (s_ip6 != NULL,
+ "connection-verify-ip6", "failed to verify %s: missing %s setting",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip6_config_get_method (s_ip6);
+ ASSERT (strcmp (tmp, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_METHOD);
+
+ ASSERT (nm_setting_ip6_config_get_num_addresses (s_ip6) == 1,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS);
+
+ /* Address #1 */
+ ip6_addr = nm_setting_ip6_config_get_address (s_ip6, 0);
+ ASSERT (ip6_addr,
+ "connection-verify-wired", "failed to verify %s: missing IP6 address #1",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (nm_ip6_address_get_prefix (ip6_addr) == 64,
+ "connection-verify-wired", "failed to verify %s: unexpected IP6 address #1 prefix",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_address1, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert IP address #1",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_address (ip6_addr), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ ASSERT (inet_pton (AF_INET6, expected6_gw1, &addr6) > 0,
+ "connection-verify-wired", "failed to verify %s: couldn't convert GW address #1",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+ ASSERT (IN6_ARE_ADDR_EQUAL (nm_ip6_address_get_gateway (ip6_addr), &addr6),
+ "connection-verify-wired", "failed to verify %s: unexpected IP4 address #1",
+ TEST_WIRED_IP6_FILE,
+ NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_ip6_wired_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ struct in6_addr addr6;
+ const char *dns = "1::cafe";
+ const char *address = "abcd::beef";
+ const char *gw = "dcba::beef";
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Work Wired IP6",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wired setting */
+
+ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
+ ASSERT (s_wired != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRED_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wired));
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
+ NULL);
+
+ /* IP6 setting */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
+ ASSERT (s_ip6 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+ NULL);
+
+ /* Addresses */
+ add_one_ip6_address (s_ip6, address, 64, gw);
+
+ /* DNS servers */
+ inet_pton (AF_INET6, dns, &addr6);
+ nm_setting_ip6_config_add_dns (s_ip6, &addr6);
+
+ /* DNS searches */
+ nm_setting_ip6_config_add_dns_search (s_ip6, "wallaceandgromit.com");
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_WIRED_MAC_CASE_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection_MAC_Case"
+
+static void
+test_read_wired_mac_case (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWired *s_wired;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_mac_address[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 };
+ const char *tmp;
+ const char *expected_id = "Test Wired Connection MAC Case";
+ const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_WIRED_MAC_CASE_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_WIRED_MAC_CASE_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID */
+ tmp = nm_setting_connection_get_uuid (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+ ASSERT (strcmp (tmp, expected_uuid) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ ASSERT (s_wired != NULL,
+ "connection-verify-wired", "failed to verify %s: missing %s setting",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* MAC address */
+ array = nm_setting_wired_get_mac_address (s_wired);
+ ASSERT (array != NULL,
+ "connection-verify-wired", "failed to verify %s: missing %s / %s key",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (array->len == ETH_ALEN,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+ ASSERT (memcmp (array->data, &expected_mac_address[0], sizeof (expected_mac_address)) == 0,
+ "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRED_MAC_CASE_FILE,
+ NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS);
+
+ g_object_unref (connection);
+}
+
+static void
+test_read_valid_wireless_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_bssid[ETH_ALEN] = { 0x00, 0x1a, 0x33, 0x44, 0x99, 0x82 };
+ const char *tmp;
+ const char *expected_id = "Test Wireless Connection";
+ const char *expected_uuid = "2f962388-e5f3-45af-a62c-ac220b8f7baa";
+ const guint64 expected_timestamp = 1226604314;
+ guint64 timestamp;
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRELESS_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_WIRELESS_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_WIRELESS_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID */
+ tmp = nm_setting_connection_get_uuid (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+ ASSERT (strcmp (tmp, expected_uuid) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+
+ /* Timestamp */
+ timestamp = nm_setting_connection_get_timestamp (s_con);
+ ASSERT (timestamp == expected_timestamp,
+ "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP);
+
+ /* Autoconnect */
+ ASSERT (nm_setting_connection_get_autoconnect (s_con) == FALSE,
+ "connection-verify-connection", "failed to verify %s: unexpected %s /%s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT);
+
+ /* ===== WIRED SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "connection-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* BSSID */
+ array = nm_setting_wireless_get_bssid (s_wireless);
+ ASSERT (array != NULL,
+ "connection-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+ ASSERT (array->len == ETH_ALEN,
+ "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+ ASSERT (memcmp (array->data, &expected_bssid[0], sizeof (expected_bssid)) == 0,
+ "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID);
+
+ /* ===== IPv4 SETTING ===== */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+ ASSERT (s_ip4 != NULL,
+ "connection-verify-ip4", "failed to verify %s: missing %s setting",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+
+ /* Method */
+ tmp = nm_setting_ip4_config_get_method (s_ip4);
+ ASSERT (strcmp (tmp, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0,
+ "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_METHOD);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_wireless_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ NMSettingIP6Config *s_ip6;
+ char *uuid;
+ GByteArray *bssid;
+ unsigned char tmpbssid[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 };
+ GByteArray *ssid;
+ unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 };
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ guint64 timestamp = 0x12344433L;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Work Wireless",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
+ NULL);
+ g_free (uuid);
+
+ /* Wireless setting */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+ ASSERT (s_wireless != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wireless));
+
+ bssid = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bssid, &tmpbssid[0], sizeof (tmpbssid));
+
+ ssid = g_byte_array_sized_new (sizeof (tmpssid));
+ g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid));
+
+ g_object_set (s_wireless,
+ NM_SETTING_WIRELESS_BSSID, bssid,
+ NM_SETTING_WIRELESS_SSID, ssid,
+ NM_SETTING_WIRED_MTU, 1000,
+ NULL);
+
+ g_byte_array_free (bssid, TRUE);
+ g_byte_array_free (ssid, TRUE);
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* IP6 setting */
+
+ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
+ ASSERT (s_ip6 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP6_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+
+ g_object_set (s_ip6,
+ NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_STRING_SSID_FILE TEST_KEYFILES_DIR"/Test_String_SSID"
+
+static void
+test_read_string_ssid (void)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wireless;
+ GError *error = NULL;
+ const GByteArray *array;
+ const char *expected_ssid = "blah blah ssid 1234";
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_STRING_SSID_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_STRING_SSID_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_STRING_SSID_FILE, error->message);
+
+ /* ===== WIRELESS SETTING ===== */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ ASSERT (s_wireless != NULL,
+ "connection-verify-wireless", "failed to verify %s: missing %s setting",
+ TEST_STRING_SSID_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME);
+
+ /* SSID */
+ array = nm_setting_wireless_get_ssid (s_wireless);
+ ASSERT (array != NULL,
+ "connection-verify-wireless", "failed to verify %s: missing %s / %s key",
+ TEST_STRING_SSID_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+ ASSERT (memcmp (array->data, expected_ssid, sizeof (expected_ssid)) == 0,
+ "connection-verify-wireless", "failed to verify %s: unexpected %s / %s key value",
+ TEST_STRING_SSID_FILE,
+ NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_string_ssid (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingIP4Config *s_ip4;
+ char *uuid, *testfile = NULL, *tmp;
+ GByteArray *ssid;
+ unsigned char tmpssid[] = { 65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93 };
+ gboolean success;
+ NMConnection *reread;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ GKeyFile *keyfile;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "String SSID Test",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* Wireless setting */
+
+ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+ ASSERT (s_wireless != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_WIRELESS_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_wireless));
+
+ ssid = g_byte_array_sized_new (sizeof (tmpssid));
+ g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid));
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+ g_byte_array_free (ssid, TRUE);
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Ensure the SSID was written out as a string */
+ keyfile = g_key_file_new ();
+ ASSERT (g_key_file_load_from_file (keyfile, testfile, 0, NULL) == TRUE,
+ "string-ssid-verify", "failed to load keyfile to verify");
+ tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, NULL);
+ ASSERT (tmp, "string-ssid-verify", "failed to load 'ssid' key from file");
+ ASSERT (strlen (tmp) == sizeof (tmpssid),
+ "string-ssid-verify", "reread SSID and expected were different sizes");
+ ASSERT (memcmp (tmp, tmpssid, sizeof (tmpssid)) == 0,
+ "string-ssid-verify", "reread SSID and expected were different");
+ g_free (tmp);
+ g_key_file_free (keyfile);
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_BT_DUN_FILE TEST_KEYFILES_DIR"/ATT_Data_Connect_BT"
+
+static void
+test_read_bt_dun_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingBluetooth *s_bluetooth;
+ NMSettingSerial *s_serial;
+ NMSettingGsm *s_gsm;
+ GError *error = NULL;
+ const GByteArray *array;
+ char expected_bdaddr[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
+ const char *tmp;
+ const char *expected_id = "AT&T Data Connect BT";
+ const char *expected_uuid = "089130ab-ce28-46e4-ad77-d44869b03d19";
+ const char *expected_apn = "ISP.CINGULAR";
+ const char *expected_username = "ISP@CINGULARGPRS.COM";
+ const char *expected_password = "CINGULAR1";
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_BT_DUN_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_BT_DUN_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_BT_DUN_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ /* UUID */
+ tmp = nm_setting_connection_get_uuid (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+ ASSERT (strcmp (tmp, expected_uuid) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_UUID);
+
+ /* ===== BLUETOOTH SETTING ===== */
+
+ s_bluetooth = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+ ASSERT (s_bluetooth != NULL,
+ "connection-verify-bt", "failed to verify %s: missing %s setting",
+ TEST_WIRELESS_FILE,
+ NM_SETTING_WIRED_SETTING_NAME);
+
+ /* BDADDR */
+ array = nm_setting_bluetooth_get_bdaddr (s_bluetooth);
+ ASSERT (array != NULL,
+ "connection-verify-bt", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_BDADDR);
+ ASSERT (array->len == ETH_ALEN,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value length",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_BDADDR);
+ ASSERT (memcmp (array->data, &expected_bdaddr[0], sizeof (expected_bdaddr)) == 0,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_BDADDR);
+
+ /* Type */
+ tmp = nm_setting_bluetooth_get_connection_type (s_bluetooth);
+ ASSERT (tmp != NULL,
+ "connection-verify-bt", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_TYPE);
+ ASSERT (strcmp (tmp, NM_SETTING_BLUETOOTH_TYPE_DUN) == 0,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_TYPE);
+
+ /* ===== GSM SETTING ===== */
+
+ s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+ ASSERT (s_gsm != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s setting",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME);
+
+ /* APN */
+ tmp = nm_setting_gsm_get_apn (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_APN);
+ ASSERT (strcmp (tmp, expected_apn) == 0,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_APN);
+
+ /* Username */
+ tmp = nm_setting_gsm_get_username (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_USERNAME);
+ ASSERT (strcmp (tmp, expected_username) == 0,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_USERNAME);
+
+ /* Password */
+ tmp = nm_setting_gsm_get_password (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PASSWORD);
+ ASSERT (strcmp (tmp, expected_password) == 0,
+ "connection-verify-bt", "failed to verify %s: unexpected %s / %s key value",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PASSWORD);
+
+ /* ===== SERIAL SETTING ===== */
+
+ s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+ ASSERT (s_serial != NULL,
+ "connection-verify-serial", "failed to verify %s: missing %s setting",
+ TEST_BT_DUN_FILE,
+ NM_SETTING_SERIAL_SETTING_NAME);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_bt_dun_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingBluetooth *s_bt;
+ NMSettingIP4Config *s_ip4;
+ NMSettingGsm *s_gsm;
+ char *uuid;
+ GByteArray *bdaddr;
+ unsigned char tmpbdaddr[] = { 0xaa, 0xb9, 0xa1, 0x74, 0x55, 0x44 };
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ guint64 timestamp = 0x12344433L;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
+ NULL);
+ g_free (uuid);
+
+ /* Bluetooth setting */
+
+ s_bt = NM_SETTING_BLUETOOTH (nm_setting_bluetooth_new ());
+ ASSERT (s_bt != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_BLUETOOTH_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_bt));
+
+ bdaddr = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (bdaddr, &tmpbdaddr[0], sizeof (tmpbdaddr));
+
+ g_object_set (s_bt,
+ NM_SETTING_BLUETOOTH_BDADDR, bdaddr,
+ NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN,
+ NULL);
+
+ g_byte_array_free (bdaddr, TRUE);
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* GSM setting */
+ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ());
+ ASSERT (s_gsm != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_GSM_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_gsm));
+
+ g_object_set (s_gsm,
+ NM_SETTING_GSM_APN, "internet2.voicestream.com",
+ NM_SETTING_GSM_USERNAME, "george.clinton",
+ NM_SETTING_GSM_PASSWORD, "parliament",
+ NM_SETTING_GSM_NUMBER, "*99#",
+ NULL);
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_GSM_FILE TEST_KEYFILES_DIR"/ATT_Data_Connect_Plain"
+
+static void
+test_read_gsm_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingSerial *s_serial;
+ NMSettingGsm *s_gsm;
+ NMSetting *s_bluetooth;
+ GError *error = NULL;
+ const char *tmp;
+ const char *expected_id = "AT&T Data Connect";
+ const char *expected_apn = "ISP.CINGULAR";
+ const char *expected_username = "ISP@CINGULARGPRS.COM";
+ const char *expected_password = "CINGULAR1";
+ const char *expected_network_id = "24005";
+ const char *expected_pin = "2345";
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_GSM_FILE, NULL);
+ ASSERT (connection != NULL,
+ "connection-read", "failed to read %s", TEST_GSM_FILE);
+
+ ASSERT (nm_connection_verify (connection, &error),
+ "connection-verify", "failed to verify %s: %s", TEST_GSM_FILE, error->message);
+
+ /* ===== CONNECTION SETTING ===== */
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ ASSERT (s_con != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s setting",
+ TEST_GSM_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME);
+
+ /* ID */
+ tmp = nm_setting_connection_get_id (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, expected_id) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+
+ tmp = nm_setting_connection_get_connection_type (s_con);
+ ASSERT (tmp != NULL,
+ "connection-verify-connection", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_ID);
+ ASSERT (strcmp (tmp, NM_SETTING_GSM_SETTING_NAME) == 0,
+ "connection-verify-connection", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_CONNECTION_SETTING_NAME,
+ NM_SETTING_CONNECTION_TYPE);
+
+ /* ===== BLUETOOTH SETTING ===== */
+
+ /* Plain GSM, so no BT setting expected */
+ s_bluetooth = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+ ASSERT (s_bluetooth == NULL,
+ "connection-verify-bt", "unexpected %s setting",
+ TEST_GSM_FILE,
+ NM_SETTING_BLUETOOTH_SETTING_NAME);
+
+ /* ===== GSM SETTING ===== */
+
+ s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+ ASSERT (s_gsm != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s setting",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME);
+
+ /* APN */
+ tmp = nm_setting_gsm_get_apn (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_APN);
+ ASSERT (strcmp (tmp, expected_apn) == 0,
+ "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_APN);
+
+ /* Username */
+ tmp = nm_setting_gsm_get_username (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_USERNAME);
+ ASSERT (strcmp (tmp, expected_username) == 0,
+ "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_USERNAME);
+
+ /* Password */
+ tmp = nm_setting_gsm_get_password (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PASSWORD);
+ ASSERT (strcmp (tmp, expected_password) == 0,
+ "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PASSWORD);
+
+ /* Network ID */
+ tmp = nm_setting_gsm_get_network_id (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_NETWORK_ID);
+ ASSERT (strcmp (tmp, expected_network_id) == 0,
+ "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_NETWORK_ID);
+
+ /* PIN */
+ tmp = nm_setting_gsm_get_pin (s_gsm);
+ ASSERT (tmp != NULL,
+ "connection-verify-gsm", "failed to verify %s: missing %s / %s key",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PIN);
+ ASSERT (strcmp (tmp, expected_pin) == 0,
+ "connection-verify-gsm", "failed to verify %s: unexpected %s / %s key value",
+ TEST_GSM_FILE,
+ NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_GSM_PIN);
+
+ /* ===== SERIAL SETTING ===== */
+
+ s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+ ASSERT (s_serial != NULL,
+ "connection-verify-serial", "failed to verify %s: missing %s setting",
+ TEST_GSM_FILE,
+ NM_SETTING_SERIAL_SETTING_NAME);
+
+ g_object_unref (connection);
+}
+
+static void
+test_write_gsm_connection (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ NMSettingGsm *s_gsm;
+ char *uuid;
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ pid_t owner_grp;
+ uid_t owner_uid;
+ guint64 timestamp = 0x12344433L;
+
+ connection = nm_connection_new ();
+ ASSERT (connection != NULL,
+ "connection-write", "failed to allocate new connection");
+
+ /* Connection setting */
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ ASSERT (s_con != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_CONNECTION_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "T-Mobile Funkadelic 2",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME,
+ NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
+ NULL);
+ g_free (uuid);
+
+ /* IP4 setting */
+
+ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
+ ASSERT (s_ip4 != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_IP4_CONFIG_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ g_object_set (s_ip4,
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+
+ /* GSM setting */
+ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ());
+ ASSERT (s_gsm != NULL,
+ "connection-write", "failed to allocate new %s setting",
+ NM_SETTING_GSM_SETTING_NAME);
+ nm_connection_add_setting (connection, NM_SETTING (s_gsm));
+
+ g_object_set (s_gsm,
+ NM_SETTING_GSM_APN, "internet2.voicestream.com",
+ NM_SETTING_GSM_USERNAME, "george.clinton.again",
+ NM_SETTING_GSM_PASSWORD, "parliament2",
+ NM_SETTING_GSM_NUMBER, "*99#",
+ NM_SETTING_GSM_PIN, "123456",
+ NM_SETTING_GSM_NETWORK_ID, "254098",
+ NM_SETTING_GSM_HOME_ONLY, TRUE,
+ NM_SETTING_GSM_NETWORK_TYPE, NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA,
+ NULL);
+
+ /* Write out the connection */
+ owner_uid = geteuid ();
+ owner_grp = getegid ();
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error);
+ ASSERT (success == TRUE,
+ "connection-write", "failed to allocate write keyfile: %s",
+ error ? error->message : "(none)");
+
+ ASSERT (testfile != NULL,
+ "connection-write", "didn't get keyfile name back after writing connection");
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, NULL);
+ ASSERT (reread != NULL, "connection-write", "failed to re-read test connection");
+
+ ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
+ "connection-write", "written and re-read connection weren't the same");
+
+ g_clear_error (&error);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+#define TEST_WIRED_TLS_OLD_FILE TEST_KEYFILES_DIR"/Test_Wired_TLS_Old"
+
+static void
+test_read_wired_8021x_tls_old_connection (void)
+{
+ NMConnection *connection;
+ NMSetting *s_wired;
+ NMSetting8021x *s_8021x;
+ GError *error = NULL;
+ const char *tmp;
+ gboolean success;
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_OLD_FILE, &error);
+ if (connection == NULL) {
+ g_assert (error);
+ g_warning ("Failed to read %s: %s", TEST_WIRED_TLS_OLD_FILE, error->message);
+ g_assert (connection);
+ }
+
+ success = nm_connection_verify (connection, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to verify %s: %s", TEST_WIRED_TLS_OLD_FILE, error->message);
+ g_assert (success);
+ }
+
+ /* ===== Wired Setting ===== */
+ s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+ g_assert (s_wired != NULL);
+
+ /* ===== 802.1x Setting ===== */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x != NULL);
+
+ g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ g_assert (g_strcmp0 (tmp, "tls") == 0);
+
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ g_assert (g_strcmp0 (tmp, "Bill Smith") == 0);
+
+ tmp = nm_setting_802_1x_get_private_key_password (s_8021x);
+ g_assert (g_strcmp0 (tmp, "12345testing") == 0);
+
+ tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0);
+
+ tmp = nm_setting_802_1x_get_client_cert_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0);
+
+ tmp = nm_setting_802_1x_get_private_key_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "/home/dcbw/Desktop/certinfra/client.pem") == 0);
+
+ g_object_unref (connection);
+}
+
+#define TEST_WIRED_TLS_NEW_FILE TEST_KEYFILES_DIR"/Test_Wired_TLS_New"
+
+static void
+test_read_wired_8021x_tls_new_connection (void)
+{
+ NMConnection *connection;
+ NMSetting *s_wired;
+ NMSetting8021x *s_8021x;
+ GError *error = NULL;
+ const char *tmp;
+ gboolean success;
+
+ connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_NEW_FILE, &error);
+ if (connection == NULL) {
+ g_assert (error);
+ g_warning ("Failed to read %s: %s", TEST_WIRED_TLS_NEW_FILE, error->message);
+ g_assert (connection);
+ }
+
+ success = nm_connection_verify (connection, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to verify %s: %s", TEST_WIRED_TLS_NEW_FILE, error->message);
+ g_assert (success);
+ }
+
+ /* ===== Wired Setting ===== */
+ s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+ g_assert (s_wired != NULL);
+
+ /* ===== 802.1x Setting ===== */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x != NULL);
+
+ g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
+ tmp = nm_setting_802_1x_get_eap_method (s_8021x, 0);
+ g_assert (g_strcmp0 (tmp, "tls") == 0);
+
+ tmp = nm_setting_802_1x_get_identity (s_8021x);
+ g_assert (g_strcmp0 (tmp, "Bill Smith") == 0);
+
+ tmp = nm_setting_802_1x_get_private_key_password (s_8021x);
+ g_assert (g_strcmp0 (tmp, "12345testing") == 0);
+
+ tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "test-ca-cert.pem") == 0);
+
+ tmp = nm_setting_802_1x_get_client_cert_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "test-key-and-cert.pem") == 0);
+
+ tmp = nm_setting_802_1x_get_private_key_path (s_8021x);
+ g_assert (g_strcmp0 (tmp, "test-key-and-cert.pem") == 0);
+
+ g_object_unref (connection);
+}
+
+#define TEST_WIRED_TLS_CA_CERT TEST_KEYFILES_DIR"/test-ca-cert.pem"
+#define TEST_WIRED_TLS_CLIENT_CERT TEST_KEYFILES_DIR"/test-key-and-cert.pem"
+#define TEST_WIRED_TLS_PRIVKEY TEST_KEYFILES_DIR"/test-key-and-cert.pem"
+
+static NMConnection *
+create_wired_tls_connection (NMSetting8021xCKScheme scheme)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingIP4Config *s_ip4;
+ NMSetting *s_wired;
+ NMSetting8021x *s_8021x;
+ char *uuid;
+ gboolean success;
+ GError *error = NULL;
+
+ connection = nm_connection_new ();
+ g_assert (connection != NULL);
+
+ /* Connection setting */
+ s_con = (NMSettingConnection *) nm_setting_connection_new ();
+ g_assert (s_con);
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_ID, "Wired Really Secure TLS",
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
+ NULL);
+ g_free (uuid);
+
+ /* IP4 setting */
+ s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+ g_assert (s_ip4);
+ g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+
+ /* Wired setting */
+ s_wired = nm_setting_wired_new ();
+ g_assert (s_wired);
+ nm_connection_add_setting (connection, s_wired);
+
+ /* 802.1x setting */
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ g_assert (s_8021x);
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ nm_setting_802_1x_add_eap_method (s_8021x, "tls");
+ g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
+
+ success = nm_setting_802_1x_set_ca_cert (s_8021x,
+ TEST_WIRED_TLS_CA_CERT,
+ scheme,
+ NULL,
+ &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to set CA cert %s: %s", TEST_WIRED_TLS_CA_CERT, error->message);
+ g_assert (success);
+ }
+
+ success = nm_setting_802_1x_set_client_cert (s_8021x,
+ TEST_WIRED_TLS_CLIENT_CERT,
+ scheme,
+ NULL,
+ &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to set client cert %s: %s", TEST_WIRED_TLS_CA_CERT, error->message);
+ g_assert (success);
+ }
+
+ success = nm_setting_802_1x_set_private_key (s_8021x,
+ TEST_WIRED_TLS_PRIVKEY,
+ "test1",
+ scheme,
+ NULL,
+ &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to set private key %s: %s", TEST_WIRED_TLS_CA_CERT, error->message);
+ g_assert (success);
+ }
+
+ return connection;
+}
+
+static void
+test_write_wired_8021x_tls_connection_path (void)
+{
+ NMConnection *connection;
+ char *tmp;
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ GError *error = NULL;
+ GKeyFile *keyfile;
+
+ connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_PATH);
+ g_assert (connection != NULL);
+
+ /* Write out the connection */
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, geteuid (), getegid (), &testfile, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to write keyfile: %s", error->message);
+ g_assert (success);
+ }
+ g_assert (testfile);
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
+ if (!reread) {
+ g_assert (error);
+ g_warning ("Failed to re-read test connection: %s", error->message);
+ g_assert (reread);
+ }
+
+ success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+ if (!reread) {
+ g_warning ("Written and re-read connection weren't the same");
+ g_assert (success);
+ }
+
+ /* Ensure the cert and key values are properly written out */
+ keyfile = g_key_file_new ();
+ g_assert (keyfile);
+ success = g_key_file_load_from_file (keyfile, testfile, G_KEY_FILE_NONE, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to re-read test file %s: %s", testfile, error->message);
+ g_assert (success);
+ }
+
+ /* CA cert */
+ tmp = g_key_file_get_string (keyfile,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT,
+ NULL);
+ g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_CA_CERT) == 0);
+ g_free (tmp);
+
+ /* Client cert */
+ tmp = g_key_file_get_string (keyfile,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CLIENT_CERT,
+ NULL);
+ g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_CLIENT_CERT) == 0);
+ g_free (tmp);
+
+ /* Private key */
+ tmp = g_key_file_get_string (keyfile,
+ NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ NULL);
+ g_assert (g_strcmp0 (tmp, TEST_WIRED_TLS_PRIVKEY) == 0);
+ g_free (tmp);
+
+ g_key_file_free (keyfile);
+ unlink (testfile);
+ g_free (testfile);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+static void
+test_write_wired_8021x_tls_connection_blob (void)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSetting8021x *s_8021x;
+ gboolean success;
+ NMConnection *reread;
+ char *testfile = NULL;
+ char *new_ca_cert;
+ char *new_client_cert;
+ char *new_priv_key;
+ const char *uuid;
+ GError *error = NULL;
+
+ connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_BLOB);
+ g_assert (connection != NULL);
+
+ /* Write out the connection */
+ success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, geteuid (), getegid (), &testfile, &error);
+ if (!success) {
+ g_assert (error);
+ g_warning ("Failed to write keyfile: %s", error->message);
+ g_assert (success);
+ }
+ g_assert (testfile);
+
+ /* Check that the new certs got written out */
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+ uuid = nm_setting_connection_get_uuid (s_con);
+ g_assert (uuid);
+
+ new_ca_cert = g_strdup_printf ("%s/%s-ca-cert.pem", TEST_SCRATCH_DIR, uuid);
+ g_assert (new_ca_cert);
+ g_assert (g_file_test (new_ca_cert, G_FILE_TEST_EXISTS));
+
+ new_client_cert = g_strdup_printf ("%s/%s-client-cert.pem", TEST_SCRATCH_DIR, uuid);
+ g_assert (new_client_cert);
+ g_assert (g_file_test (new_client_cert, G_FILE_TEST_EXISTS));
+
+ new_priv_key = g_strdup_printf ("%s/%s-private-key.pem", TEST_SCRATCH_DIR, uuid);
+ g_assert (new_priv_key);
+ g_assert (g_file_test (new_priv_key, G_FILE_TEST_EXISTS));
+
+ /* Read the connection back in and compare it to the one we just wrote out */
+ reread = nm_keyfile_plugin_connection_from_file (testfile, &error);
+ if (!reread) {
+ g_assert (error);
+ g_warning ("Failed to re-read test connection: %s", error->message);
+ g_assert (reread);
+ }
+
+ /* Ensure the re-read connection's certificates use the path scheme */
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X);
+ g_assert (s_8021x);
+ g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+ g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+ g_assert (nm_setting_802_1x_get_private_key_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+
+ unlink (testfile);
+ g_free (testfile);
+
+ /* Clean up written certs */
+ unlink (new_ca_cert);
+ g_free (new_ca_cert);
+
+ unlink (new_client_cert);
+ g_free (new_client_cert);
+
+ unlink (new_priv_key);
+ g_free (new_priv_key);
+
+ g_object_unref (reread);
+ g_object_unref (connection);
+}
+
+int main (int argc, char **argv)
+{
+ GError *error = NULL;
+ char *base;
+
+ g_type_init ();
+
+ if (!nm_utils_init (&error))
+ FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
+
+ /* The tests */
+ test_read_valid_wired_connection ();
+ test_write_wired_connection ();
+
+ test_read_ip6_wired_connection ();
+ test_write_ip6_wired_connection ();
+
+ test_read_wired_mac_case ();
+
+ test_read_valid_wireless_connection ();
+ test_write_wireless_connection ();
+
+ test_read_string_ssid ();
+ test_write_string_ssid ();
+
+ test_read_bt_dun_connection ();
+ test_write_bt_dun_connection ();
+
+ test_read_gsm_connection ();
+ test_write_gsm_connection ();
+
+ test_read_wired_8021x_tls_old_connection ();
+ test_read_wired_8021x_tls_new_connection ();
+ test_write_wired_8021x_tls_connection_path ();
+ test_write_wired_8021x_tls_connection_blob ();
+
+ base = g_path_get_basename (argv[0]);
+ fprintf (stdout, "%s: SUCCESS\n", base);
+ g_free (base);
+ return 0;
+}
+
diff --git a/src/settings/plugins/keyfile/utils.c b/src/settings/plugins/keyfile/utils.c
new file mode 100644
index 000000000..7b93a245d
--- /dev/null
+++ b/src/settings/plugins/keyfile/utils.c
@@ -0,0 +1,98 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include "utils.h"
+
+
+static const char temp_letters[] =
+"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/*
+ * Check '.[a-zA-Z0-9]{6}' file suffix used for temporary files by g_file_set_contents() (mkstemp()).
+ */
+static gboolean
+check_mkstemp_suffix (const char *path)
+{
+ const char *ptr;
+
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ /* Matches *.[a-zA-Z0-9]{6} suffix of mkstemp()'s temporary files */
+ ptr = strrchr (path, '.');
+ if (ptr && (strspn (ptr + 1, temp_letters) == 6) && (! ptr[7]))
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+check_prefix (const char *base, const char *tag)
+{
+ int len, tag_len;
+
+ g_return_val_if_fail (base != NULL, TRUE);
+ g_return_val_if_fail (tag != NULL, TRUE);
+
+ len = strlen (base);
+ tag_len = strlen (tag);
+ if ((len > tag_len) && !strncasecmp (base, tag, tag_len))
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+check_suffix (const char *base, const char *tag)
+{
+ int len, tag_len;
+
+ g_return_val_if_fail (base != NULL, TRUE);
+ g_return_val_if_fail (tag != NULL, TRUE);
+
+ len = strlen (base);
+ tag_len = strlen (tag);
+ if ((len > tag_len) && !strcasecmp (base + len - tag_len, tag))
+ return TRUE;
+ return FALSE;
+}
+
+gboolean
+nm_keyfile_plugin_utils_should_ignore_file (const char *filename)
+{
+ char *base;
+ gboolean ignore = FALSE;
+
+ g_return_val_if_fail (filename != NULL, TRUE);
+
+ base = g_path_get_basename (filename);
+ g_return_val_if_fail (base != NULL, TRUE);
+
+ /* Ignore files with certain patterns */
+ if ( (check_prefix (base, ".") && check_suffix (base, SWP_TAG)) /* vim temporary files: .filename.swp */
+ || (check_prefix (base, ".") && check_suffix (base, SWPX_TAG)) /* vim temporary files: .filename.swpx */
+ || check_mkstemp_suffix (base) /* temporary files created by mkstemp() */
+ || base[strlen (base) - 1] == '~')
+ ignore = TRUE;
+
+ g_free (base);
+ return ignore;
+}
+
diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h
new file mode 100644
index 000000000..68e6e56f2
--- /dev/null
+++ b/src/settings/plugins/keyfile/utils.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2010 Red Hat, Inc.
+ */
+
+#ifndef _UTILS_H_
+#define _UTILS_H_
+
+#include <glib.h>
+#include "common.h"
+
+gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename);
+
+#endif /* _UTILS_H_ */
+
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
new file mode 100644
index 000000000..5ecf5891c
--- /dev/null
+++ b/src/settings/plugins/keyfile/writer.c
@@ -0,0 +1,1044 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <dbus/dbus-glib.h>
+#include <nm-setting.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-ip6-config.h>
+#include <nm-setting-vpn.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-8021x.h>
+#include <nm-utils.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/ether.h>
+#include <ctype.h>
+
+#include "nm-dbus-glib-types.h"
+#include "writer.h"
+#include "common.h"
+
+static gboolean
+write_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GArray *array;
+ int i;
+ int *tmp_array;
+
+ array = (GArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return TRUE;
+
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = g_array_index (array, int, i);
+
+ g_key_file_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len);
+ g_free (tmp_array);
+ return TRUE;
+}
+
+static void
+ip4_dns_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GArray *array;
+ char **list;
+ int i, num = 0;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY));
+
+ array = (GArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return;
+
+ list = g_new0 (char *, array->len + 1);
+
+ for (i = 0; i < array->len; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ struct in_addr addr;
+
+ addr.s_addr = g_array_index (array, guint32, i);
+ if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
+ g_warning ("%s: error converting IP4 address 0x%X",
+ __func__, ntohl (addr.s_addr));
+ } else
+ list[num++] = g_strdup (buf);
+ }
+
+ g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num);
+ g_strfreev (list);
+}
+
+static void
+write_ip4_values (GKeyFile *file,
+ const char *setting_name,
+ const char *key,
+ GPtrArray *array,
+ guint32 tuple_len,
+ guint32 addr1_pos,
+ guint32 addr2_pos)
+{
+ char **list = NULL;
+ int i, j;
+
+ list = g_new (char *, tuple_len);
+
+ for (i = 0, j = 0; i < array->len; i++, j++) {
+ GArray *tuple = g_ptr_array_index (array, i);
+ gboolean success = TRUE;
+ char *key_name;
+ int k;
+
+ memset (list, 0, tuple_len * sizeof (char *));
+
+ for (k = 0; k < tuple_len; k++) {
+ if (k == addr1_pos || k == addr2_pos) {
+ char buf[INET_ADDRSTRLEN + 1];
+ struct in_addr addr;
+
+ /* IP addresses */
+ addr.s_addr = g_array_index (tuple, guint32, k);
+ if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) {
+ g_warning ("%s: error converting IP4 address 0x%X",
+ __func__, ntohl (addr.s_addr));
+ success = FALSE;
+ break;
+ } else {
+ list[k] = g_strdup (buf);
+ }
+ } else {
+ /* prefix, metric */
+ list[k] = g_strdup_printf ("%d", g_array_index (tuple, guint32, k));
+ }
+ }
+
+ if (success) {
+ key_name = g_strdup_printf ("%s%d", key, j + 1);
+ g_key_file_set_string_list (file, setting_name, key_name, (const char **) list, tuple_len);
+ g_free (key_name);
+ }
+
+ for (k = 0; k < tuple_len; k++)
+ g_free (list[k]);
+ }
+ g_free (list);
+}
+
+static void
+ip4_addr_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT));
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (array && array->len)
+ write_ip4_values (file, setting_name, key, array, 3, 0, 2);
+}
+
+static void
+ip4_route_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT));
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (array && array->len)
+ write_ip4_values (file, setting_name, key, array, 4, 0, 2);
+}
+
+static void
+ip6_dns_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ GByteArray *byte_array;
+ char **list;
+ int i, num = 0;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR));
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return;
+
+ list = g_new0 (char *, array->len + 1);
+
+ for (i = 0; i < array->len; i++) {
+ char buf[INET6_ADDRSTRLEN];
+
+ byte_array = g_ptr_array_index (array, i);
+ if (!inet_ntop (AF_INET6, (struct in6_addr *) byte_array->data, buf, sizeof (buf))) {
+ int j;
+ GString *ip6_str = g_string_new (NULL);
+ g_string_append_printf (ip6_str, "%02X", byte_array->data[0]);
+ for (j = 1; j < 16; j++)
+ g_string_append_printf (ip6_str, " %02X", byte_array->data[j]);
+ g_warning ("%s: error converting IP6 address %s",
+ __func__, ip6_str->str);
+ g_string_free (ip6_str, TRUE);
+ } else
+ list[num++] = g_strdup (buf);
+ }
+
+ g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num);
+ g_strfreev (list);
+}
+
+static gboolean
+ip6_array_to_addr (GValueArray *values,
+ guint32 idx,
+ char *buf,
+ size_t buflen,
+ gboolean *out_is_unspec)
+{
+ GByteArray *byte_array;
+ GValue *addr_val;
+ struct in6_addr *addr;
+
+ g_return_val_if_fail (buflen >= INET6_ADDRSTRLEN, FALSE);
+
+ addr_val = g_value_array_get_nth (values, idx);
+ byte_array = g_value_get_boxed (addr_val);
+ addr = (struct in6_addr *) byte_array->data;
+
+ if (out_is_unspec && IN6_IS_ADDR_UNSPECIFIED (addr))
+ *out_is_unspec = TRUE;
+
+ errno = 0;
+ if (!inet_ntop (AF_INET6, addr, buf, buflen)) {
+ GString *ip6_str = g_string_sized_new (INET6_ADDRSTRLEN + 10);
+
+ /* error converting the address */
+ g_string_append_printf (ip6_str, "%02X", byte_array->data[0]);
+ for (idx = 1; idx < 16; idx++)
+ g_string_append_printf (ip6_str, " %02X", byte_array->data[idx]);
+ g_warning ("%s: error %d converting IP6 address %s",
+ __func__, errno, ip6_str->str);
+ g_string_free (ip6_str, TRUE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static char *
+ip6_array_to_addr_prefix (GValueArray *values)
+{
+ GValue *prefix_val;
+ char *ret = NULL;
+ GString *ip6_str;
+ char buf[INET6_ADDRSTRLEN + 1];
+ gboolean is_unspec = FALSE;
+
+ /* address */
+ if (ip6_array_to_addr (values, 0, buf, sizeof (buf), NULL)) {
+ /* Enough space for the address, '/', and the prefix */
+ ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5);
+
+ /* prefix */
+ g_string_append (ip6_str, buf);
+ prefix_val = g_value_array_get_nth (values, 1);
+ g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val));
+
+ if (ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec)) {
+ if (!is_unspec)
+ g_string_append_printf (ip6_str, ",%s", buf);
+ }
+
+ ret = ip6_str->str;
+ g_string_free (ip6_str, FALSE);
+ }
+
+ return ret;
+}
+
+static void
+ip6_addr_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+ int i, j;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS));
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return;
+
+ for (i = 0, j = 1; i < array->len; i++) {
+ GValueArray *values = g_ptr_array_index (array, i);
+ char *key_name, *ip6_addr;
+
+ if (values->n_values != 3) {
+ g_warning ("%s: error writing IP6 address %d (address array length "
+ "%d is not 3)",
+ __func__, i, values->n_values);
+ continue;
+ }
+
+ ip6_addr = ip6_array_to_addr_prefix (values);
+ if (ip6_addr) {
+ /* Write it out */
+ key_name = g_strdup_printf ("%s%d", key, j++);
+ g_key_file_set_string (file, setting_name, key_name, ip6_addr);
+ g_free (key_name);
+ g_free (ip6_addr);
+ }
+ }
+}
+
+static void
+ip6_route_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+ char *list[3];
+ int i, j;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE));
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return;
+
+ for (i = 0, j = 1; i < array->len; i++) {
+ GValueArray *values = g_ptr_array_index (array, i);
+ char *key_name;
+ guint32 int_val;
+ char buf[INET6_ADDRSTRLEN + 1];
+ gboolean is_unspec = FALSE;
+
+ memset (list, 0, sizeof (list));
+
+ /* Address and prefix */
+ list[0] = ip6_array_to_addr_prefix (values);
+ if (!list[0])
+ continue;
+
+ /* Next Hop */
+ if (!ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec))
+ continue;
+ if (is_unspec)
+ continue;
+ list[1] = g_strdup (buf);
+
+ /* Metric */
+ value = g_value_array_get_nth (values, 3);
+ int_val = g_value_get_uint (value);
+ list[2] = g_strdup_printf ("%d", int_val);
+
+ /* Write it out */
+ key_name = g_strdup_printf ("%s%d", key, j++);
+ g_key_file_set_string_list (file, setting_name, key_name, (const char **) list, 3);
+ g_free (key_name);
+
+ g_free (list[0]);
+ g_free (list[1]);
+ g_free (list[2]);
+ }
+}
+
+
+static void
+mac_address_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GByteArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+ char *mac;
+ struct ether_addr tmp;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
+
+ array = (GByteArray *) g_value_get_boxed (value);
+ if (!array)
+ return;
+
+ if (array->len != ETH_ALEN) {
+ g_warning ("%s: invalid %s / %s MAC address length %d",
+ __func__, setting_name, key, array->len);
+ return;
+ }
+
+ memcpy (tmp.ether_addr_octet, array->data, ETH_ALEN);
+ mac = ether_ntoa (&tmp);
+ g_key_file_set_string (file, setting_name, key, mac);
+}
+
+static void
+write_hash_of_string (GKeyFile *file,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GHashTableIter iter;
+ const char *property = NULL, *data = NULL;
+ const char *group_name = nm_setting_get_name (setting);
+ gboolean vpn_secrets = FALSE;
+
+ /* Write VPN secrets out to a different group to keep them separate */
+ if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) {
+ group_name = VPN_SECRETS_GROUP;
+ vpn_secrets = TRUE;
+ }
+
+ g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value));
+ while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) {
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* Handle VPN secrets specially; they are nested in the property's hash;
+ * we don't want to write them if the secret is not saved or not required.
+ */
+ if (vpn_secrets && nm_setting_get_secret_flags (setting, property, &flags, NULL)) {
+ if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED))
+ continue;
+ }
+
+ g_key_file_set_string (file, group_name, property, data);
+ }
+}
+
+static void
+ssid_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GByteArray *array;
+ const char *setting_name = nm_setting_get_name (setting);
+ gboolean new_format = TRUE;
+ int i, *tmp_array;
+ char *ssid;
+
+ g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
+
+ array = (GByteArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return;
+
+ /* Check whether each byte is printable. If not, we have to use an
+ * integer list, otherwise we can just use a string.
+ */
+ for (i = 0; i < array->len; i++) {
+ char c = array->data[i] & 0xFF;
+ if (!isprint (c)) {
+ new_format = FALSE;
+ break;
+ }
+ }
+
+ if (new_format) {
+ ssid = g_malloc0 (array->len + 1);
+ memcpy (ssid, array->data, array->len);
+ g_key_file_set_string (file, setting_name, key, ssid);
+ g_free (ssid);
+ } else {
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = (int) array->data[i];
+ g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len);
+ g_free (tmp_array);
+ }
+}
+
+typedef struct ObjectType {
+ const char *key;
+ const char *suffix;
+ const char *privkey_pw_prop;
+ NMSetting8021xCKScheme (*scheme_func) (NMSetting8021x *setting);
+ NMSetting8021xCKFormat (*format_func) (NMSetting8021x *setting);
+ const char * (*path_func) (NMSetting8021x *setting);
+ const GByteArray * (*blob_func) (NMSetting8021x *setting);
+} ObjectType;
+
+static const ObjectType objtypes[10] = {
+ { NM_SETTING_802_1X_CA_CERT,
+ "ca-cert",
+ NULL,
+ nm_setting_802_1x_get_ca_cert_scheme,
+ NULL,
+ nm_setting_802_1x_get_ca_cert_path,
+ nm_setting_802_1x_get_ca_cert_blob },
+
+ { NM_SETTING_802_1X_PHASE2_CA_CERT,
+ "inner-ca-cert",
+ NULL,
+ nm_setting_802_1x_get_phase2_ca_cert_scheme,
+ NULL,
+ nm_setting_802_1x_get_phase2_ca_cert_path,
+ nm_setting_802_1x_get_phase2_ca_cert_blob },
+
+ { NM_SETTING_802_1X_CLIENT_CERT,
+ "client-cert",
+ NULL,
+ nm_setting_802_1x_get_client_cert_scheme,
+ NULL,
+ nm_setting_802_1x_get_client_cert_path,
+ nm_setting_802_1x_get_client_cert_blob },
+
+ { NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ "inner-client-cert",
+ NULL,
+ nm_setting_802_1x_get_phase2_client_cert_scheme,
+ NULL,
+ nm_setting_802_1x_get_phase2_client_cert_path,
+ nm_setting_802_1x_get_phase2_client_cert_blob },
+
+ { NM_SETTING_802_1X_PRIVATE_KEY,
+ "private-key",
+ NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
+ nm_setting_802_1x_get_private_key_scheme,
+ nm_setting_802_1x_get_private_key_format,
+ nm_setting_802_1x_get_private_key_path,
+ nm_setting_802_1x_get_private_key_blob },
+
+ { NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ "inner-private-key",
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
+ nm_setting_802_1x_get_phase2_private_key_scheme,
+ nm_setting_802_1x_get_phase2_private_key_format,
+ nm_setting_802_1x_get_phase2_private_key_path,
+ nm_setting_802_1x_get_phase2_private_key_blob },
+
+ { NULL },
+};
+
+static gboolean
+write_cert_key_file (const char *path,
+ const GByteArray *data,
+ GError **error)
+{
+ char *tmppath;
+ int fd = -1, written;
+ gboolean success = FALSE;
+
+ tmppath = g_malloc0 (strlen (path) + 10);
+ g_assert (tmppath);
+ memcpy (tmppath, path, strlen (path));
+ strcat (tmppath, ".XXXXXX");
+
+ errno = 0;
+ fd = mkstemp (tmppath);
+ if (fd < 0) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "Could not create temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ /* Only readable by root */
+ errno = 0;
+ if (fchmod (fd, S_IRUSR | S_IWUSR) != 0) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "Could not set permissions for temporary file '%s': %d",
+ path, errno);
+ goto out;
+ }
+
+ errno = 0;
+ written = write (fd, data->data, data->len);
+ if (written != data->len) {
+ close (fd);
+ unlink (tmppath);
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "Could not write temporary file for '%s': %d",
+ path, errno);
+ goto out;
+ }
+ close (fd);
+
+ /* Try to rename */
+ errno = 0;
+ if (rename (tmppath, path) == 0)
+ success = TRUE;
+ else {
+ unlink (tmppath);
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "Could not rename temporary file to '%s': %d",
+ path, errno);
+ }
+
+out:
+ g_free (tmppath);
+ return success;
+}
+
+static void
+cert_writer (GKeyFile *file,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ const char *setting_name = nm_setting_get_name (setting);
+ NMSetting8021xCKScheme scheme;
+ NMSetting8021xCKFormat format;
+ const char *path = NULL, *ext = "pem";
+ const ObjectType *objtype = NULL;
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (objtypes) && objtypes[i].key; i++) {
+ if (g_strcmp0 (objtypes[i].key, key) == 0) {
+ objtype = &objtypes[i];
+ break;
+ }
+ }
+ g_return_if_fail (objtype != NULL);
+
+ scheme = objtypes->scheme_func (NM_SETTING_802_1X (setting));
+ if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
+ path = objtype->path_func (NM_SETTING_802_1X (setting));
+ g_assert (path);
+ g_key_file_set_string (file, setting_name, key, path);
+ } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+ const GByteArray *blob;
+ gboolean success;
+ GError *error = NULL;
+ char *new_path;
+
+ blob = objtype->blob_func (NM_SETTING_802_1X (setting));
+ g_assert (blob);
+
+ if (objtype->format_func) {
+ /* Get the extension for a private key */
+ format = objtype->format_func (NM_SETTING_802_1X (setting));
+ if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
+ ext = "p12";
+ } else {
+ /* DER or PEM format certificate? */
+ if (blob->len > 2 && blob->data[0] == 0x30 && blob->data[1] == 0x82)
+ ext = "der";
+ }
+
+ /* Write the raw data out to the standard file so that we can use paths
+ * from now on instead of pushing around the certificate data.
+ */
+ new_path = g_strdup_printf ("%s/%s-%s.%s", keyfile_dir, uuid, objtype->suffix, ext);
+ g_assert (new_path);
+
+ success = write_cert_key_file (new_path, blob, &error);
+ if (success) {
+ /* Write the path value to the keyfile */
+ g_key_file_set_string (file, setting_name, key, new_path);
+ } else {
+ g_warning ("Failed to write certificate/key %s: %s", new_path, error->message);
+ g_error_free (error);
+ }
+ g_free (new_path);
+ } else
+ g_assert_not_reached ();
+}
+
+typedef struct {
+ const char *setting_name;
+ const char *key;
+ void (*writer) (GKeyFile *keyfile,
+ const char *keyfile_dir,
+ const char *uuid,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value);
+} KeyWriter;
+
+/* A table of keys that require further parsing/conversion because they are
+ * stored in a format that can't be automatically read using the key's type.
+ * i.e. IPv4 addresses, which are stored in NetworkManager as guint32, but are
+ * stored in keyfiles as strings, eg "10.1.1.2" or IPv6 addresses stored
+ * in struct in6_addr internally, but as string in keyfiles.
+ */
+static KeyWriter key_writers[] = {
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ADDRESSES,
+ ip4_addr_writer },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ADDRESSES,
+ ip6_addr_writer },
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_ROUTES,
+ ip4_route_writer },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_ROUTES,
+ ip6_route_writer },
+ { NM_SETTING_IP4_CONFIG_SETTING_NAME,
+ NM_SETTING_IP4_CONFIG_DNS,
+ ip4_dns_writer },
+ { NM_SETTING_IP6_CONFIG_SETTING_NAME,
+ NM_SETTING_IP6_CONFIG_DNS,
+ ip6_dns_writer },
+ { NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_MAC_ADDRESS,
+ mac_address_writer },
+ { NM_SETTING_WIRED_SETTING_NAME,
+ NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
+ mac_address_writer },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_MAC_ADDRESS,
+ mac_address_writer },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
+ mac_address_writer },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_BSSID,
+ mac_address_writer },
+ { NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_BLUETOOTH_BDADDR,
+ mac_address_writer },
+ { NM_SETTING_WIRELESS_SETTING_NAME,
+ NM_SETTING_WIRELESS_SSID,
+ ssid_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CA_CERT,
+ cert_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_CLIENT_CERT,
+ cert_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PRIVATE_KEY,
+ cert_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_CA_CERT,
+ cert_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
+ cert_writer },
+ { NM_SETTING_802_1X_SETTING_NAME,
+ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
+ cert_writer },
+ { NULL, NULL, NULL }
+};
+
+typedef struct {
+ GKeyFile *keyfile;
+ const char *keyfile_dir;
+ const char *uuid;
+} WriteInfo;
+
+static void
+write_setting_value (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ GParamFlags flag,
+ gpointer user_data)
+{
+ WriteInfo *info = user_data;
+ const char *setting_name;
+ GType type = G_VALUE_TYPE (value);
+ KeyWriter *writer = &key_writers[0];
+ GParamSpec *pspec;
+ NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
+
+ /* Setting name gets picked up from the keyfile's section name instead */
+ if (!strcmp (key, NM_SETTING_NAME))
+ return;
+
+ /* Don't write the NMSettingConnection object's 'read-only' property */
+ if ( NM_IS_SETTING_CONNECTION (setting)
+ && !strcmp (key, NM_SETTING_CONNECTION_READ_ONLY))
+ return;
+
+ setting_name = nm_setting_get_name (setting);
+
+ /* If the value is the default value, remove the item from the keyfile */
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), key);
+ if (pspec) {
+ if (g_param_value_defaults (pspec, (GValue *) value)) {
+ g_key_file_remove_key (info->keyfile, setting_name, key, NULL);
+ return;
+ }
+ }
+
+ /* Don't write secrets that are owned by user secret agents or aren't
+ * supposed to be saved.
+ */
+ if ( (pspec->flags & NM_SETTING_PARAM_SECRET)
+ && nm_setting_get_secret_flags (setting, key, &flags, NULL)
+ && (flags != NM_SETTING_SECRET_FLAG_NONE))
+ return;
+
+ /* Look through the list of handlers for non-standard format key values */
+ while (writer->setting_name) {
+ if (!strcmp (writer->setting_name, setting_name) && !strcmp (writer->key, key)) {
+ (*writer->writer) (info->keyfile, info->keyfile_dir, info->uuid, setting, key, value);
+ return;
+ }
+ writer++;
+ }
+
+ if (type == G_TYPE_STRING) {
+ const char *str;
+
+ str = g_value_get_string (value);
+ if (str)
+ g_key_file_set_string (info->keyfile, setting_name, key, str);
+ } else if (type == G_TYPE_UINT)
+ g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value));
+ else if (type == G_TYPE_INT)
+ g_key_file_set_integer (info->keyfile, setting_name, key, g_value_get_int (value));
+ else if (type == G_TYPE_UINT64) {
+ char *numstr;
+
+ numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value));
+ g_key_file_set_value (info->keyfile, setting_name, key, numstr);
+ g_free (numstr);
+ } else if (type == G_TYPE_BOOLEAN) {
+ g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value));
+ } else if (type == G_TYPE_CHAR) {
+ g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_char (value));
+ } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
+ GByteArray *array;
+
+ array = (GByteArray *) g_value_get_boxed (value);
+ if (array && array->len > 0) {
+ int *tmp_array;
+ int i;
+
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = (int) array->data[i];
+
+ g_key_file_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len);
+ g_free (tmp_array);
+ }
+ } else if (type == DBUS_TYPE_G_LIST_OF_STRING) {
+ GSList *list;
+ GSList *iter;
+
+ list = (GSList *) g_value_get_boxed (value);
+ if (list) {
+ char **array;
+ int i = 0;
+
+ array = g_new (char *, g_slist_length (list));
+ for (iter = list; iter; iter = iter->next)
+ array[i++] = iter->data;
+
+ g_key_file_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i);
+ g_free (array);
+ }
+ } else if (type == DBUS_TYPE_G_MAP_OF_STRING) {
+ write_hash_of_string (info->keyfile, setting, key, value);
+ } else if (type == DBUS_TYPE_G_UINT_ARRAY) {
+ if (!write_array_of_uint (info->keyfile, setting, key, value)) {
+ g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
+ setting_name, key, g_type_name (type));
+ }
+ } else {
+ g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
+ setting_name, key, g_type_name (type));
+ }
+}
+
+static char *
+_writer_id_to_filename (const char *id)
+{
+ char *filename, *f;
+ const char *i = id;
+
+ f = filename = g_malloc0 (strlen (id) + 1);
+
+ /* Convert '/' to '*' */
+ while (*i) {
+ if (*i == '/')
+ *f++ = '*';
+ else
+ *f++ = *i;
+ i++;
+ }
+
+ return filename;
+}
+
+static gboolean
+_internal_write_connection (NMConnection *connection,
+ const char *keyfile_dir,
+ uid_t owner_uid,
+ pid_t owner_grp,
+ const char *existing_path,
+ char **out_path,
+ GError **error)
+{
+ GKeyFile *key_file;
+ char *data;
+ gsize len;
+ gboolean success = FALSE;
+ char *filename = NULL, *path;
+ const char *id;
+ WriteInfo info;
+
+ if (out_path)
+ g_return_val_if_fail (*out_path == NULL, FALSE);
+
+ id = nm_connection_get_id (connection);
+ if (!id) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "%s.%d: connection had no ID", __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ info.keyfile = key_file = g_key_file_new ();
+ info.keyfile_dir = keyfile_dir;
+ info.uuid = nm_connection_get_uuid (connection);
+ g_assert (info.uuid);
+ nm_connection_for_each_setting_value (connection, write_setting_value, &info);
+ data = g_key_file_to_data (key_file, &len, error);
+ if (!data)
+ goto out;
+
+ filename = _writer_id_to_filename (id);
+ path = g_build_filename (keyfile_dir, filename, NULL);
+
+ /* If a file with this path already exists (but isn't the existing path
+ * of the connection) then we need another name. Multiple connections
+ * can have the same ID (ie if two connections with the same ID are visible
+ * to different users) but of course can't have the same path. Yeah,
+ * there's a race here, but there's not a lot we can do about it, and
+ * we shouldn't get more than one connection with the same UUID either.
+ */
+ if (g_file_test (path, G_FILE_TEST_EXISTS) && (g_strcmp0 (path, existing_path) != 0)) {
+ /* A keyfile with this connection's ID already exists. Pick another name. */
+ g_free (path);
+
+ path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection));
+ if (g_file_test (path, G_FILE_TEST_EXISTS)) {
+ /* Hmm, this is odd. Give up. */
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "%s.%d: could not find suitable keyfile file name (%s already used)",
+ __FILE__, __LINE__, path);
+ g_free (path);
+ goto out;
+ }
+ }
+
+ g_file_set_contents (path, data, len, error);
+ if (chown (path, owner_uid, owner_grp) < 0) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "%s.%d: error chowning '%s': %d", __FILE__, __LINE__,
+ path, errno);
+ unlink (path);
+ } else {
+ if (chmod (path, S_IRUSR | S_IWUSR) < 0) {
+ g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+ "%s.%d: error setting permissions on '%s': %d", __FILE__,
+ __LINE__, path, errno);
+ unlink (path);
+ } else {
+ if (out_path && g_strcmp0 (existing_path, path)) {
+ *out_path = path; /* pass path out to caller */
+ path = NULL;
+ }
+ success = TRUE;
+ }
+ }
+ g_free (path);
+
+out:
+ g_free (filename);
+ g_free (data);
+ g_key_file_free (key_file);
+ return success;
+}
+
+gboolean
+nm_keyfile_plugin_write_connection (NMConnection *connection,
+ const char *existing_path,
+ char **out_path,
+ GError **error)
+{
+ return _internal_write_connection (connection,
+ KEYFILE_DIR,
+ 0, 0,
+ existing_path,
+ out_path,
+ error);
+}
+
+gboolean
+nm_keyfile_plugin_write_test_connection (NMConnection *connection,
+ const char *keyfile_dir,
+ uid_t owner_uid,
+ pid_t owner_grp,
+ char **out_path,
+ GError **error)
+{
+ return _internal_write_connection (connection,
+ keyfile_dir,
+ owner_uid, owner_grp,
+ NULL,
+ out_path,
+ error);
+}
+
diff --git a/src/settings/plugins/keyfile/writer.h b/src/settings/plugins/keyfile/writer.h
new file mode 100644
index 000000000..a602f2f4a
--- /dev/null
+++ b/src/settings/plugins/keyfile/writer.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service - keyfile plugin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
+ */
+
+#ifndef _KEYFILE_PLUGIN_WRITER_H
+#define _KEYFILE_PLUGIN_WRITER_H
+
+#include <sys/types.h>
+#include <glib.h>
+#include <nm-connection.h>
+
+gboolean nm_keyfile_plugin_write_connection (NMConnection *connection,
+ const char *existing_path,
+ char **out_path,
+ GError **error);
+
+gboolean nm_keyfile_plugin_write_test_connection (NMConnection *connection,
+ const char *keyfile_dir,
+ uid_t owner_uid,
+ pid_t owner_grp,
+ char **out_path,
+ GError **error);
+
+#endif /* _KEYFILE_PLUGIN_WRITER_H */
diff --git a/src/settings/tests/Makefile.am b/src/settings/tests/Makefile.am
new file mode 100644
index 000000000..4a4513986
--- /dev/null
+++ b/src/settings/tests/Makefile.am
@@ -0,0 +1,32 @@
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/src/settings
+
+noinst_PROGRAMS = \
+ test-wired-defname
+
+####### wired defname test #######
+
+test_wired_defname_SOURCES = \
+ test-wired-defname.c
+
+test_wired_defname_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS)
+
+test_wired_defname_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/settings/libtest-settings-utils.la \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS)
+
+###########################################
+
+if WITH_TESTS
+
+check-local: test-wired-defname
+ $(abs_builddir)/test-wired-defname
+
+endif
+
diff --git a/src/settings/tests/Makefile.in b/src/settings/tests/Makefile.in
new file mode 100644
index 000000000..70e6b17e9
--- /dev/null
+++ b/src/settings/tests/Makefile.in
@@ -0,0 +1,632 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = test-wired-defname$(EXEEXT)
+subdir = src/settings/tests
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_wired_defname_OBJECTS = \
+ test_wired_defname-test-wired-defname.$(OBJEXT)
+test_wired_defname_OBJECTS = $(am_test_wired_defname_OBJECTS)
+am__DEPENDENCIES_1 =
+test_wired_defname_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/settings/libtest-settings-utils.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(test_wired_defname_SOURCES)
+DIST_SOURCES = $(test_wired_defname_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_SYS_DIR = @DBUS_SYS_DIR@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DHCLIENT_PATH = @DHCLIENT_PATH@
+DHCLIENT_VERSION = @DHCLIENT_VERSION@
+DHCPCD_PATH = @DHCPCD_PATH@
+DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
+KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBDL = @LIBDL@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBM = @LIBM@
+LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_LIBS = @LIBNL_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
+NM_MICRO_VERSION = @NM_MICRO_VERSION@
+NM_MINOR_VERSION = @NM_MINOR_VERSION@
+NM_VERSION = @NM_VERSION@
+NSS_CFLAGS = @NSS_CFLAGS@
+NSS_LIBS = @NSS_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKGCONFIG_PATH = @PKGCONFIG_PATH@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
+RANLIB = @RANLIB@
+RESOLVCONF_PATH = @RESOLVCONF_PATH@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
+UDEV_BASE_DIR = @UDEV_BASE_DIR@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -I$(top_srcdir)/src/settings
+
+
+####### wired defname test #######
+test_wired_defname_SOURCES = \
+ test-wired-defname.c
+
+test_wired_defname_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS)
+
+test_wired_defname_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/settings/libtest-settings-utils.la \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/settings/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/settings/tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+test-wired-defname$(EXEEXT): $(test_wired_defname_OBJECTS) $(test_wired_defname_DEPENDENCIES)
+ @rm -f test-wired-defname$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wired_defname_OBJECTS) $(test_wired_defname_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_wired_defname-test-wired-defname.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+test_wired_defname-test-wired-defname.o: test-wired-defname.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wired_defname-test-wired-defname.o -MD -MP -MF $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o test_wired_defname-test-wired-defname.o `test -f 'test-wired-defname.c' || echo '$(srcdir)/'`test-wired-defname.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo $(DEPDIR)/test_wired_defname-test-wired-defname.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wired-defname.c' object='test_wired_defname-test-wired-defname.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wired_defname-test-wired-defname.o `test -f 'test-wired-defname.c' || echo '$(srcdir)/'`test-wired-defname.c
+
+test_wired_defname-test-wired-defname.obj: test-wired-defname.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wired_defname-test-wired-defname.obj -MD -MP -MF $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo -c -o test_wired_defname-test-wired-defname.obj `if test -f 'test-wired-defname.c'; then $(CYGPATH_W) 'test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/test-wired-defname.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wired_defname-test-wired-defname.Tpo $(DEPDIR)/test_wired_defname-test-wired-defname.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wired-defname.c' object='test_wired_defname-test-wired-defname.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wired_defname_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wired_defname-test-wired-defname.obj `if test -f 'test-wired-defname.c'; then $(CYGPATH_W) 'test-wired-defname.c'; else $(CYGPATH_W) '$(srcdir)/test-wired-defname.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+@WITH_TESTS_FALSE@check-local:
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+###########################################
+
+@WITH_TESTS_TRUE@check-local: test-wired-defname
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-wired-defname
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/settings/tests/test-wired-defname.c b/src/settings/tests/test-wired-defname.c
new file mode 100644
index 000000000..f6627fa9c
--- /dev/null
+++ b/src/settings/tests/test-wired-defname.c
@@ -0,0 +1,147 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <nm-connection.h>
+#include <nm-setting-connection.h>
+#include "nm-settings-utils.h"
+
+static NMConnection *
+_new_connection (const char *id)
+{
+ NMConnection *a;
+ NMSetting *setting;
+
+ a = nm_connection_new ();
+ setting = nm_setting_connection_new ();
+ g_object_set (setting, NM_SETTING_CONNECTION_ID, id, NULL);
+ nm_connection_add_setting (a, setting);
+ return a;
+}
+
+/*******************************************/
+
+static void
+test_defname_no_connections (void)
+{
+ GHashTable *hash;
+ char *name;
+
+ hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ name = nm_settings_utils_get_default_wired_name (hash);
+ g_assert_cmpstr (name, ==, "Wired connection 1");
+
+ g_hash_table_destroy (hash);
+}
+
+/*******************************************/
+
+static void
+test_defname_no_conflict (void)
+{
+ GHashTable *hash;
+ char *name;
+
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref);
+
+ g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf"));
+ g_hash_table_insert (hash, "b", _new_connection ("work wifi"));
+ g_hash_table_insert (hash, "c", _new_connection ("random gsm connection"));
+
+ name = nm_settings_utils_get_default_wired_name (hash);
+ g_assert_cmpstr (name, ==, "Wired connection 1");
+
+ g_hash_table_destroy (hash);
+}
+
+/*******************************************/
+
+static void
+test_defname_conflict (void)
+{
+ GHashTable *hash;
+ char *name;
+
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref);
+
+ g_hash_table_insert (hash, "a", _new_connection ("asdfasdfasdfadf"));
+ g_hash_table_insert (hash, "b", _new_connection ("Wired connection 1"));
+ g_hash_table_insert (hash, "c", _new_connection ("random gsm connection"));
+
+ name = nm_settings_utils_get_default_wired_name (hash);
+ g_assert_cmpstr (name, ==, "Wired connection 2");
+
+ g_hash_table_destroy (hash);
+}
+
+/*******************************************/
+
+static void
+test_defname_multiple_conflicts (void)
+{
+ GHashTable *hash;
+ char *name;
+
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_object_unref);
+
+ g_hash_table_insert (hash, "a", _new_connection ("random gsm connection"));
+ g_hash_table_insert (hash, "b", _new_connection ("home wifi"));
+ g_hash_table_insert (hash, "c", _new_connection ("Wired connection 1"));
+ g_hash_table_insert (hash, "d", _new_connection ("Wired connection 2"));
+ g_hash_table_insert (hash, "e", _new_connection ("Wired connection 3"));
+ g_hash_table_insert (hash, "f", _new_connection ("work wifi"));
+ g_hash_table_insert (hash, "g", _new_connection ("a vpn"));
+
+ name = nm_settings_utils_get_default_wired_name (hash);
+ g_assert_cmpstr (name, ==, "Wired connection 4");
+
+ g_hash_table_destroy (hash);
+}
+
+/*******************************************/
+
+#if GLIB_CHECK_VERSION(2,25,12)
+typedef GTestFixtureFunc TCFunc;
+#else
+typedef void (*TCFunc)(void);
+#endif
+
+#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL)
+
+int main (int argc, char **argv)
+{
+ GTestSuite *suite;
+
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ suite = g_test_get_root ();
+
+ g_test_suite_add (suite, TESTCASE (test_defname_no_connections, NULL));
+ g_test_suite_add (suite, TESTCASE (test_defname_no_conflict, NULL));
+ g_test_suite_add (suite, TESTCASE (test_defname_conflict, NULL));
+ g_test_suite_add (suite, TESTCASE (test_defname_multiple_conflicts, NULL));
+
+ return g_test_run ();
+}
+
diff --git a/src/supplicant-manager/Makefile.in b/src/supplicant-manager/Makefile.in
index 08ffaecec..cfee45102 100644
--- a/src/supplicant-manager/Makefile.in
+++ b/src/supplicant-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/supplicant-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -66,7 +71,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -135,7 +140,6 @@ am__relativize = \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -144,8 +148,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -162,6 +164,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -170,6 +173,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -178,8 +182,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -194,13 +198,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -208,6 +222,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -216,13 +232,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -248,12 +266,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -268,10 +283,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index a65a458f5..e9e58f39f 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2006 - 2008 Red Hat, Inc.
+ * Copyright (C) 2006 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -34,73 +34,48 @@
#include "nm-glib-compat.h"
#define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface"
-#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID"
+#define WPAS_DBUS_IFACE_BSS WPAS_DBUS_INTERFACE ".BSS"
#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network"
#define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface"
-#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".ExistsError"
-
+#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists"
G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
+static void wpas_iface_properties_changed (DBusGProxy *proxy,
+ GHashTable *props,
+ gpointer user_data);
+
+static void wpas_iface_scan_done (DBusGProxy *proxy,
+ gboolean success,
+ gpointer user_data);
#define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_INTERFACE, \
NMSupplicantInterfacePrivate))
-static void nm_supplicant_interface_set_property (GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-
-static void nm_supplicant_interface_get_property (GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-
-static void nm_supplicant_interface_start (NMSupplicantInterface *self);
-
-static void nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface *self,
- gboolean get_only);
-
-static void nm_supplicant_interface_smgr_state_changed (NMSupplicantManager *smgr,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data);
-
-static void nm_supplicant_interface_set_state (NMSupplicantInterface *self,
- guint32 new_state);
-
-
/* Signals */
enum {
STATE, /* change in the interface's state */
REMOVED, /* interface was removed by the supplicant */
- SCANNED_AP, /* interface saw a new access point from a scan */
- SCAN_REQ_RESULT, /* result of a wireless scan request */
- SCAN_RESULTS, /* scan results returned from supplicant */
- CONNECTION_STATE, /* link state of the device's connection */
+ NEW_BSS, /* interface saw a new access point from a scan */
+ SCAN_DONE, /* wifi scan is complete */
CONNECTION_ERROR, /* an error occurred during a connection request */
LAST_SIGNAL
};
-static guint nm_supplicant_interface_signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL] = { 0 };
/* Properties */
enum {
PROP_0 = 0,
- PROP_SUPPLICANT_MANAGER,
- PROP_DEVICE,
- PROP_STATE,
- PROP_CONNECTION_STATE,
PROP_SCANNING,
LAST_PROP
};
-typedef struct
-{
+typedef struct {
NMSupplicantManager * smgr;
- gulong smgr_state_sig_handler;
+ gulong smgr_avail_id;
NMDBusManager * dbus_mgr;
char * dev;
gboolean is_wireless;
@@ -110,18 +85,19 @@ typedef struct
NMCallStore * assoc_pcalls;
NMCallStore * other_pcalls;
- guint32 con_state;
gboolean scanning;
+ DBusGProxy * wpas_proxy;
DBusGProxy * iface_proxy;
- DBusGProxy * net_proxy;
+ DBusGProxy * props_proxy;
+ char * net_path;
+ guint32 blobs_left;
- guint scan_results_timeout;
guint32 last_scan;
NMSupplicantConfig * cfg;
- gboolean dispose_has_run;
+ gboolean disposed;
} NMSupplicantInterfacePrivate;
static gboolean
@@ -203,827 +179,488 @@ nm_supplicant_info_destroy (gpointer user_data)
}
}
-
-NMSupplicantInterface *
-nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless)
-{
- NMSupplicantInterface * iface;
-
- g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL);
- g_return_val_if_fail (ifname != NULL, NULL);
-
- iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
- "supplicant-manager", smgr,
- "device", ifname,
- NULL);
- if (iface) {
- NM_SUPPLICANT_INTERFACE_GET_PRIVATE (iface)->is_wireless = is_wireless;
- nm_supplicant_interface_start (iface);
- }
-
- return iface;
-}
-
static void
-nm_supplicant_interface_init (NMSupplicantInterface * self)
+emit_error_helper (NMSupplicantInterface *self,
+ GError *err)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
- priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
- priv->assoc_pcalls = nm_call_store_new ();
- priv->other_pcalls = nm_call_store_new ();
+ const char *name = NULL;
- priv->dispose_has_run = FALSE;
+ if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION)
+ name = dbus_g_error_get_name (err);
- priv->dbus_mgr = nm_dbus_manager_get ();
+ g_signal_emit (self, signals[CONNECTION_ERROR], 0, name, err->message);
}
-
static void
-nm_supplicant_interface_set_property (GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec)
+bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
- gulong id;
-
- switch (prop_id) {
- case PROP_SUPPLICANT_MANAGER:
- priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value));
- g_object_ref (G_OBJECT (priv->smgr));
-
- id = g_signal_connect (priv->smgr,
- "state",
- G_CALLBACK (nm_supplicant_interface_smgr_state_changed),
- object);
- priv->smgr_state_sig_handler = id;
- break;
- case PROP_DEVICE:
- /* Construct-only */
- priv->dev = g_strdup (g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ GError *error = NULL;
+ GHashTable *props = NULL;
+
+ if (dbus_g_proxy_end_call (proxy, call_id, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_signal_emit (info->interface, signals[NEW_BSS], 0, props);
+ g_hash_table_destroy (props);
+ } else {
+ if (!strstr (error->message, "The BSSID requested was invalid")) {
+ nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.",
+ error->message);
+ }
+ g_error_free (error);
}
}
static void
-nm_supplicant_interface_get_property (GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec)
+request_bss_properties (NMSupplicantInterface *self,
+ GPtrArray *paths)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ int i;
- switch (prop_id) {
- case PROP_SUPPLICANT_MANAGER:
- g_value_set_object (value, G_OBJECT (priv->smgr));
- break;
- case PROP_DEVICE:
- g_value_set_string (value, priv->dev);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_CONNECTION_STATE:
- g_value_set_uint (value, priv->con_state);
- break;
- case PROP_SCANNING:
- g_value_set_boolean (value, priv->scanning);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ /* Fire off a "properties" call for each returned BSSID */
+ for (i = 0; i < paths->len; i++) {
+ NMSupplicantInfo *info;
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
+
+ proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ g_ptr_array_index (paths, i),
+ DBUS_INTERFACE_PROPERTIES);
+ info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (proxy, "GetAll",
+ bssid_properties_cb,
+ info,
+ nm_supplicant_info_destroy,
+ G_TYPE_STRING, WPAS_DBUS_IFACE_BSS,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (info, call);
+ g_object_unref (proxy);
}
}
static void
-try_remove_iface (DBusGConnection *g_connection,
- const char *path)
+wpas_iface_bss_added (DBusGProxy *proxy,
+ const char *object_path,
+ GHashTable *props,
+ gpointer user_data)
{
- DBusGProxy *proxy;
-
- g_return_if_fail (g_connection != NULL);
- g_return_if_fail (path != NULL);
-
- proxy = dbus_g_proxy_new_for_name (g_connection,
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- WPAS_DBUS_INTERFACE);
- if (!proxy)
- return;
-
- dbus_g_proxy_call_no_reply (proxy, "removeInterface",
- DBUS_TYPE_G_OBJECT_PATH, path,
- G_TYPE_INVALID);
- g_object_unref (proxy);
+ g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[NEW_BSS], 0, props);
}
-static void
-nm_supplicant_interface_dispose (GObject *object)
+static int
+wpas_state_string_to_enum (const char *str_state)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
- guint32 sm_state;
-
- if (priv->dispose_has_run) {
- G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
- return;
- }
-
- priv->dispose_has_run = TRUE;
-
- /* Ask wpa_supplicant to remove this interface */
- sm_state = nm_supplicant_manager_get_state (priv->smgr);
- if (sm_state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
- if (priv->object_path) {
- try_remove_iface (nm_dbus_manager_get_connection (priv->dbus_mgr),
- priv->object_path);
- }
- }
-
- if (priv->iface_proxy)
- g_object_unref (priv->iface_proxy);
-
- if (priv->net_proxy)
- g_object_unref (priv->net_proxy);
-
- if (priv->scan_results_timeout)
- g_source_remove (priv->scan_results_timeout);
-
- if (priv->smgr) {
- g_signal_handler_disconnect (priv->smgr,
- priv->smgr_state_sig_handler);
- g_object_unref (priv->smgr);
- }
-
- g_free (priv->dev);
-
- /* Cancel pending calls before unrefing the dbus manager */
- cancel_all_callbacks (priv->other_pcalls);
- nm_call_store_destroy (priv->other_pcalls);
-
- cancel_all_callbacks (priv->assoc_pcalls);
- nm_call_store_destroy (priv->assoc_pcalls);
-
- if (priv->dbus_mgr)
- g_object_unref (priv->dbus_mgr);
-
- if (priv->cfg)
- g_object_unref (priv->cfg);
-
- g_free (priv->object_path);
-
- /* Chain up to the parent class */
- G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
+ if (!strcmp (str_state, "disconnected"))
+ return NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED;
+ else if (!strcmp (str_state, "inactive"))
+ return NM_SUPPLICANT_INTERFACE_STATE_INACTIVE;
+ else if (!strcmp (str_state, "scanning"))
+ return NM_SUPPLICANT_INTERFACE_STATE_SCANNING;
+ else if (!strcmp (str_state, "authenticating"))
+ return NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING;
+ else if (!strcmp (str_state, "associating"))
+ return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING;
+ else if (!strcmp (str_state, "associated"))
+ return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED;
+ else if (!strcmp (str_state, "4way_handshake"))
+ return NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE;
+ else if (!strcmp (str_state, "group_handshake"))
+ return NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE;
+ else if (!strcmp (str_state, "completed"))
+ return NM_SUPPLICANT_INTERFACE_STATE_COMPLETED;
+
+ nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant state '%s'", str_state);
+ return -1;
}
static void
-nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
+set_state (NMSupplicantInterface *self, guint32 new_state)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ guint32 old_state = priv->state;
- object_class->dispose = nm_supplicant_interface_dispose;
- object_class->set_property = nm_supplicant_interface_set_property;
- object_class->get_property = nm_supplicant_interface_get_property;
+ g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
- /* Properties */
- g_object_class_install_property (object_class,
- PROP_SUPPLICANT_MANAGER,
- g_param_spec_object ("supplicant-manager",
- "Supplicant Manager",
- "Supplicant manager to which this interface belongs",
- NM_TYPE_SUPPLICANT_MANAGER,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_DEVICE,
- g_param_spec_string ("device",
- "Device",
- "Device which this interface represents to the supplicant",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class,
- PROP_STATE,
- g_param_spec_uint ("state",
- "State",
- "State of the supplicant interface; INIT, READY, or DOWN",
- NM_SUPPLICANT_INTERFACE_STATE_INIT,
- NM_SUPPLICANT_INTERFACE_STATE_LAST - 1,
- NM_SUPPLICANT_INTERFACE_STATE_INIT,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class,
- PROP_SCANNING,
- g_param_spec_boolean ("scanning",
- "Scanning",
- "Scanning",
- FALSE,
- G_PARAM_READABLE));
+ if (new_state == priv->state)
+ return;
- /* Signals */
- nm_supplicant_interface_signals[STATE] =
- g_signal_new ("state",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state),
- NULL, NULL,
- _nm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+ /* DOWN is a terminal state */
+ g_return_if_fail (priv->state != NM_SUPPLICANT_INTERFACE_STATE_DOWN);
- nm_supplicant_interface_signals[REMOVED] =
- g_signal_new ("removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ /* Cannot regress to READY, STARTING, or INIT from higher states */
+ if (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY)
+ g_return_if_fail (new_state > NM_SUPPLICANT_INTERFACE_STATE_READY);
- nm_supplicant_interface_signals[SCANNED_AP] =
- g_signal_new ("scanned-ap",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scanned_ap),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- nm_supplicant_interface_signals[SCAN_REQ_RESULT] =
- g_signal_new ("scan-req-result",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_req_result),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
- G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+ if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
+ /* Cancel all pending calls when going down */
+ cancel_all_callbacks (priv->other_pcalls);
+ cancel_all_callbacks (priv->assoc_pcalls);
- nm_supplicant_interface_signals[SCAN_RESULTS] =
- g_signal_new ("scan-results",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_results),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
+ /* Disconnect supplicant manager state listeners since we're done */
+ if (priv->smgr_avail_id) {
+ g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id);
+ priv->smgr_avail_id = 0;
+ }
- nm_supplicant_interface_signals[CONNECTION_STATE] =
- g_signal_new ("connection-state",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_state),
- NULL, NULL,
- _nm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+ if (priv->iface_proxy) {
+ dbus_g_proxy_disconnect_signal (priv->iface_proxy,
+ "PropertiesChanged",
+ G_CALLBACK (wpas_iface_properties_changed),
+ self);
+ dbus_g_proxy_disconnect_signal (priv->iface_proxy,
+ "ScanDone",
+ G_CALLBACK (wpas_iface_scan_done),
+ self);
+ dbus_g_proxy_disconnect_signal (priv->iface_proxy,
+ "BSSAdded",
+ G_CALLBACK (wpas_iface_bss_added),
+ self);
+ }
+ }
- nm_supplicant_interface_signals[CONNECTION_ERROR] =
- g_signal_new ("connection-error",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error),
- NULL, NULL,
- _nm_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
+ priv->state = new_state;
+ g_signal_emit (self, signals[STATE], 0, priv->state, old_state);
}
static void
-emit_error_helper (NMSupplicantInterface *self,
- GError *err)
+set_state_from_string (NMSupplicantInterface *self, const char *new_state)
{
- const char *name = NULL;
+ int state;
- if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION)
- name = dbus_g_error_get_name (err);
-
- g_signal_emit (self,
- nm_supplicant_interface_signals[CONNECTION_ERROR],
- 0,
- name,
- err->message);
+ state = wpas_state_string_to_enum (new_state);
+ g_warn_if_fail (state > 0);
+ if (state > 0)
+ set_state (self, (guint32) state);
}
static void
-bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+set_scanning (NMSupplicantInterface *self, gboolean new_scanning)
{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- GError *err = NULL;
- GHashTable *hash = NULL;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ GTimeVal cur_time;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_MAP_OF_VARIANT, &hash,
- G_TYPE_INVALID)) {
- if (!strstr (err->message, "The BSSID requested was invalid")) {
- nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.",
- err->message);
+ if (priv->scanning != new_scanning) {
+ priv->scanning = new_scanning;
+
+ /* Cache time of last scan completion */
+ if (priv->scanning == FALSE) {
+ g_get_current_time (&cur_time);
+ priv->last_scan = cur_time.tv_sec;
}
- g_error_free (err);
- } else {
- g_signal_emit (info->interface,
- nm_supplicant_interface_signals[SCANNED_AP],
- 0,
- hash);
- g_hash_table_destroy (hash);
+ g_object_notify (G_OBJECT (self), "scanning");
}
}
-static void
-request_bssid_properties (NMSupplicantInterface * self,
- const char * op)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- NMSupplicantInfo *info;
- DBusGProxy *proxy;
- DBusGProxyCall *call;
-
- proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- op,
- WPAS_DBUS_IFACE_BSSID);
- info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (proxy, "properties",
- bssid_properties_cb,
- info,
- nm_supplicant_info_destroy,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
- g_object_unref (proxy);
-}
-
-static void
-scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+gboolean
+nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
{
- GError *err = NULL;
- GPtrArray *array = NULL;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &array,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_SUPPLICANT, "could not get scan results: %s.", err->message);
- g_error_free (err);
- } else {
- int i;
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
-
- /* Notify listeners of the result of the scan */
- g_signal_emit (info->interface,
- nm_supplicant_interface_signals[SCAN_RESULTS],
- 0,
- array->len);
-
- /* Fire off a "properties" call for each returned BSSID */
- for (i = 0; i < array->len; i++) {
- char *op = g_ptr_array_index (array, i);
+ NMSupplicantInterfacePrivate *priv;
- request_bssid_properties (info->interface, op);
- g_free (op);
- }
+ g_return_val_if_fail (self != NULL, FALSE);
- g_ptr_array_free (array, TRUE);
- }
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ if (priv->scanning)
+ return TRUE;
+ if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
+ return TRUE;
+ return FALSE;
}
-static gboolean
-request_scan_results (gpointer user_data)
+static void
+wpas_iface_scan_done (DBusGProxy *proxy,
+ gboolean success,
+ gpointer user_data)
{
NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- NMSupplicantInfo *info;
- DBusGProxyCall *call;
GTimeVal cur_time;
- priv->scan_results_timeout = 0;
-
- g_return_val_if_fail (priv->iface_proxy != NULL, FALSE);
-
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanResults",
- scan_results_cb,
- info,
- nm_supplicant_info_destroy,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
-
+ /* Cache last scan completed time */
g_get_current_time (&cur_time);
priv->last_scan = cur_time.tv_sec;
- return FALSE;
+
+ g_signal_emit (self, signals[SCAN_DONE], 0, success);
}
static void
-wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data)
+wpas_iface_properties_changed (DBusGProxy *proxy,
+ GHashTable *props,
+ gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
- GTimeVal cur_time;
-
- /* Only query scan results if a query is not queued */
- if (priv->scan_results_timeout)
- return;
+ NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
+ GValue *value;
- g_get_current_time (&cur_time);
+ value = g_hash_table_lookup (props, "Scanning");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value))
+ set_scanning (self, g_value_get_boolean (value));
- /* Only fetch scan results every 4s max, but initially do it right away */
- if (priv->last_scan + 4 < cur_time.tv_sec) {
- priv->scan_results_timeout = g_idle_add (request_scan_results,
- user_data);
- } else {
- priv->scan_results_timeout =
- g_timeout_add_seconds ((4 - (cur_time.tv_sec - priv->last_scan)),
- request_scan_results, user_data);
- }
-}
+ value = g_hash_table_lookup (props, "State");
+ if (value && G_VALUE_HOLDS_STRING (value))
+ set_state_from_string (self, g_value_get_string (value));
-static guint32
-wpas_state_string_to_enum (const char * str_state)
-{
- guint32 enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
-
- if (!strcmp (str_state, "DISCONNECTED"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
- else if (!strcmp (str_state, "INACTIVE"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE;
- else if (!strcmp (str_state, "SCANNING"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING;
- else if (!strcmp (str_state, "ASSOCIATING"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING;
- else if (!strcmp (str_state, "ASSOCIATED"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED;
- else if (!strcmp (str_state, "4WAY_HANDSHAKE"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE;
- else if (!strcmp (str_state, "GROUP_HANDSHAKE"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE;
- else if (!strcmp (str_state, "COMPLETED"))
- enum_state = NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED;
-
- return enum_state;
+ value = g_hash_table_lookup (props, "BSSs");
+ if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH))
+ request_bss_properties (self, g_value_get_boxed (value));
}
static void
-wpas_iface_handle_state_change (DBusGProxy *proxy,
- const char *str_new_state,
- const char *str_old_state,
- gpointer user_data)
+iface_get_props_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
- guint32 old_state, enum_new_state;
-
- enum_new_state = wpas_state_string_to_enum (str_new_state);
- old_state = priv->con_state;
- priv->con_state = enum_new_state;
- if (priv->con_state != old_state) {
- g_signal_emit (user_data,
- nm_supplicant_interface_signals[CONNECTION_STATE],
- 0,
- priv->con_state,
- old_state);
- }
-}
-
-
-static void
-iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- GError *err = NULL;
- char *state_str = NULL;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- G_TYPE_STRING, &state_str,
- G_TYPE_INVALID)) {
- nm_log_warn (LOGD_SUPPLICANT, "could not get interface state: %s.", err->message);
- g_error_free (err);
+ NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ GHashTable *props = NULL;
+ GError *error = NULL;
+
+ if (dbus_g_proxy_end_call (proxy, call_id, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ wpas_iface_properties_changed (NULL, props, info->interface);
+ g_hash_table_destroy (props);
} else {
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
-
- priv->con_state = wpas_state_string_to_enum (state_str);
- g_free (state_str);
- nm_supplicant_interface_set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_READY);
+ nm_log_warn (LOGD_SUPPLICANT, "could not get interface properties: %s.",
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
}
}
static void
-wpas_iface_get_state (NMSupplicantInterface *self)
+wpas_iface_get_props (NMSupplicantInterface *self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
NMSupplicantInfo *info;
DBusGProxyCall *call;
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "state",
- iface_state_cb,
+ info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
+ iface_get_props_cb,
info,
nm_supplicant_info_destroy,
+ G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
}
static void
-iface_scanning_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+interface_add_done (NMSupplicantInterface *self, char *path)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
+
+ priv->object_path = path;
+
+ priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ path,
+ WPAS_DBUS_IFACE_INTERFACE);
+
+ dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->iface_proxy, "PropertiesChanged",
+ DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "PropertiesChanged",
+ G_CALLBACK (wpas_iface_properties_changed),
+ self, NULL);
+
+ dbus_g_proxy_add_signal (priv->iface_proxy, "ScanDone", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanDone",
+ G_CALLBACK (wpas_iface_scan_done),
+ self,
+ NULL);
+
+ dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->iface_proxy, "BSSAdded", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSAdded",
+ G_CALLBACK (wpas_iface_bss_added),
+ self,
+ NULL);
+
+ priv->props_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+ WPAS_DBUS_SERVICE,
+ path,
+ DBUS_INTERFACE_PROPERTIES);
+ /* Get initial properties */
+ wpas_iface_get_props (self);
+
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY);
+}
+
+static void
+interface_get_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call_id,
+ gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- gboolean scanning = FALSE;
+ GError *error = NULL;
+ char *path = NULL;
- if (dbus_g_proxy_end_call (proxy, call_id, NULL,
- G_TYPE_BOOLEAN, &scanning,
- G_TYPE_INVALID)) {
- if (scanning != priv->scanning) {
- priv->scanning = scanning;
- g_object_notify (G_OBJECT (info->interface), "scanning");
- }
+ if (dbus_g_proxy_end_call (proxy, call_id, &error,
+ DBUS_TYPE_G_OBJECT_PATH, &path,
+ G_TYPE_INVALID)) {
+ interface_add_done (info->interface, path);
+ } else {
+ nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
+ priv->dev, error->message);
+ g_clear_error (&error);
+ set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
}
}
static void
-wpas_iface_get_scanning (NMSupplicantInterface *self)
+interface_get (NMSupplicantInterface *self)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
NMSupplicantInfo *info;
DBusGProxyCall *call;
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanning",
- iface_scanning_cb,
+ info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->wpas_proxy, "GetInterface",
+ interface_get_cb,
info,
nm_supplicant_info_destroy,
+ G_TYPE_STRING, priv->dev,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
}
static void
-wpas_iface_handle_scanning (DBusGProxy *proxy,
- gboolean scanning,
- gpointer user_data)
-{
- NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
- if (scanning != priv->scanning) {
- priv->scanning = scanning;
- g_object_notify (G_OBJECT (self), "scanning");
- }
-}
-
-gboolean
-nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
-{
- NMSupplicantInterfacePrivate *priv;
-
- g_return_val_if_fail (self != NULL, FALSE);
-
- priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- if (priv->scanning)
- return TRUE;
- if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING)
- return TRUE;
- return FALSE;
-}
-
-static void
-nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+interface_add_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call_id,
+ gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GError *err = NULL;
+ GError *error = NULL;
char *path = NULL;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_OBJECT_PATH, &path,
- G_TYPE_INVALID)) {
-
- if (dbus_g_error_has_name (err, WPAS_ERROR_INVALID_IFACE)) {
- /* Interface not added, try to add it */
- nm_supplicant_interface_add_to_supplicant (info->interface, FALSE);
- } else if (dbus_g_error_has_name (err, WPAS_ERROR_EXISTS_ERROR)) {
- /* Interface already added, just try to get the interface */
- nm_supplicant_interface_add_to_supplicant (info->interface, TRUE);
+ if (dbus_g_proxy_end_call (proxy, call_id, &error,
+ DBUS_TYPE_G_OBJECT_PATH, &path,
+ G_TYPE_INVALID)) {
+ interface_add_done (info->interface, path);
+ } else {
+ if (dbus_g_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) {
+ /* Interface already added, just get its object path */
+ interface_get (info->interface);
+ } else if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN)
+ || dbus_g_error_has_name (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) {
+ /* Supplicant wasn't running and could be launched via service
+ * activation. Wait for it to start by moving back to the INIT
+ * state.
+ */
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s",
+ priv->dev, error->message);
+ set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_INIT);
} else {
- nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s",
- priv->dev, err->message);
+ nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s",
+ priv->dev, error->message);
+ set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
}
-
- g_error_free (err);
- } else {
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): interface added to supplicant", priv->dev);
-
- priv->object_path = path;
-
- priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- path,
- WPAS_DBUS_IFACE_INTERFACE);
-
- dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID);
-
- dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING,
- G_TYPE_NONE,
- G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
-
- dbus_g_proxy_add_signal (priv->iface_proxy, "StateChange", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-
- dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable",
- G_CALLBACK (wpas_iface_query_scan_results),
- info->interface,
- NULL);
-
- dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange",
- G_CALLBACK (wpas_iface_handle_state_change),
- info->interface,
- NULL);
-
- dbus_g_proxy_add_signal (priv->iface_proxy, "Scanning", G_TYPE_BOOLEAN, G_TYPE_INVALID);
-
- dbus_g_proxy_connect_signal (priv->iface_proxy, "Scanning",
- G_CALLBACK (wpas_iface_handle_scanning),
- info->interface,
- NULL);
-
- /* Interface added to the supplicant; get its initial state. */
- wpas_iface_get_state (info->interface);
- wpas_iface_get_scanning (info->interface);
+ g_clear_error (&error);
}
}
static void
-nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self,
- gboolean get_only)
+interface_add (NMSupplicantInterface *self, gboolean is_wireless)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- NMSupplicantInfo *info;
- DBusGProxy *proxy;
DBusGProxyCall *call;
-
- proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- WPAS_DBUS_INTERFACE);
- info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
-
- if (get_only) {
- call = dbus_g_proxy_begin_call (proxy, "getInterface",
- nm_supplicant_interface_add_cb,
- info,
- nm_supplicant_info_destroy,
- G_TYPE_STRING, priv->dev,
- G_TYPE_INVALID);
- } else {
- GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
- GValue *driver;
-
- driver = g_new0 (GValue, 1);
- g_value_init (driver, G_TYPE_STRING);
- g_value_set_string (driver, priv->is_wireless ? "wext" : "wired");
- g_hash_table_insert (hash, "driver", driver);
-
- call = dbus_g_proxy_begin_call (proxy, "addInterface",
- nm_supplicant_interface_add_cb,
- info,
- nm_supplicant_info_destroy,
- G_TYPE_STRING, priv->dev,
- DBUS_TYPE_G_MAP_OF_VARIANT, hash,
- G_TYPE_INVALID);
-
- g_value_unset (driver);
- g_free (driver);
- g_hash_table_destroy (hash);
- }
-
- g_object_unref (proxy);
-
- nm_supplicant_info_set_call (info, call);
-}
-
-static void
-nm_supplicant_interface_start (NMSupplicantInterface * self)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- guint32 state;
+ NMSupplicantInfo *info;
+ GHashTable *hash;
+ GValue *driver, *ifname;
/* Can only start the interface from INIT state */
g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
nm_log_dbg (LOGD_SUPPLICANT, "(%s): adding interface to supplicant", priv->dev);
- state = nm_supplicant_manager_get_state (priv->smgr);
- if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
- nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
- nm_supplicant_interface_add_to_supplicant (self, FALSE);
- } else if (state == NM_SUPPLICANT_MANAGER_STATE_DOWN) {
- /* Don't do anything; wait for signal from supplicant manager
- * that its state has changed.
- */
- } else
- nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
-}
+ /* Move to starting to prevent double-calls of interface_add() */
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
-static void
-nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self)
-{
- switch (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state) {
- case NM_SUPPLICANT_INTERFACE_STATE_INIT:
- /* Move to STARTING state when supplicant is ready */
- nm_supplicant_interface_start (self);
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_STARTING:
- /* Don't do anything here, though we should never hit this */
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_READY:
- /* Don't do anything here, though we should never hit this */
- break;
- case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
- /* Don't do anything here; interface can't get out of DOWN state */
- break;
- default:
- nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant interface state!");
- break;
- }
-}
+ /* Try to add the interface to the supplicant. If the supplicant isn't
+ * running, this will start it via D-Bus activation and return the response
+ * when the supplicant has started.
+ */
+ info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls);
-static void
-nm_supplicant_interface_set_state (NMSupplicantInterface * self,
- guint32 new_state)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- guint32 old_state;
+ hash = g_hash_table_new (g_str_hash, g_str_equal);
- g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
+ driver = g_new0 (GValue, 1);
+ g_value_init (driver, G_TYPE_STRING);
+ g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired");
+ g_hash_table_insert (hash, "Driver", driver);
- if (new_state == priv->state)
- return;
+ ifname = g_new0 (GValue, 1);
+ g_value_init (ifname, G_TYPE_STRING);
+ g_value_set_string (ifname, priv->dev);
+ g_hash_table_insert (hash, "Ifname", ifname);
- old_state = priv->state;
- if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
- /* If the interface is transitioning to DOWN and there's are
- * in-progress pending calls, cancel them.
- */
- cancel_all_callbacks (priv->other_pcalls);
- cancel_all_callbacks (priv->assoc_pcalls);
- }
+ call = dbus_g_proxy_begin_call (priv->wpas_proxy, "CreateInterface",
+ interface_add_cb,
+ info,
+ nm_supplicant_info_destroy,
+ DBUS_TYPE_G_MAP_OF_VARIANT, hash,
+ G_TYPE_INVALID);
- priv->state = new_state;
- g_signal_emit (self,
- nm_supplicant_interface_signals[STATE],
- 0,
- priv->state,
- old_state);
+ g_hash_table_destroy (hash);
+ g_value_unset (driver);
+ g_free (driver);
+ g_value_unset (ifname);
+ g_free (ifname);
+
+ nm_supplicant_info_set_call (info, call);
}
static void
-nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr,
- guint32 new_state,
- guint32 old_state,
- gpointer user_data)
+smgr_avail_cb (NMSupplicantManager *smgr,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (user_data);
+ NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
- switch (new_state) {
- case NM_SUPPLICANT_MANAGER_STATE_DOWN:
- /* The supplicant went away, likely the connection to it is also
- * gone. Therefore, this interface must move to the DOWN state
- * and be disposed of.
- */
- nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
- break;
- case NM_SUPPLICANT_MANAGER_STATE_IDLE:
- /* Handle the supplicant now being available. */
- nm_supplicant_interface_handle_supplicant_manager_idle_state (self);
- break;
- default:
- nm_log_warn (LOGD_SUPPLICANT, "Unknown supplicant manager state!");
- break;
+ if (nm_supplicant_manager_available (smgr)) {
+ /* This can happen if the supplicant couldn't be activated but
+ * for some reason was started after the activation failure.
+ */
+ if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT)
+ interface_add (self, priv->is_wireless);
+ } else {
+ /* The supplicant stopped; so we must tear down the interface */
+ set_state (self, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
}
}
-
static void
remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- GError *err = NULL;
- guint tmp;
+ GError *error = NULL;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
nm_log_dbg (LOGD_SUPPLICANT, "Couldn't remove network from supplicant interface: %s.",
- err->message);
- g_error_free (err);
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
}
}
static void
disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
- GError *err = NULL;
- guint tmp;
+ GError *error = NULL;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't disconnect supplicant interface: %s.",
- err->message);
- g_error_free (err);
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
}
}
@@ -1045,32 +682,26 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self)
if (!priv->iface_proxy)
return;
- /* Don't try to disconnect if the supplicant interface is already
- * disconnected.
- */
- if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
- || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) {
- if (priv->net_proxy) {
- g_object_unref (priv->net_proxy);
- priv->net_proxy = NULL;
- }
-
+ /* Don't try to disconnect if the supplicant interface is already disconnected */
+ if ( priv->state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED
+ || priv->state == NM_SUPPLICANT_INTERFACE_STATE_INACTIVE) {
+ g_free (priv->net_path);
+ priv->net_path = NULL;
return;
}
/* Remove any network that was added by NetworkManager */
- if (priv->net_proxy) {
- dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork",
+ if (priv->net_path) {
+ dbus_g_proxy_begin_call (priv->iface_proxy, "RemoveNetwork",
remove_network_cb,
NULL, NULL,
- DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy),
+ DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
G_TYPE_INVALID);
-
- g_object_unref (priv->net_proxy);
- priv->net_proxy = NULL;
+ g_free (priv->net_path);
+ priv->net_path = NULL;
}
- dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect",
+ dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect",
disconnect_cb,
NULL, NULL,
G_TYPE_INVALID);
@@ -1081,9 +712,8 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
GError *err = NULL;
- guint tmp;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't select network config: %s.", err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
@@ -1091,163 +721,86 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat
}
static void
-set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
-{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GError *err = NULL;
- guint tmp;
-
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
- nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network config: %s.", err->message);
- emit_error_helper (info->interface, err);
- g_error_free (err);
- } else {
- DBusGProxyCall *call;
-
- info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "selectNetwork",
- select_network_cb,
- info,
- nm_supplicant_info_destroy,
- DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (proxy),
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
- }
-}
-
-static void
-call_set_network (NMSupplicantInfo *info)
+call_select_network (NMSupplicantInterface *self)
{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GHashTable *config_hash;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
DBusGProxyCall *call;
+ NMSupplicantInfo *info;
- config_hash = nm_supplicant_config_get_hash (priv->cfg);
- call = dbus_g_proxy_begin_call (priv->net_proxy, "set",
- set_network_cb,
+ /* We only select the network after all blobs (if any) have been set */
+ if (priv->blobs_left > 0)
+ return;
+
+ info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork",
+ select_network_cb,
info,
nm_supplicant_info_destroy,
- DBUS_TYPE_G_MAP_OF_VARIANT, config_hash,
+ DBUS_TYPE_G_OBJECT_PATH, priv->net_path,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
- g_hash_table_destroy (config_hash);
}
static void
-set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
GError *err = NULL;
guint tmp;
+ priv->blobs_left--;
+
if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
- } else {
- info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
- call_set_network (info);
- }
-}
-
-static GValue *
-byte_array_to_gvalue (const GByteArray *array)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
- g_value_set_boxed (val, array);
-
- return val;
-}
-
-static void
-blob_free (GValue *val)
-{
- g_value_unset (val);
- g_slice_free (GValue, val);
-}
-
-static void
-convert_blob (const char *key, const GByteArray *value, GHashTable *hash)
-{
- GValue *val;
-
- val = byte_array_to_gvalue (value);
- g_hash_table_insert (hash, g_strdup (key), val);
-}
-
-static void
-call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- DBusGProxyCall *call;
- GHashTable *blobs;
-
- blobs = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) blob_free);
- if (!blobs) {
- const char *msg = "Not enough memory to create blob table.";
-
- nm_log_warn (LOGD_SUPPLICANT, "%s", msg);
- g_signal_emit (info->interface,
- nm_supplicant_interface_signals[CONNECTION_ERROR],
- 0, "SendBlobError", msg);
- return;
- }
-
- g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs);
-
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "setBlobs",
- set_blobs_cb,
- info,
- nm_supplicant_info_destroy,
- DBUS_TYPE_G_MAP_OF_VARIANT, blobs,
- G_TYPE_INVALID);
- nm_supplicant_info_set_call (info, call);
- g_hash_table_destroy (blobs);
+ } else
+ call_select_network (info->interface);
}
static void
add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
GError *err = NULL;
- char *path = NULL;
+ GHashTable *blobs;
+ GHashTableIter iter;
+ gpointer name, data;
+ DBusGProxyCall *call;
+ NMSupplicantInfo *blob_info;
+
+ g_free (priv->net_path);
+ priv->net_path = NULL;
if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- DBUS_TYPE_G_OBJECT_PATH, &path,
+ DBUS_TYPE_G_OBJECT_PATH, &priv->net_path,
G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.",
err->message);
emit_error_helper (info->interface, err);
g_error_free (err);
- } else {
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- GHashTable *blobs;
-
- priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
- WPAS_DBUS_SERVICE,
- path,
- WPAS_DBUS_IFACE_NETWORK);
- g_free (path);
-
- info = nm_supplicant_info_new (info->interface,
- priv->net_proxy,
- priv->assoc_pcalls);
- /* Send any blobs first; if there aren't any jump to sending the
- * config settings.
- */
- blobs = nm_supplicant_config_get_blobs (priv->cfg);
- if (g_hash_table_size (blobs) > 0)
- call_set_blobs (info, blobs);
- else
- call_set_network (info);
+ return;
}
+
+ /* Send blobs first; otherwise jump to sending the config settings */
+ blobs = nm_supplicant_config_get_blobs (priv->cfg);
+ priv->blobs_left = g_hash_table_size (blobs);
+ g_hash_table_iter_init (&iter, blobs);
+ while (g_hash_table_iter_next (&iter, &name, &data)) {
+ blob_info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddBlob",
+ add_blob_cb,
+ blob_info,
+ nm_supplicant_info_destroy,
+ DBUS_TYPE_STRING, name,
+ DBUS_TYPE_G_UCHAR_ARRAY, blobs,
+ G_TYPE_INVALID);
+ nm_supplicant_info_set_call (blob_info, call);
+ }
+
+ call_select_network (info->interface);
}
static void
@@ -1256,10 +809,10 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
GError *err = NULL;
- guint32 tmp;
DBusGProxyCall *call;
+ GHashTable *config_hash;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Couldn't send AP scan mode to the supplicant interface: %s.",
err->message);
emit_error_helper (info->interface, err);
@@ -1270,12 +823,15 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d",
nm_supplicant_config_get_ap_scan (priv->cfg));
- info = nm_supplicant_info_new (info->interface, proxy, info->store);
- call = dbus_g_proxy_begin_call (proxy, "addNetwork",
+ info = nm_supplicant_info_new (info->interface, priv->iface_proxy, info->store);
+ config_hash = nm_supplicant_config_get_hash (priv->cfg);
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddNetwork",
add_network_cb,
info,
nm_supplicant_info_destroy,
+ DBUS_TYPE_G_MAP_OF_VARIANT, config_hash,
G_TYPE_INVALID);
+ g_hash_table_destroy (config_hash);
nm_supplicant_info_set_call (info, call);
}
@@ -1286,7 +842,7 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
NMSupplicantInterfacePrivate *priv;
NMSupplicantInfo *info;
DBusGProxyCall *call;
- guint32 ap_scan;
+ GValue value = { 0, };
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
@@ -1303,46 +859,54 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
g_object_ref (priv->cfg);
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan",
+ g_value_init (&value, G_TYPE_UINT);
+ g_value_set_uint (&value, nm_supplicant_config_get_ap_scan (priv->cfg));
+
+ info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls);
+ call = dbus_g_proxy_begin_call (priv->props_proxy, "Set",
set_ap_scan_cb,
info,
nm_supplicant_info_destroy,
- G_TYPE_UINT, ap_scan,
+ G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
+ G_TYPE_STRING, "ApScan",
+ G_TYPE_VALUE, &value,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
+ g_value_unset (&value);
return call != NULL;
}
-const char *
-nm_supplicant_interface_get_device (NMSupplicantInterface * self)
-{
- g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
-
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
-}
-
static void
scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
{
NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
GError *err = NULL;
- guint32 success = 0;
- if (!dbus_g_proxy_end_call (proxy, call_id, &err,
- G_TYPE_UINT, &success,
- G_TYPE_INVALID)) {
+ if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) {
nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", err->message);
- g_error_free (err);
}
+ g_signal_emit (info->interface, signals[SCAN_DONE], 0, err ? FALSE : TRUE);
+ g_clear_error (&err);
+}
+
+static void
+destroy_gvalue (gpointer data)
+{
+ GValue *value = (GValue *) data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+static GValue *
+string_to_gvalue (const char *str)
+{
+ GValue *val = g_slice_new0 (GValue);
- /* Notify listeners of the result of the scan */
- g_signal_emit (info->interface,
- nm_supplicant_interface_signals[SCAN_REQ_RESULT],
- 0,
- success ? TRUE : FALSE);
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_string (val, str);
+ return val;
}
gboolean
@@ -1351,17 +915,24 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface * self)
NMSupplicantInterfacePrivate *priv;
NMSupplicantInfo *info;
DBusGProxyCall *call;
+ GHashTable *hash;
g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ /* Scan parameters */
+ hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue);
+ g_hash_table_insert (hash, "Type", string_to_gvalue ("active"));
+
info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan",
+ call = dbus_g_proxy_begin_call (priv->iface_proxy, "Scan",
scan_request_cb,
info,
nm_supplicant_info_destroy,
+ DBUS_TYPE_G_MAP_OF_VARIANT, hash,
G_TYPE_INVALID);
+ g_hash_table_destroy (hash);
nm_supplicant_info_set_call (info, call);
return call != NULL;
@@ -1375,14 +946,6 @@ nm_supplicant_interface_get_state (NMSupplicantInterface * self)
return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state;
}
-guint32
-nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self)
-{
- g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED);
-
- return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->con_state;
-}
-
const char *
nm_supplicant_interface_state_to_string (guint32 state)
{
@@ -1393,6 +956,24 @@ nm_supplicant_interface_state_to_string (guint32 state)
return "starting";
case NM_SUPPLICANT_INTERFACE_STATE_READY:
return "ready";
+ case NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED:
+ return "disconnected";
+ case NM_SUPPLICANT_INTERFACE_STATE_INACTIVE:
+ return "inactive";
+ case NM_SUPPLICANT_INTERFACE_STATE_SCANNING:
+ return "scanning";
+ case NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING:
+ return "authenticating";
+ case NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING:
+ return "associating";
+ case NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED:
+ return "associated";
+ case NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE:
+ return "4-way handshake";
+ case NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE:
+ return "group handshake";
+ case NM_SUPPLICANT_INTERFACE_STATE_COMPLETED:
+ return "completed";
case NM_SUPPLICANT_INTERFACE_STATE_DOWN:
return "down";
default:
@@ -1402,28 +983,227 @@ nm_supplicant_interface_state_to_string (guint32 state)
}
const char *
-nm_supplicant_interface_connection_state_to_string (guint32 state)
+nm_supplicant_interface_get_device (NMSupplicantInterface * self)
{
- switch (state) {
- case NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED:
- return "disconnected";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE:
- return "inactive";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING:
- return "scanning";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING:
- return "associating";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED:
- return "associated";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE:
- return "4-way handshake";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE:
- return "group handshake";
- case NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED:
- return "completed";
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
+
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
+}
+
+const char *
+nm_supplicant_interface_get_object_path (NMSupplicantInterface *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
+
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->object_path;
+}
+
+const char *
+nm_supplicant_interface_get_ifname (NMSupplicantInterface *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
+
+ return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
+}
+
+/*******************************************************************/
+
+NMSupplicantInterface *
+nm_supplicant_interface_new (NMSupplicantManager *smgr,
+ const char *ifname,
+ gboolean is_wireless,
+ gboolean start_now)
+{
+ NMSupplicantInterface *self;
+ NMSupplicantInterfacePrivate *priv;
+ guint id;
+
+ g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL);
+ g_return_val_if_fail (ifname != NULL, NULL);
+
+ self = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE, NULL);
+ if (self) {
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+ priv->smgr = g_object_ref (smgr);
+ id = g_signal_connect (priv->smgr,
+ "notify::" NM_SUPPLICANT_MANAGER_AVAILABLE,
+ G_CALLBACK (smgr_avail_cb),
+ self);
+ priv->smgr_avail_id = id;
+
+ priv->dev = g_strdup (ifname);
+ priv->is_wireless = is_wireless;
+
+ if (start_now)
+ interface_add (self, priv->is_wireless);
+ }
+
+ return self;
+}
+
+static void
+nm_supplicant_interface_init (NMSupplicantInterface * self)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ DBusGConnection *bus;
+
+ priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
+ priv->assoc_pcalls = nm_call_store_new ();
+ priv->other_pcalls = nm_call_store_new ();
+ priv->dbus_mgr = nm_dbus_manager_get ();
+
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+ priv->wpas_proxy = dbus_g_proxy_new_for_name (bus,
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE);
+}
+
+static void
+set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
- return "unknown";
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_SCANNING:
+ g_value_set_boolean (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->scanning);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
+
+ if (priv->disposed) {
+ G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
+ return;
+ }
+ priv->disposed = TRUE;
+
+ /* Cancel pending calls before unrefing the dbus manager */
+ cancel_all_callbacks (priv->other_pcalls);
+ nm_call_store_destroy (priv->other_pcalls);
+
+ cancel_all_callbacks (priv->assoc_pcalls);
+ nm_call_store_destroy (priv->assoc_pcalls);
+
+ if (priv->props_proxy)
+ g_object_unref (priv->props_proxy);
+
+ if (priv->iface_proxy)
+ g_object_unref (priv->iface_proxy);
+
+ g_free (priv->net_path);
+
+ if (priv->wpas_proxy)
+ g_object_unref (priv->wpas_proxy);
+
+ if (priv->smgr) {
+ if (priv->smgr_avail_id)
+ g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id);
+ g_object_unref (priv->smgr);
+ }
+
+ g_free (priv->dev);
+
+ if (priv->dbus_mgr)
+ g_object_unref (priv->dbus_mgr);
+
+ if (priv->cfg)
+ g_object_unref (priv->cfg);
+
+ g_free (priv->object_path);
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
+}
+
+static void
+nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
+
+ object_class->dispose = dispose;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+
+ /* Properties */
+ g_object_class_install_property (object_class, PROP_SCANNING,
+ g_param_spec_boolean ("scanning",
+ "Scanning",
+ "Scanning",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* Signals */
+ signals[STATE] =
+ g_signal_new (NM_SUPPLICANT_INTERFACE_STATE,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state),
+ NULL, NULL,
+ _nm_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
+ signals[REMOVED] =
+ g_signal_new (NM_SUPPLICANT_INTERFACE_REMOVED,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_BSS] =
+ g_signal_new (NM_SUPPLICANT_INTERFACE_NEW_BSS,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, new_bss),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ signals[SCAN_DONE] =
+ g_signal_new (NM_SUPPLICANT_INTERFACE_SCAN_DONE,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_done),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ signals[CONNECTION_ERROR] =
+ g_signal_new (NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR,
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error),
+ NULL, NULL,
+ _nm_marshal_VOID__STRING_STRING,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
}
diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h
index bee5436f5..e32411d7c 100644
--- a/src/supplicant-manager/nm-supplicant-interface.h
+++ b/src/supplicant-manager/nm-supplicant-interface.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2006 - 2008 Red Hat, Inc.
+ * Copyright (C) 2006 - 2010 Red Hat, Inc.
* Copyright (C) 2007 - 2008 Novell, Inc.
*/
@@ -26,47 +26,27 @@
#include <dbus/dbus.h>
#include "nm-supplicant-types.h"
-G_BEGIN_DECLS
-
/*
* Supplicant interface states
- * The states are linear, ie INIT -> READY -> DOWN and state may only be
- * changed in one direction. If an interface reaches the DOWN state, it
- * cannot be re-initialized; it must be torn down and a new one created.
- *
- * INIT: interface has been created, but cannot be used yet; it is waiting
- * for pending requests of the supplicant to complete.
- * READY: interface is ready for use
- * DOWN: interface has been removed or has otherwise been made invalid; it
- * must be torn down.
- *
- * Note: LAST is an invalid state and only used for boundary checking.
+ * A mix of wpa_supplicant interface states and internal states.
*/
enum {
NM_SUPPLICANT_INTERFACE_STATE_INIT = 0,
NM_SUPPLICANT_INTERFACE_STATE_STARTING,
NM_SUPPLICANT_INTERFACE_STATE_READY,
+ NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED,
+ NM_SUPPLICANT_INTERFACE_STATE_INACTIVE,
+ NM_SUPPLICANT_INTERFACE_STATE_SCANNING,
+ NM_SUPPLICANT_INTERFACE_STATE_AUTHENTICATING,
+ NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING,
+ NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED,
+ NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE,
+ NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE,
+ NM_SUPPLICANT_INTERFACE_STATE_COMPLETED,
NM_SUPPLICANT_INTERFACE_STATE_DOWN,
NM_SUPPLICANT_INTERFACE_STATE_LAST
};
-
-/*
- * Supplicant interface connection states
- * The wpa_supplicant state for the connection.
- */
-enum {
- NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED = 0,
- NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE,
- NM_SUPPLICANT_INTERFACE_CON_STATE_SCANNING,
- NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATING,
- NM_SUPPLICANT_INTERFACE_CON_STATE_ASSOCIATED,
- NM_SUPPLICANT_INTERFACE_CON_STATE_4WAY_HANDSHAKE,
- NM_SUPPLICANT_INTERFACE_CON_STATE_GROUP_HANDSHAKE,
- NM_SUPPLICANT_INTERFACE_CON_STATE_COMPLETED,
- NM_SUPPLICANT_INTERFACE_CON_STATE_LAST
-};
-
#define NM_TYPE_SUPPLICANT_INTERFACE (nm_supplicant_interface_get_type ())
#define NM_SUPPLICANT_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterface))
#define NM_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
@@ -74,6 +54,12 @@ enum {
#define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE))
#define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
+#define NM_SUPPLICANT_INTERFACE_STATE "state"
+#define NM_SUPPLICANT_INTERFACE_REMOVED "removed"
+#define NM_SUPPLICANT_INTERFACE_NEW_BSS "new-bss"
+#define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done"
+#define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error"
+
struct _NMSupplicantInterface {
GObject parent;
};
@@ -91,23 +77,14 @@ typedef struct {
/* interface was removed by the supplicant */
void (*removed) (NMSupplicantInterface * iface);
- /* interface saw a new access point from a scan */
- void (*scanned_ap) (NMSupplicantInterface * iface,
- DBusMessage * message);
+ /* interface saw a new BSS */
+ void (*new_bss) (NMSupplicantInterface *iface,
+ GHashTable *props);
- /* result of a wireless scan request */
- void (*scan_req_result) (NMSupplicantInterface * iface,
+ /* wireless scan is done */
+ void (*scan_done) (NMSupplicantInterface *iface,
gboolean success);
- /* scan results returned from supplicant */
- void (*scan_results) (NMSupplicantInterface * iface,
- guint num_bssids);
-
- /* link state of the device's connection */
- void (*connection_state) (NMSupplicantInterface * iface,
- guint32 new_state,
- guint32 old_state);
-
/* an error occurred during a connection request */
void (*connection_error) (NMSupplicantInterface * iface,
const char * name,
@@ -119,7 +96,8 @@ GType nm_supplicant_interface_get_type (void);
NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr,
const char *ifname,
- gboolean is_wireless);
+ gboolean is_wireless,
+ gboolean start_now);
gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface,
NMSupplicantConfig * cfg);
@@ -128,18 +106,16 @@ void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface);
const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
+const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface);
+
gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self);
guint32 nm_supplicant_interface_get_state (NMSupplicantInterface * self);
-guint32 nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self);
-
const char *nm_supplicant_interface_state_to_string (guint32 state);
-const char *nm_supplicant_interface_connection_state_to_string (guint32 state);
-
gboolean nm_supplicant_interface_get_scanning (NMSupplicantInterface *self);
-G_END_DECLS
+const char *nm_supplicant_interface_get_ifname (NMSupplicantInterface *self);
#endif /* NM_SUPPLICANT_INTERFACE_H */
diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c
index a2cf58eb8..8209da21d 100644
--- a/src/supplicant-manager/nm-supplicant-manager.c
+++ b/src/supplicant-manager/nm-supplicant-manager.c
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2006 - 2008 Red Hat, Inc.
+ * Copyright (C) 2006 - 2010 Red Hat, Inc.
* Copyright (C) 2007 - 2008 Novell, Inc.
*/
@@ -26,19 +26,7 @@
#include "nm-supplicant-manager.h"
#include "nm-supplicant-interface.h"
#include "nm-dbus-manager.h"
-#include "nm-marshal.h"
#include "nm-logging.h"
-#include "nm-glib-compat.h"
-
-#define SUPPLICANT_POKE_INTERVAL 120
-
-typedef struct {
- NMDBusManager * dbus_mgr;
- guint32 state;
- GSList * ifaces;
- gboolean dispose_has_run;
- guint poke_id;
-} NMSupplicantManagerPrivate;
#define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_MANAGER, \
@@ -46,298 +34,283 @@ typedef struct {
G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT)
+/* Properties */
+enum {
+ PROP_0 = 0,
+ PROP_AVAILABLE,
+ LAST_PROP
+};
-static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
- const char *name,
- const char *old,
- const char *new,
- gpointer user_data);
+typedef struct {
+ NMDBusManager * dbus_mgr;
+ guint name_owner_id;
+ DBusGProxy * proxy;
+ gboolean running;
+ GHashTable * ifaces;
+ guint die_count_reset_id;
+ guint die_count;
+ gboolean disposed;
+} NMSupplicantManagerPrivate;
-static void nm_supplicant_manager_set_state (NMSupplicantManager * self,
- guint32 new_state);
+/********************************************************************/
-static gboolean nm_supplicant_manager_startup (NMSupplicantManager * self);
+static inline gboolean
+die_count_exceeded (guint32 count)
+{
+ return count > 2;
+}
+NMSupplicantInterface *
+nm_supplicant_manager_iface_get (NMSupplicantManager * self,
+ const char *ifname,
+ gboolean is_wireless)
+{
+ NMSupplicantManagerPrivate *priv;
+ NMSupplicantInterface *iface = NULL;
+ gboolean start_now;
-/* Signals */
-enum {
- STATE, /* change in the manager's state */
- LAST_SIGNAL
-};
-static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 };
+ g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
+ g_return_val_if_fail (ifname != NULL, NULL);
+ priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
-NMSupplicantManager *
-nm_supplicant_manager_get (void)
-{
- static NMSupplicantManager * singleton = NULL;
+ iface = g_hash_table_lookup (priv->ifaces, ifname);
+ if (!iface) {
+ /* If we're making the supplicant take a time out for a bit, don't
+ * let the supplicant interface start immediately, just let it hang
+ * around in INIT state until we're ready to talk to the supplicant
+ * again.
+ */
+ start_now = !die_count_exceeded (priv->die_count);
- if (!singleton) {
- singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL));
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
+ iface = nm_supplicant_interface_new (self, ifname, is_wireless, start_now);
+ if (iface)
+ g_hash_table_insert (priv->ifaces, g_strdup (ifname), iface);
} else {
- g_object_ref (singleton);
+ nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname);
}
- g_assert (singleton);
- return singleton;
+ return iface;
}
-static gboolean
-poke_supplicant_cb (gpointer user_data)
+void
+nm_supplicant_manager_iface_release (NMSupplicantManager *self,
+ NMSupplicantInterface *iface)
{
- NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
- NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- DBusGConnection *g_connection;
- DBusGProxy *proxy;
- const char *tmp = "ignoreme";
-
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- proxy = dbus_g_proxy_new_for_name (g_connection,
- WPAS_DBUS_SERVICE,
- WPAS_DBUS_PATH,
- WPAS_DBUS_INTERFACE);
- if (!proxy) {
- nm_log_warn (LOGD_SUPPLICANT, "Error: could not init wpa_supplicant proxy");
- goto out;
- }
+ NMSupplicantManagerPrivate *priv;
+ const char *ifname, *op;
- nm_log_info (LOGD_SUPPLICANT, "Trying to start the supplicant...");
- dbus_g_proxy_call_no_reply (proxy, "getInterface", G_TYPE_STRING, tmp, G_TYPE_INVALID);
- g_object_unref (proxy);
+ g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
+ g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface));
-out:
- /* Reschedule the poke */
- priv->poke_id = g_timeout_add_seconds (SUPPLICANT_POKE_INTERVAL,
- poke_supplicant_cb,
- (gpointer) self);
+ ifname = nm_supplicant_interface_get_ifname (iface);
+ g_assert (ifname);
- return FALSE;
-}
+ priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
-static void
-nm_supplicant_manager_init (NMSupplicantManager * self)
-{
- NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- gboolean running;
+ g_return_if_fail (g_hash_table_lookup (priv->ifaces, ifname) == iface);
- priv->dispose_has_run = FALSE;
- priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
- priv->dbus_mgr = nm_dbus_manager_get ();
- priv->poke_id = 0;
+ /* Ask wpa_supplicant to remove this interface */
+ op = nm_supplicant_interface_get_object_path (iface);
+ if (priv->running && priv->proxy && op) {
+ dbus_g_proxy_call_no_reply (priv->proxy, "RemoveInterface",
+ DBUS_TYPE_G_OBJECT_PATH, op,
+ G_TYPE_INVALID);
+ }
- running = nm_supplicant_manager_startup (self);
+ g_hash_table_remove (priv->ifaces, ifname);
+}
- g_signal_connect (priv->dbus_mgr,
- "name-owner-changed",
- G_CALLBACK (nm_supplicant_manager_name_owner_changed),
- self);
+gboolean
+nm_supplicant_manager_available (NMSupplicantManager *self)
+{
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
- if (!running) {
- /* Try to activate the supplicant */
- priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self);
- }
+ if (die_count_exceeded (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->die_count))
+ return FALSE;
+ return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->running;
}
static void
-nm_supplicant_manager_dispose (GObject *object)
+set_running (NMSupplicantManager *self, gboolean now_running)
{
- NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
-
- if (priv->dispose_has_run) {
- G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
- return;
- }
-
- priv->dispose_has_run = TRUE;
-
- if (priv->poke_id) {
- g_source_remove (priv->poke_id);
- priv->poke_id = 0;
- }
-
- if (priv->dbus_mgr) {
- g_object_unref (G_OBJECT (priv->dbus_mgr));
- priv->dbus_mgr = NULL;
- }
+ NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+ gboolean old_available = nm_supplicant_manager_available (self);
- /* Chain up to the parent class */
- G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
+ priv->running = now_running;
+ if (old_available != nm_supplicant_manager_available (self))
+ g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE);
}
static void
-nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
+set_die_count (NMSupplicantManager *self, guint new_die_count)
{
- GObjectClass * object_class = G_OBJECT_CLASS (klass);
+ NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+ gboolean old_available = nm_supplicant_manager_available (self);
- g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
+ priv->die_count = new_die_count;
+ if (old_available != nm_supplicant_manager_available (self))
+ g_object_notify (G_OBJECT (self), NM_SUPPLICANT_MANAGER_AVAILABLE);
+}
- object_class->dispose = nm_supplicant_manager_dispose;
-
- /* Signals */
- nm_supplicant_manager_signals[STATE] =
- g_signal_new ("state",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMSupplicantManagerClass, state),
- NULL, NULL,
- _nm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+static gboolean
+wpas_die_count_reset_cb (gpointer user_data)
+{
+ NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
+ NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+
+ /* Reset the die count back to zero, which allows use of the supplicant again */
+ priv->die_count_reset_id = 0;
+ set_die_count (self, 0);
+ nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant die count reset");
+ return FALSE;
}
static void
-nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
- const char *name,
- const char *old_owner,
- const char *new_owner,
- gpointer user_data)
+name_owner_changed (NMDBusManager *dbus_mgr,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
{
- NMSupplicantManager * self = (NMSupplicantManager *) user_data;
+ NMSupplicantManager *self = NM_SUPPLICANT_MANAGER (user_data);
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
gboolean old_owner_good = (old_owner && strlen (old_owner));
gboolean new_owner_good = (new_owner && strlen (new_owner));
- /* Can't handle the signal if its not from the supplicant service */
+ /* We only care about the supplicant here */
if (strcmp (WPAS_DBUS_SERVICE, name) != 0)
return;
if (!old_owner_good && new_owner_good) {
- gboolean running;
-
- running = nm_supplicant_manager_startup (self);
-
- if (running && priv->poke_id) {
- g_source_remove (priv->poke_id);
- priv->poke_id = 0;
- }
+ nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant started");
+ set_running (self, TRUE);
} else if (old_owner_good && !new_owner_good) {
- nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_DOWN);
+ nm_log_info (LOGD_SUPPLICANT, "wpa_supplicant stopped");
- if (priv->poke_id)
- g_source_remove (priv->poke_id);
-
- /* Poke the supplicant so that it gets activated by dbus system bus
- * activation.
+ /* Reschedule the die count reset timeout. Every time the supplicant
+ * dies we wait 10 seconds before resetting the counter. If the
+ * supplicant died more than twice before the timer is reset, then
+ * we don't try to talk to the supplicant for a while.
*/
- priv->poke_id = g_idle_add (poke_supplicant_cb, (gpointer) self);
+ if (priv->die_count_reset_id)
+ g_source_remove (priv->die_count_reset_id);
+ priv->die_count_reset_id = g_timeout_add_seconds (10, wpas_die_count_reset_cb, self);
+ set_die_count (self, priv->die_count + 1);
+
+ if (die_count_exceeded (priv->die_count)) {
+ nm_log_info (LOGD_SUPPLICANT,
+ "wpa_supplicant die count %d; ignoring for 10 seconds",
+ priv->die_count);
+ }
+
+ set_running (self, FALSE);
}
}
+/*******************************************************************/
-guint32
-nm_supplicant_manager_get_state (NMSupplicantManager * self)
+NMSupplicantManager *
+nm_supplicant_manager_get (void)
{
- g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
+ static NMSupplicantManager *singleton = NULL;
- return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state;
+ if (!singleton)
+ singleton = NM_SUPPLICANT_MANAGER (g_object_new (NM_TYPE_SUPPLICANT_MANAGER, NULL));
+ else
+ g_object_ref (singleton);
+
+ g_assert (singleton);
+ return singleton;
}
static void
-nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state)
+nm_supplicant_manager_init (NMSupplicantManager * self)
{
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
- guint32 old_state;
-
- if (new_state == priv->state)
- return;
+ DBusGConnection *bus;
- old_state = priv->state;
- priv->state = new_state;
- g_signal_emit (self,
- nm_supplicant_manager_signals[STATE],
- 0,
- priv->state,
- old_state);
+ priv->dbus_mgr = nm_dbus_manager_get ();
+ priv->name_owner_id = g_signal_connect (priv->dbus_mgr,
+ NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
+ G_CALLBACK (name_owner_changed),
+ self);
+ priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, WPAS_DBUS_SERVICE);
+
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+ priv->proxy = dbus_g_proxy_new_for_name (bus,
+ WPAS_DBUS_SERVICE,
+ WPAS_DBUS_PATH,
+ WPAS_DBUS_INTERFACE);
+
+ priv->ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
-static gboolean
-nm_supplicant_manager_startup (NMSupplicantManager * self)
+static void
+set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- gboolean running;
-
- /* FIXME: convert to pending call */
- running = nm_dbus_manager_name_has_owner (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->dbus_mgr,
- WPAS_DBUS_SERVICE);
- if (running)
- nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE);
-
- return running;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
-NMSupplicantInterface *
-nm_supplicant_manager_get_iface (NMSupplicantManager * self,
- const char *ifname,
- gboolean is_wireless)
+static void
+get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
- NMSupplicantManagerPrivate *priv;
- NMSupplicantInterface * iface = NULL;
- GSList * elt;
+ switch (prop_id) {
+ case PROP_AVAILABLE:
+ g_value_set_boolean (value, nm_supplicant_manager_available (NM_SUPPLICANT_MANAGER (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
- g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
- g_return_val_if_fail (ifname != NULL, NULL);
+static void
+dispose (GObject *object)
+{
+ NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
- priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+ if (priv->disposed)
+ goto out;
+ priv->disposed = TRUE;
- /* Ensure we don't already have this interface */
- for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) {
- NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
+ if (priv->die_count_reset_id)
+ g_source_remove (priv->die_count_reset_id);
- if (!strcmp (ifname, nm_supplicant_interface_get_device (if_tmp))) {
- iface = if_tmp;
- break;
- }
+ if (priv->dbus_mgr) {
+ if (priv->name_owner_id)
+ g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
+ g_object_unref (G_OBJECT (priv->dbus_mgr));
}
- if (!iface) {
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): creating new supplicant interface", ifname);
- iface = nm_supplicant_interface_new (self, ifname, is_wireless);
- if (iface)
- priv->ifaces = g_slist_append (priv->ifaces, iface);
- } else {
- nm_log_dbg (LOGD_SUPPLICANT, "(%s): returning existing supplicant interface", ifname);
- }
+ g_hash_table_destroy (priv->ifaces);
- return iface;
+ if (priv->proxy)
+ g_object_unref (priv->proxy);
+
+out:
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
}
-void
-nm_supplicant_manager_release_iface (NMSupplicantManager * self,
- NMSupplicantInterface * iface)
+static void
+nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
{
- NMSupplicantManagerPrivate *priv;
- GSList * elt;
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
- g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface));
-
- priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+ g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
- for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) {
- NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
-
- if (if_tmp == iface) {
- /* Remove the iface from the supplicant manager's list and
- * dereference to match additional reference in get_iface.
- */
- priv->ifaces = g_slist_remove_link (priv->ifaces, elt);
- g_slist_free_1 (elt);
- g_object_unref (iface);
- break;
- }
- }
-}
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+ object_class->dispose = dispose;
-const char *
-nm_supplicant_manager_state_to_string (guint32 state)
-{
- switch (state) {
- case NM_SUPPLICANT_MANAGER_STATE_DOWN:
- return "down";
- case NM_SUPPLICANT_MANAGER_STATE_IDLE:
- return "idle";
- default:
- break;
- }
- return "unknown";
+ g_object_class_install_property (object_class, PROP_AVAILABLE,
+ g_param_spec_boolean (NM_SUPPLICANT_MANAGER_AVAILABLE,
+ "Available",
+ "Available",
+ FALSE,
+ G_PARAM_READABLE));
}
-
diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h
index fef2a7744..9e2f3b21b 100644
--- a/src/supplicant-manager/nm-supplicant-manager.h
+++ b/src/supplicant-manager/nm-supplicant-manager.h
@@ -26,30 +26,13 @@
#include "nm-supplicant-types.h"
#include "nm-device.h"
-#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant"
-#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant"
-#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant"
+#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1"
+#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1"
+#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1"
G_BEGIN_DECLS
-/*
- * Supplicant manager states
- * Either state may transition to the other state at any time.
- *
- * DOWN: supplicant manager has been created, but cannot be used; the supplicant
- * is either not running or has not yet been fully initialized.
- * IDLE: supplicant manager is ready for use
- *
- * Note: LAST is an invalid state and only used for boundary checking.
- */
-enum {
- NM_SUPPLICANT_MANAGER_STATE_DOWN = 0,
- NM_SUPPLICANT_MANAGER_STATE_IDLE,
- NM_SUPPLICANT_MANAGER_STATE_LAST
-};
-
-
#define NM_TYPE_SUPPLICANT_MANAGER (nm_supplicant_manager_get_type ())
#define NM_SUPPLICANT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManager))
#define NM_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass))
@@ -57,6 +40,8 @@ enum {
#define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER))
#define NM_SUPPLICANT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass))
+#define NM_SUPPLICANT_MANAGER_AVAILABLE "available"
+
struct _NMSupplicantManager
{
GObject parent;
@@ -65,24 +50,19 @@ struct _NMSupplicantManager
typedef struct
{
GObjectClass parent;
-
- /* class members */
- void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state);
} NMSupplicantManagerClass;
GType nm_supplicant_manager_get_type (void);
-NMSupplicantManager * nm_supplicant_manager_get (void);
-
-guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr);
+NMSupplicantManager *nm_supplicant_manager_get (void);
-NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr,
- const char *ifname,
- gboolean is_wireless);
+NMSupplicantInterface *nm_supplicant_manager_iface_get (NMSupplicantManager *mgr,
+ const char *ifname,
+ gboolean is_wireless);
-void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr,
- NMSupplicantInterface * iface);
+void nm_supplicant_manager_iface_release (NMSupplicantManager *mgr,
+ NMSupplicantInterface *iface);
-const char *nm_supplicant_manager_state_to_string (guint32 state);
+gboolean nm_supplicant_manager_available (NMSupplicantManager *mgr);
#endif /* NM_SUPPLICANT_MANAGER_H */
diff --git a/src/supplicant-manager/tests/Makefile.in b/src/supplicant-manager/tests/Makefile.in
index ac812e2e4..58cb15f38 100644
--- a/src/supplicant-manager/tests/Makefile.in
+++ b/src/supplicant-manager/tests/Makefile.in
@@ -39,11 +39,16 @@ subdir = src/supplicant-manager/tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -63,7 +68,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -94,7 +99,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -103,8 +107,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -121,6 +123,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -129,6 +132,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -137,8 +141,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -153,13 +157,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -167,6 +181,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -175,13 +191,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -207,12 +225,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -227,10 +242,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am
deleted file mode 100644
index 0b92228f5..000000000
--- a/src/system-settings/Makefile.am
+++ /dev/null
@@ -1,61 +0,0 @@
-INCLUDES = -I${top_srcdir} \
- -I${top_srcdir}/include \
- -I${top_srcdir}/libnm-util \
- -I${top_srcdir}/libnm-glib \
- -I${top_srcdir}/src/logging \
- -I${top_srcdir}/src \
- -I${top_builddir}/marshallers
-
-noinst_LTLIBRARIES = libsystem-settings.la
-
-BUILT_SOURCES = \
- nm-settings-system-glue.h
-
-libsystem_settings_la_SOURCES = \
- nm-sysconfig-settings.c \
- nm-sysconfig-settings.h \
- nm-inotify-helper.c \
- nm-inotify-helper.h \
- nm-polkit-helpers.h \
- nm-system-config-error.c \
- nm-system-config-error.h \
- nm-system-config-interface.c \
- nm-system-config-interface.h \
- nm-sysconfig-connection.c \
- nm-sysconfig-connection.h \
- nm-default-wired-connection.c \
- nm-default-wired-connection.h
-
-libsystem_settings_la_CPPFLAGS = \
- $(DBUS_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GMODULE_CFLAGS) \
- $(POLKIT_CFLAGS) \
- -DG_DISABLE_DEPRECATED \
- -DBINDIR=\"$(bindir)\" \
- -DSBINDIR=\"$(sbindir)\" \
- -DLIBEXECDIR=\"$(libexecdir)\" \
- -DDATADIR=\"$(datadir)\" \
- -DSYSCONFDIR=\"$(sysconfdir)\" \
- -DLOCALSTATEDIR=\"$(localstatedir)\" \
- -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
- -DPLUGINDIR=\"$(pkglibdir)\"
-
-libsystem_settings_la_LIBADD = \
- $(top_builddir)/libnm-util/libnm-util.la \
- $(top_builddir)/libnm-glib/libnm-glib.la \
- $(top_builddir)/marshallers/libmarshallers.la \
- $(top_builddir)/src/logging/libnm-logging.la \
- $(DBUS_LIBS) \
- $(GLIB_LIBS) \
- $(GMODULE_LIBS) \
- $(POLKIT_LIBS)
-
-libsystem_settings_la_LDFLAGS = -rdynamic
-
-nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $<
-
-CLEANFILES = \
- $(BUILT_SOURCES)
-
diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c
deleted file mode 100644
index 0d19dea01..000000000
--- a/src/system-settings/nm-default-wired-connection.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Novell, Inc.
- * (C) Copyright 2009 Red Hat, Inc.
- */
-
-#include <netinet/ether.h>
-
-#include <glib/gi18n.h>
-
-#include <NetworkManager.h>
-#include <nm-setting-connection.h>
-#include <nm-setting-wired.h>
-#include <nm-utils.h>
-
-#include "nm-dbus-glib-types.h"
-#include "nm-marshal.h"
-#include "nm-default-wired-connection.h"
-#include "nm-settings-connection-interface.h"
-
-static NMSettingsConnectionInterface *parent_settings_connection_iface;
-
-static void settings_connection_interface_init (NMSettingsConnectionInterface *iface);
-
-G_DEFINE_TYPE_EXTENDED (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0,
- G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
- settings_connection_interface_init))
-
-#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate))
-
-typedef struct {
- NMDevice *device;
- GByteArray *mac;
- gboolean read_only;
-} NMDefaultWiredConnectionPrivate;
-
-enum {
- PROP_0,
- PROP_MAC,
- PROP_DEVICE,
- PROP_READ_ONLY,
- LAST_PROP
-};
-
-enum {
- TRY_UPDATE,
- DELETED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-
-NMDefaultWiredConnection *
-nm_default_wired_connection_new (const GByteArray *mac,
- NMDevice *device,
- gboolean read_only)
-{
-
- g_return_val_if_fail (mac != NULL, NULL);
- g_return_val_if_fail (mac->len == ETH_ALEN, NULL);
- g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
-
- return g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION,
- NM_DEFAULT_WIRED_CONNECTION_MAC, mac,
- NM_DEFAULT_WIRED_CONNECTION_DEVICE, device,
- NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, read_only,
- NULL);
-}
-
-NMDevice *
-nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired)
-{
- g_return_val_if_fail (NM_IS_DEFAULT_WIRED_CONNECTION (wired), NULL);
-
- return NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (wired)->device;
-}
-
-static gboolean
-update (NMSettingsConnectionInterface *connection,
- NMSettingsConnectionInterfaceUpdateFunc callback,
- gpointer user_data)
-{
- NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
-
- /* Keep the object alive over try-update since it might get removed
- * from the settings service there, but we still need it for the callback.
- */
- g_object_ref (connection);
- g_signal_emit (self, signals[TRY_UPDATE], 0);
- callback (connection, NULL, user_data);
- g_object_unref (connection);
- return TRUE;
-}
-
-static gboolean
-do_delete (NMSettingsConnectionInterface *connection,
- NMSettingsConnectionInterfaceDeleteFunc callback,
- gpointer user_data)
-{
- NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
- NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (connection);
-
- g_signal_emit (self, signals[DELETED], 0, priv->mac);
- return parent_settings_connection_iface->delete (connection, callback, user_data);
-}
-
-/****************************************************************/
-
-static void
-settings_connection_interface_init (NMSettingsConnectionInterface *iface)
-{
- parent_settings_connection_iface = g_type_interface_peek_parent (iface);
- iface->update = update;
- iface->delete = do_delete;
-}
-
-static void
-nm_default_wired_connection_init (NMDefaultWiredConnection *self)
-{
-}
-
-static GObject *
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- NMDefaultWiredConnectionPrivate *priv;
- NMSettingConnection *s_con;
- NMSettingWired *s_wired;
- char *id, *uuid;
-
- object = G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->constructor (type, n_construct_params, construct_params);
- if (!object)
- return NULL;
-
- priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
-
- s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
-
- id = g_strdup_printf (_("Auto %s"), nm_device_get_iface (priv->device));
- uuid = nm_utils_uuid_generate ();
-
- g_object_set (s_con,
- NM_SETTING_CONNECTION_ID, id,
- NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
- NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
- NM_SETTING_CONNECTION_UUID, uuid,
- NM_SETTING_CONNECTION_READ_ONLY, priv->read_only,
- NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL),
- NULL);
-
- g_free (id);
- g_free (uuid);
-
- nm_connection_add_setting (NM_CONNECTION (object), NM_SETTING (s_con));
-
- /* Lock the connection to the specific device */
- s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
- g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL);
- nm_connection_add_setting (NM_CONNECTION (object), NM_SETTING (s_wired));
-
- return object;
-}
-
-static void
-finalize (GObject *object)
-{
- NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
-
- g_object_unref (priv->device);
- g_byte_array_free (priv->mac, TRUE);
-
- G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->finalize (object);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_MAC:
- g_value_set_pointer (value, priv->mac);
- break;
- case PROP_DEVICE:
- g_value_set_object (value, priv->device);
- break;
- case PROP_READ_ONLY:
- g_value_set_boolean (value, priv->read_only);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
- GByteArray *array;
-
- switch (prop_id) {
- case PROP_MAC:
- /* Construct only */
- array = g_value_get_pointer (value);
- if (priv->mac) {
- g_byte_array_free (priv->mac, TRUE);
- priv->mac = NULL;
- }
- if (array) {
- g_return_if_fail (array->len == ETH_ALEN);
- priv->mac = g_byte_array_sized_new (array->len);
- g_byte_array_append (priv->mac, array->data, ETH_ALEN);
- }
- break;
- case PROP_DEVICE:
- if (priv->device)
- g_object_unref (priv->device);
- priv->device = g_value_dup_object (value);
- break;
- case PROP_READ_ONLY:
- priv->read_only = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate));
-
- /* Virtual methods */
- object_class->constructor = constructor;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
-
- /* Properties */
- g_object_class_install_property
- (object_class, PROP_MAC,
- g_param_spec_pointer (NM_DEFAULT_WIRED_CONNECTION_MAC,
- "MAC",
- "MAC Address",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, PROP_DEVICE,
- g_param_spec_object (NM_DEFAULT_WIRED_CONNECTION_DEVICE,
- "Device",
- "Device",
- NM_TYPE_DEVICE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, PROP_READ_ONLY,
- g_param_spec_boolean (NM_DEFAULT_WIRED_CONNECTION_READ_ONLY,
- "ReadOnly",
- "Read Only",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /* Signals */
- signals[TRY_UPDATE] =
- g_signal_new ("try-update",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /* The 'deleted' signal is used to signal intentional deletions (like
- * updating or user-requested deletion) rather than using the
- * superclass' 'removed' signal, since that signal doesn't have the
- * semantics we want; it gets emitted as a side-effect of various operations
- * and is meant more for D-Bus clients instead of in-service uses.
- */
- signals[DELETED] =
- g_signal_new ("deleted",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-}
diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c
deleted file mode 100644
index 73906d20a..000000000
--- a/src/system-settings/nm-sysconfig-connection.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Novell, Inc.
- * (C) Copyright 2008 - 2010 Red Hat, Inc.
- */
-
-#include <NetworkManager.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#include "nm-sysconfig-connection.h"
-#include "nm-system-config-error.h"
-#include "nm-dbus-glib-types.h"
-#include "nm-settings-connection-interface.h"
-#include "nm-settings-interface.h"
-#include "nm-polkit-helpers.h"
-#include "nm-logging.h"
-
-
-static void settings_connection_interface_init (NMSettingsConnectionInterface *klass);
-
-G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION, 0,
- G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
- settings_connection_interface_init))
-
-#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
- NM_TYPE_SYSCONFIG_CONNECTION, \
- NMSysconfigConnectionPrivate))
-
-typedef struct {
- PolkitAuthority *authority;
- GSList *pk_calls;
- NMConnection *secrets;
-} NMSysconfigConnectionPrivate;
-
-/**************************************************************/
-
-static void
-ignore_cb (NMSettingsConnectionInterface *connection,
- GError *error,
- gpointer user_data)
-{
-}
-
-gboolean
-nm_sysconfig_connection_update (NMSysconfigConnection *self,
- NMConnection *new,
- gboolean signal_update,
- GError **error)
-{
- NMSysconfigConnectionPrivate *priv;
- GHashTable *new_settings;
- gboolean success = FALSE;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (self), FALSE);
- g_return_val_if_fail (new != NULL, FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (new), FALSE);
-
- priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
-
- /* Do nothing if there's nothing to update */
- if (nm_connection_compare (NM_CONNECTION (self),
- NM_CONNECTION (new),
- NM_SETTING_COMPARE_FLAG_EXACT))
- return TRUE;
-
- new_settings = nm_connection_to_hash (new);
- g_assert (new_settings);
- if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) {
- /* Copy the connection to keep its secrets around even if NM
- * calls nm_connection_clear_secrets().
- */
- if (priv->secrets)
- g_object_unref (priv->secrets);
- priv->secrets = nm_connection_duplicate (NM_CONNECTION (self));
-
- if (signal_update) {
- nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self),
- ignore_cb,
- NULL);
- }
- success = TRUE;
- }
- g_hash_table_destroy (new_settings);
- return success;
-}
-
-/**************************************************************/
-
-static GValue *
-string_to_gvalue (const char *str)
-{
- GValue *val = g_slice_new0 (GValue);
-
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
- return val;
-}
-
-static GValue *
-byte_array_to_gvalue (const GByteArray *array)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
- g_value_set_boxed (val, array);
-
- return val;
-}
-
-static void
-copy_one_secret (gpointer key, gpointer value, gpointer user_data)
-{
- const char *value_str = (const char *) value;
-
- if (value_str) {
- g_hash_table_insert ((GHashTable *) user_data,
- g_strdup ((char *) key),
- string_to_gvalue (value_str));
- }
-}
-
-static void
-add_secrets (NMSetting *setting,
- const char *key,
- const GValue *value,
- GParamFlags flags,
- gpointer user_data)
-{
- GHashTable *secrets = user_data;
-
- if (!(flags & NM_SETTING_PARAM_SECRET))
- return;
-
- /* Copy secrets into the returned hash table */
- if (G_VALUE_HOLDS_STRING (value)) {
- const char *tmp;
-
- tmp = g_value_get_string (value);
- if (tmp)
- g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (tmp));
- } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) {
- /* Flatten the string hash by pulling its keys/values out */
- g_hash_table_foreach (g_value_get_boxed (value), copy_one_secret, secrets);
- } else if (G_VALUE_TYPE (value) == DBUS_TYPE_G_UCHAR_ARRAY) {
- GByteArray *array;
-
- array = g_value_get_boxed (value);
- if (array)
- g_hash_table_insert (secrets, g_strdup (key), byte_array_to_gvalue (array));
- }
-}
-
-static void
-destroy_gvalue (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static gboolean
-get_secrets (NMSettingsConnectionInterface *connection,
- const char *setting_name,
- const char **hints,
- gboolean request_new,
- NMSettingsConnectionInterfaceGetSecretsFunc callback,
- gpointer user_data)
-{
- NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (connection);
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- GHashTable *settings = NULL;
- GHashTable *secrets = NULL;
- NMSetting *setting;
- GError *error = NULL;
-
- /* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
- * will clear secrets on this object's settings. priv->secrets should be
- * a complete copy of this object and kept in sync by
- * nm_sysconfig_connection_update().
- */
- if (!priv->secrets) {
- error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
- "%s.%d - Internal error; secrets cache invalid.",
- __FILE__, __LINE__);
- (*callback) (connection, NULL, error, user_data);
- g_error_free (error);
- return TRUE;
- }
-
- setting = nm_connection_get_setting_by_name (priv->secrets, setting_name);
- if (!setting) {
- error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
- NM_SETTINGS_INTERFACE_ERROR_INVALID_SETTING,
- "%s.%d - Connection didn't have requested setting '%s'.",
- __FILE__, __LINE__, setting_name);
- (*callback) (connection, NULL, error, user_data);
- g_error_free (error);
- return TRUE;
- }
-
- /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
- * will contain all the individual settings hashes.
- */
- settings = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, (GDestroyNotify) g_hash_table_destroy);
-
- /* Add the secrets from this setting to the inner secrets hash for this setting */
- secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
- nm_setting_enumerate_values (setting, add_secrets, secrets);
-
- g_hash_table_insert (settings, g_strdup (setting_name), secrets);
- callback (connection, settings, NULL, user_data);
- g_hash_table_destroy (settings);
- return TRUE;
-}
-
-/**************************************************************/
-
-typedef struct {
- NMSysconfigConnection *self;
- DBusGMethodInvocation *context;
- PolkitSubject *subject;
- GCancellable *cancellable;
- gboolean disposed;
-
- /* Update */
- NMConnection *connection;
-
- /* Secrets */
- char *setting_name;
- char **hints;
- gboolean request_new;
-} PolkitCall;
-
-static PolkitCall *
-polkit_call_new (NMSysconfigConnection *self,
- DBusGMethodInvocation *context,
- NMConnection *connection,
- const char *setting_name,
- const char **hints,
- gboolean request_new)
-{
- PolkitCall *call;
- char *sender;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (context != NULL, NULL);
-
- call = g_malloc0 (sizeof (PolkitCall));
- call->self = self;
- call->context = context;
- call->cancellable = g_cancellable_new ();
- call->connection = connection;
- call->setting_name = g_strdup (setting_name);
- if (hints)
- call->hints = g_strdupv ((char **) hints);
- call->request_new = request_new;
-
- sender = dbus_g_method_get_sender (context);
- call->subject = polkit_system_bus_name_new (sender);
- g_free (sender);
-
- return call;
-}
-
-static void
-polkit_call_free (PolkitCall *call)
-{
- if (call->connection)
- g_object_unref (call->connection);
- g_free (call->setting_name);
- if (call->hints)
- g_strfreev (call->hints);
-
- g_object_unref (call->subject);
- g_object_unref (call->cancellable);
- g_free (call);
-}
-
-static void
-con_update_cb (NMSettingsConnectionInterface *connection,
- GError *error,
- gpointer user_data)
-{
- PolkitCall *call = user_data;
-
- if (error)
- dbus_g_method_return_error (call->context, error);
- else
- dbus_g_method_return (call->context);
-
- polkit_call_free (call);
-}
-
-static void
-pk_update_cb (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PolkitCall *call = user_data;
- NMSysconfigConnection *self = call->self;
- NMSysconfigConnectionPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL;
-
- /* If our NMSysconfigConnection is already gone, do nothing */
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
-
- priv->pk_calls = g_slist_remove (priv->pk_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- /* Caller didn't successfully authenticate */
- if (!polkit_authorization_result_get_is_authorized (pk_result)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Insufficient privileges.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- goto out;
- }
-
- /* Update our settings internally so the update() call will save the new
- * ones. We don't let nm_sysconfig_connection_update() handle the update
- * signal since we need our own callback after the update is done.
- */
- if (!nm_sysconfig_connection_update (self, call->connection, FALSE, &error)) {
- /* Shouldn't really happen since we've already validated the settings */
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- goto out;
- }
-
- /* Caller is authenticated, now we can finally try to commit the update */
- nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self),
- con_update_cb,
- call);
-
-out:
- g_object_unref (pk_result);
-}
-
-static void
-dbus_update (NMExportedConnection *exported,
- GHashTable *new_settings,
- DBusGMethodInvocation *context)
-{
- NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- PolkitCall *call;
- NMConnection *tmp;
- GError *error = NULL;
-
- /* Check if the settings are valid first */
- tmp = nm_connection_new_from_hash (new_settings, &error);
- if (!tmp) {
- g_assert (error);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- call = polkit_call_new (self, context, tmp, NULL, NULL, FALSE);
- g_assert (call);
- polkit_authority_check_authorization (priv->authority,
- call->subject,
- NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY,
- NULL,
- POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
- call->cancellable,
- pk_update_cb,
- call);
- priv->pk_calls = g_slist_prepend (priv->pk_calls, call);
-}
-
-static void
-con_delete_cb (NMSettingsConnectionInterface *connection,
- GError *error,
- gpointer user_data)
-{
- PolkitCall *call = user_data;
-
- if (error)
- dbus_g_method_return_error (call->context, error);
- else
- dbus_g_method_return (call->context);
-
- polkit_call_free (call);
-}
-
-static void
-pk_delete_cb (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PolkitCall *call = user_data;
- NMSysconfigConnection *self = call->self;
- NMSysconfigConnectionPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL;
-
- /* If our NMSysconfigConnection is already gone, do nothing */
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
-
- priv->pk_calls = g_slist_remove (priv->pk_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- /* Caller didn't successfully authenticate */
- if (!polkit_authorization_result_get_is_authorized (pk_result)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Insufficient privileges.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- goto out;
- }
-
- /* Caller is authenticated, now we can finally try to delete */
- nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (self),
- con_delete_cb,
- call);
-
-out:
- g_object_unref (pk_result);
-}
-
-static void
-dbus_delete (NMExportedConnection *exported,
- DBusGMethodInvocation *context)
-{
- NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- PolkitCall *call;
-
- call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE);
- g_assert (call);
- polkit_authority_check_authorization (priv->authority,
- call->subject,
- NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY,
- NULL,
- POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
- call->cancellable,
- pk_delete_cb,
- call);
- priv->pk_calls = g_slist_prepend (priv->pk_calls, call);
-}
-
-static void
-con_secrets_cb (NMSettingsConnectionInterface *connection,
- GHashTable *secrets,
- GError *error,
- gpointer user_data)
-{
- PolkitCall *call = user_data;
-
- if (error)
- dbus_g_method_return_error (call->context, error);
- else
- dbus_g_method_return (call->context, secrets);
-
- polkit_call_free (call);
-}
-
-static void
-pk_secrets_cb (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PolkitCall *call = user_data;
- NMSysconfigConnection *self = call->self;
- NMSysconfigConnectionPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL;
-
- /* If our NMSysconfigConnection is already gone, do nothing */
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
-
- priv->pk_calls = g_slist_remove (priv->pk_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- /* Caller didn't successfully authenticate */
- if (!polkit_authorization_result_get_is_authorized (pk_result)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Insufficient privileges.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- goto out;
- }
-
- /* Caller is authenticated, now we can finally try to update */
- nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (self),
- call->setting_name,
- (const char **) call->hints,
- call->request_new,
- con_secrets_cb,
- call);
-
-out:
- g_object_unref (pk_result);
-}
-
-static void
-dbus_get_secrets (NMExportedConnection *exported,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context)
-{
- NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- PolkitCall *call;
-
- call = polkit_call_new (self, context, NULL, setting_name, hints, request_new);
- g_assert (call);
- polkit_authority_check_authorization (priv->authority,
- call->subject,
- NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY,
- NULL,
- POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
- call->cancellable,
- pk_secrets_cb,
- call);
- priv->pk_calls = g_slist_prepend (priv->pk_calls, call);
-}
-
-/**************************************************************/
-
-static void
-settings_connection_interface_init (NMSettingsConnectionInterface *iface)
-{
- iface->get_secrets = get_secrets;
-}
-
-static void
-nm_sysconfig_connection_init (NMSysconfigConnection *self)
-{
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- GError *error = NULL;
-
- priv->authority = polkit_authority_get_sync (NULL, NULL);
- if (!priv->authority) {
- nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static void
-dispose (GObject *object)
-{
- NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (object);
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- GSList *iter;
-
- if (priv->secrets)
- g_object_unref (priv->secrets);
-
- /* Cancel PolicyKit requests */
- for (iter = priv->pk_calls; iter; iter = g_slist_next (iter)) {
- PolkitCall *call = iter->data;
-
- call->disposed = TRUE;
- g_cancellable_cancel (call->cancellable);
- }
- g_slist_free (priv->pk_calls);
- priv->pk_calls = NULL;
-
- G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object);
-}
-
-static void
-nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- NMExportedConnectionClass *ec_class = NM_EXPORTED_CONNECTION_CLASS (class);
-
- g_type_class_add_private (class, sizeof (NMSysconfigConnectionPrivate));
-
- /* Virtual methods */
- object_class->dispose = dispose;
- ec_class->update = dbus_update;
- ec_class->delete = dbus_delete;
- ec_class->get_secrets = dbus_get_secrets;
-}
diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h
deleted file mode 100644
index 0431dc95c..000000000
--- a/src/system-settings/nm-sysconfig-connection.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Novell, Inc.
- */
-
-#ifndef NM_SYSCONFIG_CONNECTION_H
-#define NM_SYSCONFIG_CONNECTION_H
-
-#include <nm-connection.h>
-#include <nm-exported-connection.h>
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_SYSCONFIG_CONNECTION (nm_sysconfig_connection_get_type ())
-#define NM_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnection))
-#define NM_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass))
-#define NM_IS_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION))
-#define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION))
-#define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass))
-
-typedef struct {
- NMExportedConnection parent;
-} NMSysconfigConnection;
-
-typedef struct {
- NMExportedConnectionClass parent;
-} NMSysconfigConnectionClass;
-
-GType nm_sysconfig_connection_get_type (void);
-
-/* Called by a system-settings plugin to update a connection is out of sync
- * with it's backing storage.
- */
-gboolean nm_sysconfig_connection_update (NMSysconfigConnection *self,
- NMConnection *new_settings,
- gboolean signal_update,
- GError **error);
-
-G_END_DECLS
-
-#endif /* NM_SYSCONFIG_CONNECTION_H */
diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c
deleted file mode 100644
index 1a1fc6fd8..000000000
--- a/src/system-settings/nm-sysconfig-settings.c
+++ /dev/null
@@ -1,1596 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * Søren Sandmann <sandmann@daimi.au.dk>
- * Dan Williams <dcbw@redhat.com>
- * Tambet Ingo <tambet@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2007 - 2011 Red Hat, Inc.
- * (C) Copyright 2008 Novell, Inc.
- */
-
-#include <unistd.h>
-#include <string.h>
-#include <gmodule.h>
-#include <net/ethernet.h>
-#include <netinet/ether.h>
-
-#include <NetworkManager.h>
-#include <nm-connection.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <nm-settings-system-interface.h>
-
-#include <nm-setting-8021x.h>
-#include <nm-setting-bluetooth.h>
-#include <nm-setting-cdma.h>
-#include <nm-setting-connection.h>
-#include <nm-setting-gsm.h>
-#include <nm-setting-ip4-config.h>
-#include <nm-setting-ip6-config.h>
-#include <nm-setting-olpc-mesh.h>
-#include <nm-setting-ppp.h>
-#include <nm-setting-pppoe.h>
-#include <nm-setting-serial.h>
-#include <nm-setting-vpn.h>
-#include <nm-setting-wired.h>
-#include <nm-setting-wireless.h>
-#include <nm-setting-wireless-security.h>
-
-#include "../nm-device-ethernet.h"
-#include "nm-dbus-glib-types.h"
-#include "nm-sysconfig-settings.h"
-#include "nm-sysconfig-connection.h"
-#include "nm-polkit-helpers.h"
-#include "nm-system-config-error.h"
-#include "nm-default-wired-connection.h"
-#include "nm-logging.h"
-
-#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
-
-/* LINKER CRACKROCK */
-#define EXPORT(sym) void * __export_##sym = &sym;
-
-#include "nm-inotify-helper.h"
-EXPORT(nm_inotify_helper_get_type)
-EXPORT(nm_inotify_helper_get)
-EXPORT(nm_inotify_helper_add_watch)
-EXPORT(nm_inotify_helper_remove_watch)
-
-EXPORT(nm_sysconfig_connection_get_type)
-EXPORT(nm_sysconfig_connection_update)
-/* END LINKER CRACKROCK */
-
-static void claim_connection (NMSysconfigSettings *self,
- NMSettingsConnectionInterface *connection,
- gboolean do_export);
-
-static void impl_settings_save_hostname (NMSysconfigSettings *self,
- const char *hostname,
- DBusGMethodInvocation *context);
-
-static void impl_settings_get_permissions (NMSysconfigSettings *self,
- DBusGMethodInvocation *context);
-
-#include "nm-settings-system-glue.h"
-
-static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
-
-typedef struct {
- PolkitAuthority *authority;
- guint auth_changed_id;
- char *config_file;
-
- GSList *pk_calls;
- GSList *permissions_calls;
-
- GSList *plugins;
- gboolean connections_loaded;
- GHashTable *connections;
- GSList *unmanaged_specs;
-} NMSysconfigSettingsPrivate;
-
-static void settings_system_interface_init (NMSettingsSystemInterface *klass);
-
-G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS_SERVICE,
- G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE,
- settings_system_interface_init))
-
-#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate))
-
-enum {
- PROPERTIES_CHANGED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-enum {
- PROP_0,
- PROP_UNMANAGED_SPECS,
-
- LAST_PROP
-};
-
-static void
-load_connections (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
-
- if (priv->connections_loaded)
- return;
-
- for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
- NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
- GSList *plugin_connections;
- GSList *elt;
-
- plugin_connections = nm_system_config_interface_get_connections (plugin);
-
- // FIXME: ensure connections from plugins loaded with a lower priority
- // get rejected when they conflict with connections from a higher
- // priority plugin.
-
- for (elt = plugin_connections; elt; elt = g_slist_next (elt))
- claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (elt->data), TRUE);
-
- g_slist_free (plugin_connections);
- }
-
- priv->connections_loaded = TRUE;
-
- /* FIXME: Bad hack */
- unmanaged_specs_changed (NULL, self);
-}
-
-static GSList *
-list_connections (NMSettingsService *settings)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings);
- GHashTableIter iter;
- gpointer key;
- GSList *list = NULL;
-
- load_connections (NM_SYSCONFIG_SETTINGS (settings));
-
- g_hash_table_iter_init (&iter, priv->connections);
- while (g_hash_table_iter_next (&iter, &key, NULL))
- list = g_slist_prepend (list, NM_EXPORTED_CONNECTION (key));
- return g_slist_reverse (list);
-}
-
-static void
-clear_unmanaged_specs (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL);
- g_slist_free (priv->unmanaged_specs);
- priv->unmanaged_specs = NULL;
-}
-
-static char*
-uscore_to_wincaps (const char *uscore)
-{
- const char *p;
- GString *str;
- gboolean last_was_uscore;
-
- last_was_uscore = TRUE;
-
- str = g_string_new (NULL);
- p = uscore;
- while (p && *p) {
- if (*p == '-' || *p == '_')
- last_was_uscore = TRUE;
- else {
- if (last_was_uscore) {
- g_string_append_c (str, g_ascii_toupper (*p));
- last_was_uscore = FALSE;
- } else
- g_string_append_c (str, *p);
- }
- ++p;
- }
-
- return g_string_free (str, FALSE);
-}
-
-static void
-notify (GObject *object, GParamSpec *pspec)
-{
- GValue *value;
- GHashTable *hash;
-
- value = g_slice_new0 (GValue);
- hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
-
- g_value_init (value, pspec->value_type);
- g_object_get_property (object, pspec->name, value);
- g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value);
- g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash);
- g_hash_table_destroy (hash);
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-const GSList *
-nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- load_connections (self);
- return priv->unmanaged_specs;
-}
-
-static NMSystemConfigInterface *
-get_plugin (NMSysconfigSettings *self, guint32 capability)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
-
- g_return_val_if_fail (self != NULL, NULL);
-
- /* Do any of the plugins support setting the hostname? */
- for (iter = priv->plugins; iter; iter = iter->next) {
- NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
-
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
- if (caps & capability)
- return NM_SYSTEM_CONFIG_INTERFACE (iter->data);
- }
-
- return NULL;
-}
-
-/* Returns an allocated string which the caller owns and must eventually free */
-char *
-nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
- char *hostname = NULL;
-
- /* Hostname returned is the hostname returned from the first plugin
- * that provides one.
- */
- for (iter = priv->plugins; iter; iter = iter->next) {
- NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
-
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
- if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, &hostname, NULL);
- if (hostname && strlen (hostname))
- return hostname;
- g_free (hostname);
- }
- }
-
- return NULL;
-}
-
-static void
-plugin_connection_added (NMSystemConfigInterface *config,
- NMSettingsConnectionInterface *connection,
- gpointer user_data)
-{
- claim_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE);
-}
-
-static gboolean
-find_unmanaged_device (NMSysconfigSettings *self, const char *needle)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
-
- for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) {
- if (!strcmp ((const char *) iter->data, needle))
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-unmanaged_specs_changed (NMSystemConfigInterface *config,
- gpointer user_data)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
-
- clear_unmanaged_specs (self);
-
- /* Ask all the plugins for their unmanaged specs */
- for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
- GSList *specs, *specs_iter;
-
- specs = nm_system_config_interface_get_unmanaged_specs (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
- for (specs_iter = specs; specs_iter; specs_iter = specs_iter->next) {
- if (!find_unmanaged_device (self, (const char *) specs_iter->data)) {
- priv->unmanaged_specs = g_slist_prepend (priv->unmanaged_specs, specs_iter->data);
- } else
- g_free (specs_iter->data);
- }
-
- g_slist_free (specs);
- }
-
- g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS);
-}
-
-static void
-hostname_changed (NMSystemConfigInterface *config,
- GParamSpec *pspec,
- gpointer user_data)
-{
- g_object_notify (G_OBJECT (user_data), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
-}
-
-static void
-add_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *plugin)
-{
- NMSysconfigSettingsPrivate *priv;
- char *pname = NULL;
- char *pinfo = NULL;
-
- g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
-
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
-
- g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
- G_CALLBACK (plugin_connection_added), self);
- g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
-
- nm_system_config_interface_init (plugin, NULL);
-
- g_object_get (G_OBJECT (plugin),
- NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
- NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo,
- NULL);
-
- g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
- G_CALLBACK (unmanaged_specs_changed), self);
-
- nm_log_info (LOGD_SYS_SET, "Loaded plugin %s: %s", pname, pinfo);
- g_free (pname);
- g_free (pinfo);
-}
-
-static GObject *
-find_plugin (GSList *list, const char *pname)
-{
- GSList *iter;
- GObject *obj = NULL;
-
- g_return_val_if_fail (pname != NULL, FALSE);
-
- for (iter = list; iter && !obj; iter = g_slist_next (iter)) {
- NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
- char *list_pname = NULL;
-
- g_object_get (G_OBJECT (plugin),
- NM_SYSTEM_CONFIG_INTERFACE_NAME,
- &list_pname,
- NULL);
- if (list_pname && !strcmp (pname, list_pname))
- obj = G_OBJECT (plugin);
-
- g_free (list_pname);
- }
-
- return obj;
-}
-
-static gboolean
-load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error)
-{
- GSList *list = NULL;
- char **plist;
- char **iter;
- gboolean success = TRUE;
-
- plist = g_strsplit (plugins, ",", 0);
- if (!plist)
- return FALSE;
-
- for (iter = plist; *iter; iter++) {
- GModule *plugin;
- char *full_name, *path;
- const char *pname = g_strstrip (*iter);
- GObject *obj;
- GObject * (*factory_func) (void);
-
- /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */
- if (!strcmp (pname, "ifcfg-fedora"))
- pname = "ifcfg-rh";
-
- obj = find_plugin (list, pname);
- if (obj)
- continue;
-
- full_name = g_strdup_printf ("nm-settings-plugin-%s", pname);
- path = g_module_build_path (PLUGINDIR, full_name);
-
- plugin = g_module_open (path, G_MODULE_BIND_LOCAL);
- if (!plugin) {
- g_set_error (error, 0, 0,
- "Could not load plugin '%s': %s",
- pname, g_module_error ());
- g_free (full_name);
- g_free (path);
- success = FALSE;
- break;
- }
-
- g_free (full_name);
- g_free (path);
-
- if (!g_module_symbol (plugin, "nm_system_config_factory", (gpointer) (&factory_func))) {
- g_set_error (error, 0, 0,
- "Could not find plugin '%s' factory function.",
- pname);
- success = FALSE;
- break;
- }
-
- obj = (*factory_func) ();
- if (!obj || !NM_IS_SYSTEM_CONFIG_INTERFACE (obj)) {
- g_set_error (error, 0, 0,
- "Plugin '%s' returned invalid system config object.",
- pname);
- success = FALSE;
- break;
- }
-
- g_module_make_resident (plugin);
- g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
- add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (obj));
- list = g_slist_append (list, obj);
- }
-
- g_strfreev (plist);
-
- g_slist_foreach (list, (GFunc) g_object_unref, NULL);
- g_slist_free (list);
-
- return success;
-}
-
-static void
-connection_removed (NMSettingsConnectionInterface *connection,
- gpointer user_data)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
- NMSettingConnection *s_con;
- GKeyFile *timestamps_file;
- const char *connection_uuid;
- char *data;
- gsize len;
- GError *error = NULL;
-
- /* Remove connection from the table */
- g_hash_table_remove (priv->connections, connection);
-
- /* Remove timestamp from timestamps database file */
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
- connection_uuid = nm_setting_connection_get_uuid (s_con);
-
- timestamps_file = g_key_file_new ();
- if (g_key_file_load_from_file (timestamps_file, NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL)) {
- g_key_file_remove_key (timestamps_file, "timestamps", connection_uuid, NULL);
- data = g_key_file_to_data (timestamps_file, &len, &error);
- if (data) {
- g_file_set_contents (NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, data, len, &error);
- g_free (data);
- }
- if (error) {
- nm_log_warn (LOGD_SYS_SET, "error writing timestamps file '%s': %s", NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, error->message);
- g_error_free (error);
- }
- }
- g_key_file_free (timestamps_file);
-}
-
-static void
-claim_connection (NMSysconfigSettings *self,
- NMSettingsConnectionInterface *connection,
- gboolean do_export)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- NMSettingConnection *s_con;
- const char *connection_uuid;
- guint64 timestamp = 0;
- GKeyFile *timestamps_file;
- GError *err = NULL;
- char *tmp_str;
-
- g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
-
- if (g_hash_table_lookup (priv->connections, connection))
- /* A plugin is lying to us. */
- return;
-
- /* Read timestamp from database file and store it into connection's object data */
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION));
- g_assert (s_con);
- connection_uuid = nm_setting_connection_get_uuid (s_con);
-
- timestamps_file = g_key_file_new ();
- g_key_file_load_from_file (timestamps_file, NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE, G_KEY_FILE_KEEP_COMMENTS, NULL);
- tmp_str = g_key_file_get_value (timestamps_file, "timestamps", connection_uuid, &err);
- if (tmp_str) {
- timestamp = g_ascii_strtoull (tmp_str, NULL, 10);
- g_free (tmp_str);
- }
-
- /* Update connection's timestamp */
- if (!err) {
- guint64 *ts_ptr = g_new (guint64, 1);
-
- *ts_ptr = timestamp;
- g_object_set_data_full (G_OBJECT (connection), NM_SYSCONFIG_SETTINGS_TIMESTAMP_TAG, ts_ptr, g_free);
- } else {
- nm_log_dbg (LOGD_SYS_SET, "failed to read connection timestamp for '%s': (%d) %s",
- connection_uuid, err->code, err->message);
- g_clear_error (&err);
- }
- g_key_file_free (timestamps_file);
-
- g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1));
- g_signal_connect (connection,
- NM_SETTINGS_CONNECTION_INTERFACE_REMOVED,
- G_CALLBACK (connection_removed),
- self);
-
- if (do_export) {
- nm_settings_service_export_connection (NM_SETTINGS_SERVICE (self), connection);
- g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, connection);
- }
-}
-
-static void
-remove_connection (NMSysconfigSettings *self,
- NMSettingsConnectionInterface *connection,
- gboolean do_signal)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
-
- if (g_hash_table_lookup (priv->connections, connection)) {
- g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
- g_hash_table_remove (priv->connections, connection);
- }
-}
-
-typedef struct {
- NMSysconfigSettings *self;
- DBusGMethodInvocation *context;
- PolkitSubject *subject;
- GCancellable *cancellable;
- gboolean disposed;
-
- NMConnection *connection;
- NMSettingsAddConnectionFunc callback;
- gpointer callback_data;
-
- char *hostname;
-
- NMSettingsSystemPermissions permissions;
- guint32 permissions_calls;
-} PolkitCall;
-
-#include "nm-dbus-manager.h"
-
-static PolkitCall *
-polkit_call_new (NMSysconfigSettings *self,
- DBusGMethodInvocation *context,
- NMConnection *connection,
- NMSettingsAddConnectionFunc callback,
- gpointer callback_data,
- const char *hostname)
-{
- PolkitCall *call;
- char *sender;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (context != NULL, NULL);
-
- call = g_malloc0 (sizeof (PolkitCall));
- call->self = self;
- call->cancellable = g_cancellable_new ();
- call->context = context;
- if (connection)
- call->connection = g_object_ref (connection);
- if (callback) {
- call->callback = callback;
- call->callback_data = callback_data;
- }
- if (hostname)
- call->hostname = g_strdup (hostname);
-
- sender = dbus_g_method_get_sender (context);
- call->subject = polkit_system_bus_name_new (sender);
- g_free (sender);
-
- return call;
-}
-
-static void
-polkit_call_free (PolkitCall *call)
-{
- if (call->connection)
- g_object_unref (call->connection);
- g_object_unref (call->cancellable);
- g_free (call->hostname);
- g_object_unref (call->subject);
- g_free (call);
-}
-
-static gboolean
-add_new_connection (NMSysconfigSettings *self,
- NMConnection *connection,
- GError **error)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GError *tmp_error = NULL, *last_error = NULL;
- GSList *iter;
- gboolean success = FALSE;
-
- /* Here's how it works:
- 1) plugin writes a connection.
- 2) plugin notices that a new connection is available for reading.
- 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal.
- 4) NMSysconfigSettings receives the signal and adds it to it's connection list.
- */
-
- for (iter = priv->plugins; iter && !success; iter = iter->next) {
- success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data),
- connection,
- &tmp_error);
- g_clear_error (&last_error);
- if (!success) {
- last_error = tmp_error;
- tmp_error = NULL;
- }
- }
-
- if (!success)
- *error = last_error;
- return success;
-}
-
-static void
-pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PolkitCall *call = user_data;
- NMSysconfigSettings *self = call->self;
- NMSysconfigSettingsPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL, *add_error = NULL;
-
- /* If NMSysconfigSettings is already gone, do nothing */
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- priv->pk_calls = g_slist_remove (priv->pk_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data);
- goto out;
- }
-
- /* Caller didn't successfully authenticate */
- if (!polkit_authorization_result_get_is_authorized (pk_result)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Insufficient privileges.");
- call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data);
- goto out;
- }
-
- if (add_new_connection (self, call->connection, &add_error))
- call->callback (NM_SETTINGS_INTERFACE (self), NULL, call->callback_data);
- else {
- error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED,
- "Saving connection failed: (%d) %s",
- add_error ? add_error->code : -1,
- (add_error && add_error->message) ? add_error->message : "(unknown)");
- g_error_free (add_error);
- call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data);
- }
-
-out:
- g_clear_error (&error);
- polkit_call_free (call);
- if (pk_result)
- g_object_unref (pk_result);
-}
-
-static void
-add_connection (NMSettingsService *service,
- NMConnection *connection,
- DBusGMethodInvocation *context, /* Only present for D-Bus calls */
- NMSettingsAddConnectionFunc callback,
- gpointer user_data)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (service);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- PolkitCall *call;
- GError *error = NULL;
-
- /* Do any of the plugins support adding? */
- if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
- "None of the registered plugins support add.");
- callback (NM_SETTINGS_INTERFACE (service), error, user_data);
- g_error_free (error);
- return;
- }
-
- call = polkit_call_new (self, context, connection, callback, user_data, NULL);
- g_assert (call);
- polkit_authority_check_authorization (priv->authority,
- call->subject,
- NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY,
- NULL,
- POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
- call->cancellable,
- pk_add_cb,
- call);
- priv->pk_calls = g_slist_append (priv->pk_calls, call);
-}
-
-static void
-pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PolkitCall *call = user_data;
- NMSysconfigSettings *self = call->self;
- NMSysconfigSettingsPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL;
- GSList *iter;
- gboolean success = FALSE;
-
- /* If our NMSysconfigConnection is already gone, do nothing */
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (call->context, error);
- g_error_free (error);
- polkit_call_free (call);
- return;
- }
-
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- priv->pk_calls = g_slist_remove (priv->pk_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- dbus_g_method_return_error (call->context, error);
- goto out;
- }
-
- /* Caller didn't successfully authenticate */
- if (!polkit_authorization_result_get_is_authorized (pk_result)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Insufficient privileges.");
- dbus_g_method_return_error (call->context, error);
- goto out;
- }
-
- /* Set the hostname in all plugins */
- for (iter = priv->plugins; iter; iter = iter->next) {
- NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE;
-
- g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
- if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
- g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, call->hostname, NULL);
- success = TRUE;
- }
- }
-
- if (success) {
- dbus_g_method_return (call->context);
- } else {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
- "Saving the hostname failed.");
- dbus_g_method_return_error (call->context, error);
- }
-
-out:
- g_clear_error (&error);
- polkit_call_free (call);
- if (pk_result)
- g_object_unref (pk_result);
-}
-
-static void
-impl_settings_save_hostname (NMSysconfigSettings *self,
- const char *hostname,
- DBusGMethodInvocation *context)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- PolkitCall *call;
- GError *error = NULL;
-
- /* Do any of the plugins support setting the hostname? */
- if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
- "None of the registered plugins support setting the hostname.");
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- call = polkit_call_new (self, context, NULL, NULL, NULL, hostname);
- g_assert (call);
- polkit_authority_check_authorization (priv->authority,
- call->subject,
- NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY,
- NULL,
- POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
- call->cancellable,
- pk_hostname_cb,
- call);
- priv->pk_calls = g_slist_append (priv->pk_calls, call);
-}
-
-static void
-pk_authority_changed_cb (GObject *object, gpointer user_data)
-{
- /* Let clients know they should re-check their authorization */
- g_signal_emit_by_name (NM_SYSCONFIG_SETTINGS (user_data),
- NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS);
-}
-
-typedef struct {
- PolkitCall *pk_call;
- const char *pk_action;
- GCancellable *cancellable;
- NMSettingsSystemPermissions permission;
- gboolean disposed;
-} PermissionsCall;
-
-static void
-permission_call_done (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- PermissionsCall *call = user_data;
- PolkitCall *pk_call = call->pk_call;
- NMSysconfigSettings *self = pk_call->self;
- NMSysconfigSettingsPrivate *priv;
- PolkitAuthorizationResult *pk_result;
- GError *error = NULL;
-
- /* If NMSysconfigSettings is gone, just skip to the end */
- if (call->disposed)
- goto done;
-
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- priv->permissions_calls = g_slist_remove (priv->permissions_calls, call);
-
- pk_result = polkit_authority_check_authorization_finish (priv->authority,
- result,
- &error);
- /* Some random error happened */
- if (error) {
- nm_log_err (LOGD_SYS_SET, "error checking '%s' permission: (%d) %s",
- call->pk_action,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- if (error)
- g_error_free (error);
- } else {
- /* If the caller is authorized, or the caller could authorize via a
- * challenge, then authorization is possible. Otherwise, caller is out of
- * luck.
- */
- if ( polkit_authorization_result_get_is_authorized (pk_result)
- || polkit_authorization_result_get_is_challenge (pk_result))
- pk_call->permissions |= call->permission;
- }
-
- g_object_unref (pk_result);
-
-done:
- pk_call->permissions_calls--;
- if (pk_call->permissions_calls == 0) {
- if (call->disposed) {
- error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Request was canceled.");
- dbus_g_method_return_error (pk_call->context, error);
- g_error_free (error);
- } else {
- /* All the permissions calls are done, return the full permissions
- * bitfield back to the user.
- */
- dbus_g_method_return (pk_call->context, pk_call->permissions);
- }
-
- polkit_call_free (pk_call);
- }
- memset (call, 0, sizeof (PermissionsCall));
- g_free (call);
-}
-
-static void
-start_permission_check (NMSysconfigSettings *self,
- PolkitCall *pk_call,
- const char *pk_action,
- NMSettingsSystemPermissions permission)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- PermissionsCall *call;
-
- g_return_if_fail (pk_call != NULL);
- g_return_if_fail (pk_action != NULL);
- g_return_if_fail (permission != NM_SETTINGS_SYSTEM_PERMISSION_NONE);
-
- call = g_malloc0 (sizeof (PermissionsCall));
- call->pk_call = pk_call;
- call->pk_action = pk_action;
- call->permission = permission;
- call->cancellable = g_cancellable_new ();
-
- pk_call->permissions_calls++;
-
- polkit_authority_check_authorization (priv->authority,
- pk_call->subject,
- pk_action,
- NULL,
- 0,
- call->cancellable,
- permission_call_done,
- call);
- priv->permissions_calls = g_slist_append (priv->permissions_calls, call);
-}
-
-static void
-impl_settings_get_permissions (NMSysconfigSettings *self,
- DBusGMethodInvocation *context)
-{
- PolkitCall *call;
-
- call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE);
- g_assert (call);
-
- /* Start checks for the various permissions */
-
- /* Only check for connection-modify if one of our plugins supports it. */
- if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
- start_permission_check (self, call,
- NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY,
- NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY);
- }
-
- /* Only check for hostname-modify if one of our plugins supports it. */
- if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
- start_permission_check (self, call,
- NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY,
- NM_SETTINGS_SYSTEM_PERMISSION_HOSTNAME_MODIFY);
- }
-
- // FIXME: hook these into plugin permissions like the modify permissions */
- start_permission_check (self, call,
- NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN,
- NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_OPEN);
- start_permission_check (self, call,
- NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED,
- NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_PROTECTED);
-}
-
-static gboolean
-get_permissions (NMSettingsSystemInterface *settings,
- NMSettingsSystemGetPermissionsFunc callback,
- gpointer user_data)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings);
- NMSettingsSystemPermissions permissions = NM_SETTINGS_SYSTEM_PERMISSION_NONE;
-
- /* Local caller (ie, NM) gets full permissions by default because it doesn't
- * need authorization. However, permissions are still subject to plugin's
- * restrictions. i.e. if no plugins support connection-modify, then even
- * the local caller won't get that permission.
- */
-
- /* Only check for connection-modify if one of our plugins supports it. */
- if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
- permissions |= NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY;
-
- /* Only check for hostname-modify if one of our plugins supports it. */
- if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME))
- permissions |= NM_SETTINGS_SYSTEM_PERMISSION_HOSTNAME_MODIFY;
-
- // FIXME: hook these into plugin permissions like the modify permissions */
- permissions |= NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_OPEN;
- permissions |= NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_PROTECTED;
-
- callback (settings, permissions, NULL, user_data);
- return TRUE;
-}
-
-static gboolean
-have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GHashTableIter iter;
- gpointer key;
- NMSettingConnection *s_con;
- NMSettingWired *s_wired;
- const GByteArray *setting_mac;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE);
- g_return_val_if_fail (mac != NULL, FALSE);
-
- /* Find a wired connection locked to the given MAC address, if any */
- g_hash_table_iter_init (&iter, priv->connections);
- while (g_hash_table_iter_next (&iter, &key, NULL)) {
- NMConnection *connection = NM_CONNECTION (key);
- const char *connection_type;
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- connection_type = nm_setting_connection_get_connection_type (s_con);
-
- if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME)
- && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
- continue;
-
- s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
-
- /* No wired setting; therefore the PPPoE connection applies to any device */
- if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) {
- ret = TRUE;
- break;
- }
-
- setting_mac = nm_setting_wired_get_mac_address (s_wired);
- if (setting_mac) {
- /* A connection mac-locked to this device */
- if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) {
- ret = TRUE;
- break;
- }
- } else {
- /* A connection that applies to any wired device */
- ret = TRUE;
- break;
- }
- }
-
- return ret;
-}
-
-/* Search through the list of blacklisted MAC addresses in the config file. */
-static gboolean
-is_mac_auto_wired_blacklisted (NMSysconfigSettings *self, const GByteArray *mac)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GKeyFile *config;
- char **list, **iter;
- gboolean found = FALSE;
-
- g_return_val_if_fail (mac != NULL, FALSE);
-
- if (!priv->config_file)
- return FALSE;
-
- config = g_key_file_new ();
- if (!config) {
- nm_log_warn (LOGD_SYS_SET, "not enough memory to load config file.");
- return FALSE;
- }
-
- g_key_file_set_list_separator (config, ',');
- if (!g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_NONE, NULL))
- goto out;
-
- list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL);
- for (iter = list; iter && *iter; iter++) {
- struct ether_addr *candidate;
-
- if (strcmp(g_strstrip(*iter), "*") == 0) {
- found = TRUE;
- break;
- }
-
- candidate = ether_aton (*iter);
- if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
- found = TRUE;
- break;
- }
- }
-
- if (list)
- g_strfreev (list);
-
-out:
- g_key_file_free (config);
- return found;
-}
-
-#define DEFAULT_WIRED_TAG "default-wired"
-
-static void
-default_wired_deleted (NMDefaultWiredConnection *wired,
- const GByteArray *mac,
- NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- NMSettingConnection *s_con;
- char *tmp;
- GKeyFile *config;
- char **list, **iter, **updated;
- gboolean found = FALSE;
- gsize len = 0, i;
- char *data;
-
- /* If there was no config file specified, there's nothing to do */
- if (!priv->config_file)
- goto cleanup;
-
- /* When the default wired connection is removed (either deleted or saved
- * to a new persistent connection by a plugin), write the MAC address of
- * the wired device to the config file and don't create a new default wired
- * connection for that device again.
- */
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
- NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
-
- /* Ignore removals of read-only connections, since they couldn't have
- * been removed by the user.
- */
- if (nm_setting_connection_get_read_only (s_con))
- goto cleanup;
-
- config = g_key_file_new ();
- if (!config)
- goto cleanup;
-
- g_key_file_set_list_separator (config, ',');
- g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL);
-
- list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL);
- for (iter = list; iter && *iter; iter++) {
- struct ether_addr *candidate;
-
- if (strcmp(g_strstrip(*iter), "*") == 0) {
- found = TRUE;
- break;
- }
-
- candidate = ether_aton (*iter);
- if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) {
- found = TRUE;
- break;
- }
- }
-
- /* Add this device's MAC to the list */
- if (!found) {
- tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
- mac->data[0], mac->data[1], mac->data[2],
- mac->data[3], mac->data[4], mac->data[5]);
-
- /* New list; size + 1 for the new element, + 1 again for ending NULL */
- updated = g_malloc0 (sizeof (char*) * (len + 2));
-
- /* Copy original list and add new MAC */
- for (i = 0; list && list[i]; i++)
- updated[i] = list[i];
- updated[i++] = tmp;
- updated[i] = NULL;
-
- g_key_file_set_string_list (config,
- "main", CONFIG_KEY_NO_AUTO_DEFAULT,
- (const char **) updated,
- len + 2);
- /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */
- g_free (updated);
- g_free (tmp);
-
- data = g_key_file_to_data (config, &len, NULL);
- if (data) {
- g_file_set_contents (priv->config_file, data, len, NULL);
- g_free (data);
- }
- }
-
- if (list)
- g_strfreev (list);
- g_key_file_free (config);
-
-cleanup:
- g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
- DEFAULT_WIRED_TAG,
- NULL);
-}
-
-static void
-delete_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer user_data)
-{
-}
-
-static gboolean
-default_wired_try_update (NMDefaultWiredConnection *wired,
- NMSysconfigSettings *self)
-{
- GError *error = NULL;
- NMSettingConnection *s_con;
- const char *id;
-
- /* Try to move this default wired conneciton to a plugin so that it has
- * persistent storage.
- */
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
- NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- id = nm_setting_connection_get_id (s_con);
- g_assert (id);
-
- remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE);
- if (add_new_connection (self, NM_CONNECTION (wired), &error)) {
- nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (wired),
- delete_cb,
- NULL);
-
- g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
- DEFAULT_WIRED_TAG,
- NULL);
- nm_log_info (LOGD_SYS_SET, "Saved default wired connection '%s' to persistent storage", id);
- return FALSE;
- }
-
- nm_log_warn (LOGD_SYS_SET, "couldn't save default wired connection '%s': %d / %s",
- id,
- error ? error->code : -1,
- (error && error->message) ? error->message : "(unknown)");
-
- /* If there was an error, don't destroy the default wired connection,
- * but add it back to the system settings service. Connection is already
- * exported on the bus, don't export it again, thus do_export == FALSE.
- */
- claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE);
- return TRUE;
-}
-
-void
-nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device)
-{
- GByteArray *mac = NULL;
- struct ether_addr tmp;
- NMDefaultWiredConnection *wired;
- NMSettingConnection *s_con;
- gboolean read_only = TRUE;
- const char *id;
-
- if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
- return;
-
- /* If the device isn't managed or it already has a default wired connection,
- * ignore it.
- */
- if ( !nm_device_get_managed (device)
- || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG))
- return;
-
- nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp);
-
- mac = g_byte_array_sized_new (ETH_ALEN);
- g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN);
-
- if ( have_connection_for_device (self, mac)
- || is_mac_auto_wired_blacklisted (self, mac))
- goto ignore;
-
- if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
- read_only = FALSE;
-
- wired = nm_default_wired_connection_new (mac, device, read_only);
- if (!wired)
- goto ignore;
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
- NM_TYPE_SETTING_CONNECTION);
- g_assert (s_con);
- id = nm_setting_connection_get_id (s_con);
- g_assert (id);
-
- nm_log_info (LOGD_SYS_SET, "Added default wired connection '%s' for %s",
- id, nm_device_get_udi (device));
-
- g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self);
- g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self);
- claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), TRUE);
- g_object_unref (wired);
-
- g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired);
-
-ignore:
- g_byte_array_free (mac, TRUE);
-}
-
-void
-nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device)
-{
- NMDefaultWiredConnection *connection;
-
- if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
- return;
-
- connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
- if (connection)
- remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (connection), TRUE);
-}
-
-NMSysconfigSettings *
-nm_sysconfig_settings_new (const char *config_file,
- const char *plugins,
- DBusGConnection *bus,
- GError **error)
-{
- NMSysconfigSettings *self;
- NMSysconfigSettingsPrivate *priv;
-
- self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS,
- NM_SETTINGS_SERVICE_BUS, bus,
- NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_SYSTEM,
- NULL);
- if (!self)
- return NULL;
-
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- priv->config_file = g_strdup (config_file);
-
- if (plugins) {
- /* Load the plugins; fail if a plugin is not found. */
- if (!load_plugins (self, plugins, error)) {
- g_object_unref (self);
- return NULL;
- }
- unmanaged_specs_changed (NULL, self);
- }
-
- return self;
-}
-
-/***************************************************************/
-
-static void
-dispose (GObject *object)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *iter;
-
- if (priv->auth_changed_id) {
- g_signal_handler_disconnect (priv->authority, priv->auth_changed_id);
- priv->auth_changed_id = 0;
- }
-
- /* Cancel PolicyKit requests */
- for (iter = priv->pk_calls; iter; iter = g_slist_next (iter)) {
- PolkitCall *call = iter->data;
-
- call->disposed = TRUE;
- g_cancellable_cancel (call->cancellable);
- }
- g_slist_free (priv->pk_calls);
- priv->pk_calls = NULL;
-
- /* Cancel PolicyKit permissions requests */
- for (iter = priv->permissions_calls; iter; iter = g_slist_next (iter)) {
- PermissionsCall *call = iter->data;
-
- call->disposed = TRUE;
- g_cancellable_cancel (call->cancellable);
- }
- g_slist_free (priv->permissions_calls);
- priv->permissions_calls = NULL;
-
- G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- g_hash_table_destroy (priv->connections);
-
- clear_unmanaged_specs (self);
-
- g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
- g_slist_free (priv->plugins);
-
- g_free (priv->config_file);
-
- G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
-}
-
-static void
-settings_system_interface_init (NMSettingsSystemInterface *iface)
-{
- iface->get_permissions = get_permissions;
-
- dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface),
- &dbus_glib_nm_settings_system_object_info);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
- const GSList *specs, *iter;
- GSList *copy = NULL;
-
- switch (prop_id) {
- case PROP_UNMANAGED_SPECS:
- specs = nm_sysconfig_settings_get_unmanaged_specs (self);
- for (iter = specs; iter; iter = g_slist_next (iter))
- copy = g_slist_append (copy, g_strdup (iter->data));
- g_value_take_boxed (value, copy);
- break;
- case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME:
- g_value_take_string (value, nm_sysconfig_settings_get_hostname (self));
-
- /* Don't ever pass NULL through D-Bus */
- if (!g_value_get_string (value))
- g_value_set_static_string (value, "");
- break;
- case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY:
- g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- NMSettingsServiceClass *ss_class = NM_SETTINGS_SERVICE_CLASS (class);
-
- g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate));
-
- /* virtual methods */
- object_class->notify = notify;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = finalize;
- ss_class->list_connections = list_connections;
- ss_class->add_connection = add_connection;
-
- /* properties */
- g_object_class_install_property
- (object_class, PROP_UNMANAGED_SPECS,
- g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
- "Unamanged device specs",
- "Unmanaged device specs",
- DBUS_TYPE_G_LIST_OF_STRING,
- G_PARAM_READABLE));
-
- g_object_class_override_property (object_class,
- NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME,
- NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
-
- g_object_class_override_property (object_class,
- NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY,
- NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY);
-
- /* signals */
- signals[PROPERTIES_CHANGED] =
- g_signal_new ("properties-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
-
- dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_DBUS_IFACE_SETTINGS_SYSTEM,
- NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
-
- dbus_g_error_domain_register (NM_SETTINGS_INTERFACE_ERROR,
- NM_DBUS_IFACE_SETTINGS,
- NM_TYPE_SETTINGS_INTERFACE_ERROR);
-
- /* And register all the settings errors with D-Bus */
- dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR);
- dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR);
- dbus_g_error_domain_register (NM_SETTING_BLUETOOTH_ERROR, NULL, NM_TYPE_SETTING_BLUETOOTH_ERROR);
- dbus_g_error_domain_register (NM_SETTING_CDMA_ERROR, NULL, NM_TYPE_SETTING_CDMA_ERROR);
- dbus_g_error_domain_register (NM_SETTING_CONNECTION_ERROR, NULL, NM_TYPE_SETTING_CONNECTION_ERROR);
- dbus_g_error_domain_register (NM_SETTING_GSM_ERROR, NULL, NM_TYPE_SETTING_GSM_ERROR);
- dbus_g_error_domain_register (NM_SETTING_IP4_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP4_CONFIG_ERROR);
- dbus_g_error_domain_register (NM_SETTING_IP6_CONFIG_ERROR, NULL, NM_TYPE_SETTING_IP6_CONFIG_ERROR);
- dbus_g_error_domain_register (NM_SETTING_OLPC_MESH_ERROR, NULL, NM_TYPE_SETTING_OLPC_MESH_ERROR);
- dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR);
- dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR);
- dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR);
- dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR);
- dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR);
- dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR);
- dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR);
- dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR);
-}
-
-static void
-nm_sysconfig_settings_init (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GError *error = NULL;
-
- priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
-
- priv->authority = polkit_authority_get_sync (NULL, &error);
- if (priv->authority) {
- priv->auth_changed_id = g_signal_connect (priv->authority,
- "changed",
- G_CALLBACK (pk_authority_changed_cb),
- self);
- } else {
- nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h
deleted file mode 100644
index 8b2622a74..000000000
--- a/src/system-settings/nm-sysconfig-settings.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * Søren Sandmann <sandmann@daimi.au.dk>
- * Dan Williams <dcbw@redhat.com>
- * Tambet Ingo <tambet@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2007 - 2009 Red Hat, Inc.
- * (C) Copyright 2008 Novell, Inc.
- */
-
-#ifndef __NM_SYSCONFIG_SETTINGS_H__
-#define __NM_SYSCONFIG_SETTINGS_H__
-
-#include <nm-connection.h>
-#include <nm-settings-service.h>
-
-#include "nm-sysconfig-connection.h"
-#include "nm-system-config-interface.h"
-#include "nm-device.h"
-
-#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ())
-#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings))
-#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
-#define NM_IS_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_SETTINGS))
-#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS))
-#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
-
-#define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
-#define NM_SYSCONFIG_SETTINGS_TIMESTAMPS_FILE LOCALSTATEDIR"/lib/NetworkManager/timestamps"
-#define NM_SYSCONFIG_SETTINGS_TIMESTAMP_TAG "timestamp-tag"
-
-typedef struct {
- NMSettingsService parent_instance;
-} NMSysconfigSettings;
-
-typedef struct {
- NMSettingsServiceClass parent_class;
-
- /* Signals */
- void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties);
-} NMSysconfigSettingsClass;
-
-GType nm_sysconfig_settings_get_type (void);
-
-NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file,
- const char *plugins,
- DBusGConnection *bus,
- GError **error);
-
-const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self);
-
-char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self);
-
-void nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device);
-
-void nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device);
-
-#endif /* __NM_SYSCONFIG_SETTINGS_H__ */
diff --git a/src/system-settings/nm-system-config-error.c b/src/system-settings/nm-system-config-error.c
deleted file mode 100644
index 13d47462f..000000000
--- a/src/system-settings/nm-system-config-error.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#include "nm-system-config-error.h"
-
-GQuark
-nm_sysconfig_settings_error_quark (void)
-{
- static GQuark ret = 0;
-
- if (ret == 0)
- ret = g_quark_from_static_string ("nm_sysconfig_settings_error");
-
- return ret;
-}
-
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
-
-GType
-nm_sysconfig_settings_error_get_type (void)
-{
- static GType etype = 0;
-
- if (etype == 0) {
- static const GEnumValue values[] = {
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, "AddFailed"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"),
- ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"),
- { 0, 0, 0 }
- };
-
- etype = g_enum_register_static ("NMSysconfigSettingsError", values);
- }
-
- return etype;
-}
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 62612a0e1..296668aa9 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -6,7 +6,10 @@ INCLUDES = \
-I$(top_srcdir)/src \
-I$(top_builddir)/src
-noinst_PROGRAMS = test-dhcp-options test-policy-hosts
+noinst_PROGRAMS = \
+ test-dhcp-options \
+ test-policy-hosts \
+ test-wifi-ap-utils
####### DHCP options test #######
@@ -39,11 +42,33 @@ test_policy_hosts_LDADD = \
$(top_builddir)/src/libtest-policy-hosts.la \
$(GLIB_LIBS)
+####### wifi ap utils test #######
+
+test_wifi_ap_utils_SOURCES = \
+ test-wifi-ap-utils.c
+
+test_wifi_ap_utils_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS)
+
+test_wifi_ap_utils_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/libtest-wifi-ap-utils.la \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS)
+
+####### secret agent interface test #######
+
+EXTRA_DIST = test-secret-agent.py
+
+###########################################
+
if WITH_TESTS
-check-local: test-dhcp-options
+check-local: test-dhcp-options test-policy-hosts test-wifi-ap-utils
$(abs_builddir)/test-dhcp-options
$(abs_builddir)/test-policy-hosts
+ $(abs_builddir)/test-wifi-ap-utils
endif
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 1b9c08337..f702ac860 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -35,16 +35,21 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = test-dhcp-options$(EXEEXT) \
- test-policy-hosts$(EXEEXT)
+ test-policy-hosts$(EXEEXT) test-wifi-ap-utils$(EXEEXT)
subdir = src/tests
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -70,8 +75,15 @@ test_policy_hosts_OBJECTS = $(am_test_policy_hosts_OBJECTS)
test_policy_hosts_DEPENDENCIES = \
$(top_builddir)/src/libtest-policy-hosts.la \
$(am__DEPENDENCIES_1)
+am_test_wifi_ap_utils_OBJECTS = \
+ test_wifi_ap_utils-test-wifi-ap-utils.$(OBJEXT)
+test_wifi_ap_utils_OBJECTS = $(am_test_wifi_ap_utils_OBJECTS)
+test_wifi_ap_utils_DEPENDENCIES = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/libtest-wifi-ap-utils.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -96,14 +108,14 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
-SOURCES = $(test_dhcp_options_SOURCES) $(test_policy_hosts_SOURCES)
+SOURCES = $(test_dhcp_options_SOURCES) $(test_policy_hosts_SOURCES) \
+ $(test_wifi_ap_utils_SOURCES)
DIST_SOURCES = $(test_dhcp_options_SOURCES) \
- $(test_policy_hosts_SOURCES)
+ $(test_policy_hosts_SOURCES) $(test_wifi_ap_utils_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -112,8 +124,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -130,6 +140,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -138,6 +149,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -146,8 +158,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -162,13 +174,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -176,6 +198,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -184,13 +208,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -216,12 +242,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -236,10 +259,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -327,6 +353,24 @@ test_policy_hosts_LDADD = \
$(top_builddir)/src/libtest-policy-hosts.la \
$(GLIB_LIBS)
+
+####### wifi ap utils test #######
+test_wifi_ap_utils_SOURCES = \
+ test-wifi-ap-utils.c
+
+test_wifi_ap_utils_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(DBUS_CFLAGS)
+
+test_wifi_ap_utils_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/libtest-wifi-ap-utils.la \
+ $(GLIB_LIBS) \
+ $(DBUS_LIBS)
+
+
+####### secret agent interface test #######
+EXTRA_DIST = test-secret-agent.py
all: all-am
.SUFFIXES:
@@ -376,6 +420,9 @@ test-dhcp-options$(EXEEXT): $(test_dhcp_options_OBJECTS) $(test_dhcp_options_DEP
test-policy-hosts$(EXEEXT): $(test_policy_hosts_OBJECTS) $(test_policy_hosts_DEPENDENCIES)
@rm -f test-policy-hosts$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_policy_hosts_OBJECTS) $(test_policy_hosts_LDADD) $(LIBS)
+test-wifi-ap-utils$(EXEEXT): $(test_wifi_ap_utils_OBJECTS) $(test_wifi_ap_utils_DEPENDENCIES)
+ @rm -f test-wifi-ap-utils$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_wifi_ap_utils_OBJECTS) $(test_wifi_ap_utils_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -385,6 +432,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dhcp_options-test-dhcp-options.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_policy_hosts-test-policy-hosts.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -445,6 +493,22 @@ test_policy_hosts-test-policy-hosts.obj: test-policy-hosts.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_policy_hosts_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_policy_hosts-test-policy-hosts.obj `if test -f 'test-policy-hosts.c'; then $(CYGPATH_W) 'test-policy-hosts.c'; else $(CYGPATH_W) '$(srcdir)/test-policy-hosts.c'; fi`
+test_wifi_ap_utils-test-wifi-ap-utils.o: test-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wifi_ap_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wifi_ap_utils-test-wifi-ap-utils.o -MD -MP -MF $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Tpo -c -o test_wifi_ap_utils-test-wifi-ap-utils.o `test -f 'test-wifi-ap-utils.c' || echo '$(srcdir)/'`test-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Tpo $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wifi-ap-utils.c' object='test_wifi_ap_utils-test-wifi-ap-utils.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wifi_ap_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wifi_ap_utils-test-wifi-ap-utils.o `test -f 'test-wifi-ap-utils.c' || echo '$(srcdir)/'`test-wifi-ap-utils.c
+
+test_wifi_ap_utils-test-wifi-ap-utils.obj: test-wifi-ap-utils.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wifi_ap_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_wifi_ap_utils-test-wifi-ap-utils.obj -MD -MP -MF $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Tpo -c -o test_wifi_ap_utils-test-wifi-ap-utils.obj `if test -f 'test-wifi-ap-utils.c'; then $(CYGPATH_W) 'test-wifi-ap-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-wifi-ap-utils.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Tpo $(DEPDIR)/test_wifi_ap_utils-test-wifi-ap-utils.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-wifi-ap-utils.c' object='test_wifi_ap_utils-test-wifi-ap-utils.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_wifi_ap_utils_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_wifi_ap_utils-test-wifi-ap-utils.obj `if test -f 'test-wifi-ap-utils.c'; then $(CYGPATH_W) 'test-wifi-ap-utils.c'; else $(CYGPATH_W) '$(srcdir)/test-wifi-ap-utils.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -652,9 +716,12 @@ uninstall-am:
tags uninstall uninstall-am
-@WITH_TESTS_TRUE@check-local: test-dhcp-options
+###########################################
+
+@WITH_TESTS_TRUE@check-local: test-dhcp-options test-policy-hosts test-wifi-ap-utils
@WITH_TESTS_TRUE@ $(abs_builddir)/test-dhcp-options
@WITH_TESTS_TRUE@ $(abs_builddir)/test-policy-hosts
+@WITH_TESTS_TRUE@ $(abs_builddir)/test-wifi-ap-utils
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/tests/test-policy-hosts.c b/src/tests/test-policy-hosts.c
index 62862e756..681758900 100644
--- a/src/tests/test-policy-hosts.c
+++ b/src/tests/test-policy-hosts.c
@@ -23,7 +23,7 @@
#include "nm-policy-hosts.h"
-#define DEBUG 1
+#define DEBUG 0
static void
test_generic (const char *before, const char *after)
diff --git a/src/tests/test-secret-agent.py b/src/tests/test-secret-agent.py
new file mode 100755
index 000000000..3b21c610a
--- /dev/null
+++ b/src/tests/test-secret-agent.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+
+import glib
+import gobject
+import sys
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+IFACE_SECRET_AGENT = 'org.freedesktop.NetworkManager.SecretAgent'
+IFACE_AGENT_MANAGER = 'org.freedesktop.NetworkManager.AgentManager'
+
+class NotAuthorizedException(dbus.DBusException):
+ _dbus_error_name = IFACE_SECRET_AGENT + '.NotAuthorized'
+
+class Agent(dbus.service.Object):
+ def __init__(self, bus, object_path):
+ self.agents = {}
+ self.bus = bus
+ dbus.service.Object.__init__(self, bus, object_path)
+
+ @dbus.service.method(IFACE_SECRET_AGENT,
+ in_signature='a{sa{sv}}osasb',
+ out_signature='a{sa{sv}}',
+ sender_keyword='sender')
+ def GetSecrets(self, connection_hash, connection_path, setting_name, hints, request_new, sender=None):
+ if not sender:
+ raise NotAuthorizedException("Internal error: couldn't get sender")
+ uid = self.bus.get_unix_user(sender)
+ if uid != 0:
+ raise NotAuthorizedException("UID %d not authorized" % uid)
+
+ print "Secrets requested path '%s' setting '%s' hints '%s' new %d" % (connection_path, setting_name, str(hints), request_new)
+
+ # return some random GSM secrets
+ s_gsm = dbus.Dictionary({'password': 'asdfadfasdfaf'})
+ con = dbus.Dictionary({'gsm': s_gsm})
+ return con
+
+def register(proxy):
+ proxy.Register("test.agent.id", dbus_interface=IFACE_AGENT_MANAGER)
+ print "Registered!"
+ return False
+
+def unregister(proxy, loop):
+ proxy.Unregister(dbus_interface=IFACE_AGENT_MANAGER)
+ loop.quit()
+ return False
+
+def main():
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+ bus = dbus.SystemBus()
+ obj = Agent(bus, "/org/freedesktop/NetworkManager/SecretAgent")
+ proxy = bus.get_object("org.freedesktop.NetworkManager",
+ "/org/freedesktop/NetworkManager/AgentManager")
+
+ mainloop = gobject.MainLoop()
+
+ gobject.idle_add(register, proxy)
+ print "Running test secret agent"
+
+ try:
+ mainloop.run()
+ except KeyboardInterrupt, e:
+ pass
+
+ print "Unregistering..."
+ unregister(proxy, mainloop);
+
+if __name__ == '__main__':
+ main()
+
diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c
new file mode 100644
index 000000000..deb31f3f5
--- /dev/null
+++ b/src/tests/test-wifi-ap-utils.c
@@ -0,0 +1,1432 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2011 Red Hat, Inc.
+ *
+ */
+
+#include <glib.h>
+#include <string.h>
+
+#include "nm-wifi-ap-utils.h"
+#include "nm-dbus-glib-types.h"
+
+#include "nm-setting-connection.h"
+#include "nm-setting-wireless.h"
+#include "nm-setting-wireless-security.h"
+#include "nm-setting-8021x.h"
+
+#define DEBUG 1
+
+/*******************************************/
+
+#define COMPARE(src, expected, success, error, edomain, ecode) \
+{ \
+ if (expected) { \
+ if (!success) { \
+ g_assert (error != NULL); \
+ g_warning ("Failed to complete connection: (%d) %s", error->code, error->message); \
+ } \
+ g_assert (success == TRUE); \
+ g_assert (error == NULL); \
+\
+ success = nm_connection_compare (src, expected, NM_SETTING_COMPARE_FLAG_EXACT); \
+ if (success == FALSE && DEBUG) { \
+ g_message ("\n- COMPLETED ---------------------------------\n"); \
+ nm_connection_dump (src); \
+ g_message ("+ EXPECTED ++++++++++++++++++++++++++++++++++++\n"); \
+ nm_connection_dump (expected); \
+ g_message ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); \
+ } \
+ g_assert (success == TRUE); \
+ } else { \
+ if (success) { \
+ g_message ("\n- COMPLETED ---------------------------------\n"); \
+ nm_connection_dump (src); \
+ } \
+ g_assert (success == FALSE); \
+ g_assert_error (error, edomain, ecode); \
+ } \
+ \
+ g_clear_error (&error); \
+}
+
+static gboolean
+complete_connection (const char *ssid,
+ const guint8 bssid[ETH_ALEN],
+ NM80211Mode mode,
+ guint32 flags,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ gboolean lock_bssid,
+ NMConnection *src,
+ GError **error)
+{
+ GByteArray *tmp;
+ gboolean success;
+
+ tmp = g_byte_array_sized_new (strlen (ssid));
+ g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid));
+
+ success = nm_ap_utils_complete_connection (tmp,
+ bssid,
+ mode,
+ flags,
+ wpa_flags,
+ rsn_flags,
+ src,
+ lock_bssid,
+ error);
+ g_byte_array_free (tmp, TRUE);
+ return success;
+}
+
+typedef struct {
+ const char *key;
+ const char *str;
+ guint32 uint;
+} KeyData;
+
+static void
+set_items (NMSetting *setting, const KeyData *items)
+{
+ const KeyData *item;
+ GParamSpec *pspec;
+ GByteArray *tmp;
+
+ for (item = items; item && item->key; item++) {
+ g_assert (item->key);
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), item->key);
+ g_assert (pspec);
+
+ if (pspec->value_type == G_TYPE_STRING) {
+ g_assert (item->uint == 0);
+ if (item->str)
+ g_object_set (G_OBJECT (setting), item->key, item->str, NULL);
+ } else if (pspec->value_type == G_TYPE_UINT) {
+ g_assert (item->str == NULL);
+ g_object_set (G_OBJECT (setting), item->key, item->uint, NULL);
+ } else if (pspec->value_type == G_TYPE_INT) {
+ gint foo = (gint) item->uint;
+
+ g_assert (item->str == NULL);
+ g_object_set (G_OBJECT (setting), item->key, foo, NULL);
+ } else if (pspec->value_type == G_TYPE_BOOLEAN) {
+ gboolean foo = !! (item->uint);
+
+ g_assert (item->str == NULL);
+ g_object_set (G_OBJECT (setting), item->key, foo, NULL);
+ } else if (pspec->value_type == DBUS_TYPE_G_UCHAR_ARRAY) {
+ g_assert (item->str);
+ tmp = g_byte_array_sized_new (strlen (item->str));
+ g_byte_array_append (tmp, (const guint8 *) item->str, strlen (item->str));
+ g_object_set (G_OBJECT (setting), item->key, tmp, NULL);
+ g_byte_array_free (tmp, TRUE);
+ } else {
+ /* Special types, check based on property name */
+ if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO))
+ nm_setting_wireless_security_add_proto (NM_SETTING_WIRELESS_SECURITY (setting), item->str);
+ else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PAIRWISE))
+ nm_setting_wireless_security_add_pairwise (NM_SETTING_WIRELESS_SECURITY (setting), item->str);
+ else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_GROUP))
+ nm_setting_wireless_security_add_group (NM_SETTING_WIRELESS_SECURITY (setting), item->str);
+ else if (!strcmp (item->key, NM_SETTING_802_1X_EAP))
+ nm_setting_802_1x_add_eap_method (NM_SETTING_802_1X (setting), item->str);
+ }
+ }
+}
+
+static NMSettingWireless *
+fill_wifi_empty (NMConnection *connection)
+{
+ NMSettingWireless *s_wifi;
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ if (!s_wifi) {
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+ }
+ return s_wifi;
+}
+
+static NMSettingWireless *
+fill_wifi (NMConnection *connection, const KeyData items[])
+{
+ NMSettingWireless *s_wifi;
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
+ if (!s_wifi) {
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+ }
+
+ set_items (NM_SETTING (s_wifi), items);
+ return s_wifi;
+}
+
+static NMSettingWirelessSecurity *
+fill_wsec (NMConnection *connection, const KeyData items[])
+{
+ NMSettingWirelessSecurity *s_wsec;
+
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ if (!s_wsec) {
+ s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wsec));
+ }
+
+ set_items (NM_SETTING (s_wsec), items);
+ return s_wsec;
+}
+
+static NMSetting8021x *
+fill_8021x (NMConnection *connection, const KeyData items[])
+{
+ NMSetting8021x *s_8021x;
+
+ s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+ if (!s_8021x) {
+ s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+ }
+
+ set_items (NM_SETTING (s_8021x), items);
+ return s_8021x;
+}
+
+static NMConnection *
+create_basic (const char *ssid,
+ const guint8 *bssid,
+ NM80211Mode mode,
+ gboolean set_security)
+{
+ NMConnection *connection;
+ NMSettingWireless *s_wifi = NULL;
+ GByteArray *tmp;
+
+ connection = nm_connection_new ();
+
+ s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wifi));
+
+ /* SSID */
+ tmp = g_byte_array_sized_new (strlen (ssid));
+ g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid));
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL);
+ g_byte_array_free (tmp, TRUE);
+
+ /* BSSID */
+ if (bssid) {
+ tmp = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (tmp, bssid, ETH_ALEN);
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, tmp, NULL);
+ g_byte_array_free (tmp, TRUE);
+ }
+
+ if (mode == NM_802_11_MODE_INFRA)
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
+ else if (mode == NM_802_11_MODE_ADHOC)
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL);
+ else
+ g_assert_not_reached ();
+
+ if (set_security)
+ g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+
+ return connection;
+}
+
+/*******************************************/
+
+static void
+test_lock_bssid (void)
+{
+ NMConnection *src, *expected;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *ssid = "blahblah";
+ gboolean success;
+ GError *error = NULL;
+
+ src = nm_connection_new ();
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ TRUE,
+ src, &error);
+ expected = create_basic (ssid, bssid, NM_802_11_MODE_INFRA, FALSE);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+ g_object_unref (expected);
+}
+
+/*******************************************/
+
+static void
+test_open_ap_empty_connection (void)
+{
+ NMConnection *src, *expected;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *ssid = "blahblah";
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an empty source connection is correctly filled with the
+ * SSID and Infra modes of the given AP details.
+ */
+
+ src = nm_connection_new ();
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, FALSE);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+ g_object_unref (expected);
+}
+
+/*******************************************/
+
+static void
+test_open_ap_leap_connection_1 (gboolean add_wifi)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0 }, { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that a basic connection filled with a LEAP username is
+ * rejected when completion is attempted with an open AP. LEAP requires
+ * the AP to have the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ if (add_wifi)
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* We expect failure */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_open_ap_leap_connection_2 (void)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that a basic connection specifying IEEE8021x security (ie, Dynamic
+ * WEP or LEAP) is rejected when completion is attempted with an open AP.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* We expect failure */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_open_ap_wep_connection (gboolean add_wifi)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that a static WEP connection is rejected when completion is
+ * attempted with an open AP.
+ */
+
+ src = nm_connection_new ();
+ if (add_wifi)
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* We expect failure */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_ap_wpa_psk_connection_base (const char *key_mgmt,
+ const char *auth_alg,
+ guint32 flags,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ gboolean add_wifi,
+ NMConnection *expected)
+{
+ NMConnection *src;
+ const char *ssid = "blahblah";
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData exp_wifi[] = {
+ { NM_SETTING_WIRELESS_SSID, ssid, 0 },
+ { NM_SETTING_WIRELESS_MODE, "infrastructure", 0 },
+ { NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 0 },
+ { NULL } };
+ const KeyData both_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 },
+ { NM_SETTING_WIRELESS_SECURITY_PSK, "asdfasdfasdfasdfasdfafs", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ src = nm_connection_new ();
+ if (add_wifi)
+ fill_wifi_empty (src);
+ fill_wsec (src, both_wsec);
+ success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA,
+ flags, wpa_flags, rsn_flags,
+ FALSE, src, &error);
+ if (expected) {
+ fill_wifi (expected, exp_wifi);
+ fill_wsec (expected, both_wsec);
+ }
+ COMPARE (src, expected, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+static void
+test_open_ap_wpa_psk_connection_1 (void)
+{
+ /* Test that a WPA-PSK connection filling only the PSK itself and *not*
+ * filling the wifi setting is rejected when completion is attempted with
+ * an open AP.
+ */
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_open_ap_wpa_psk_connection_2 (void)
+{
+ /* Test that a WPA-PSK connection filling only the PSK itself and also
+ * filling the wifi setting is rejected when completion is attempted with
+ * an open AP.
+ */
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ TRUE, NULL);
+}
+
+static void
+test_open_ap_wpa_psk_connection_3 (void)
+{
+ /* Test that a WPA-PSK connection filling the PSK and setting the auth alg
+ * to 'open' is rejected when completion is attempted with an open AP.
+ */
+ test_ap_wpa_psk_connection_base (NULL, "open",
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_open_ap_wpa_psk_connection_4 (void)
+{
+ /* Test that a WPA-PSK connection filling the PSK and setting the auth alg
+ * to 'shared' is rejected when completion is attempted with an open AP.
+ * Shared auth cannot be used with WPA.
+ */
+ test_ap_wpa_psk_connection_base (NULL, "shared",
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_open_ap_wpa_psk_connection_5 (void)
+{
+ /* Test that a WPA-PSK connection filling the PSK, the auth algorithm, and
+ * key management is rejected when completion is attempted with an open AP.
+ */
+ test_ap_wpa_psk_connection_base ("wpa-psk", "open",
+ NM_802_11_AP_FLAGS_NONE,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+/*******************************************/
+
+static void
+test_ap_wpa_eap_connection_base (const char *key_mgmt,
+ const char *auth_alg,
+ guint32 flags,
+ guint32 wpa_flags,
+ guint32 rsn_flags,
+ gboolean add_wifi,
+ guint error_domain,
+ guint error_code)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_empty[] = { { NULL } };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ src = nm_connection_new ();
+ if (add_wifi)
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ fill_8021x (src, src_empty);
+ success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA,
+ flags, wpa_flags, rsn_flags,
+ FALSE, src, &error);
+ /* Failure expected */
+ COMPARE (src, NULL, success, error, error_domain, error_code);
+
+ g_object_unref (src);
+}
+
+enum {
+ IDX_NONE = 0,
+ IDX_OPEN,
+ IDX_PRIV,
+ IDX_WPA_PSK_PTKIP_GTKIP,
+ IDX_WPA_PSK_PTKIP_PCCMP_GTKIP,
+ IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP,
+ IDX_WPA_RSN_PSK_PCCMP_GCCMP,
+ IDX_RSN_PSK_PCCMP_GCCMP,
+ IDX_RSN_PSK_PTKIP_PCCMP_GTKIP,
+ IDX_WPA_8021X,
+ IDX_RSN_8021X,
+};
+
+static guint32
+flags_for_idx (guint32 idx)
+{
+ if (idx == IDX_OPEN)
+ return NM_802_11_AP_FLAGS_NONE;
+ else if ( idx == IDX_PRIV
+ || idx == IDX_WPA_PSK_PTKIP_GTKIP
+ || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_RSN_PSK_PCCMP_GCCMP
+ || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP
+ || idx == IDX_WPA_8021X
+ || idx == IDX_RSN_8021X)
+ return NM_802_11_AP_FLAGS_PRIVACY;
+ else
+ g_assert_not_reached ();
+}
+
+static guint32
+wpa_flags_for_idx (guint32 idx)
+{
+ if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_RSN_8021X
+ || idx == IDX_RSN_PSK_PCCMP_GCCMP || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP)
+ return NM_802_11_AP_SEC_NONE;
+ else if (idx == IDX_WPA_PSK_PTKIP_GTKIP)
+ return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP)
+ return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (IDX_WPA_RSN_PSK_PCCMP_GCCMP)
+ return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_WPA_8021X)
+ return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_802_1X;
+ else
+ g_assert_not_reached ();
+}
+
+static guint32
+rsn_flags_for_idx (guint32 idx)
+{
+ if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_WPA_8021X
+ || idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP)
+ return NM_802_11_AP_SEC_NONE;
+ else if (idx == IDX_RSN_PSK_PCCMP_GCCMP)
+ return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP)
+ return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP)
+ return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP)
+ return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK;
+ else if (idx == IDX_RSN_8021X)
+ return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_802_1X;
+ else
+ g_assert_not_reached ();
+}
+
+static guint32
+error_domain_for_idx (guint32 idx, guint num)
+{
+ if (idx == IDX_OPEN)
+ return NM_SETTING_WIRELESS_SECURITY_ERROR;
+ else if (idx == IDX_PRIV) {
+ if (num <= 3)
+ return NM_SETTING_802_1X_ERROR;
+ else
+ return NM_SETTING_WIRELESS_SECURITY_ERROR;
+ } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP)
+ return NM_SETTING_WIRELESS_SECURITY_ERROR;
+ else
+ g_assert_not_reached ();
+}
+
+static guint32
+error_code_for_idx (guint32 idx, guint num)
+{
+ if (idx == IDX_OPEN)
+ return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY;
+ else if (idx == IDX_PRIV) {
+ if (num <= 3)
+ return NM_SETTING_802_1X_ERROR_MISSING_PROPERTY;
+ else
+ return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY;
+ } else if (idx == IDX_WPA_PSK_PTKIP_GTKIP || idx == IDX_WPA_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_WPA_RSN_PSK_PCCMP_GCCMP || idx == IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP
+ || idx == IDX_RSN_PSK_PTKIP_PCCMP_GTKIP || idx == IDX_RSN_PSK_PCCMP_GCCMP)
+ return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY;
+ else
+ g_assert_not_reached ();
+}
+
+static void
+test_ap_wpa_eap_connection_1 (guint32 idx)
+{
+ test_ap_wpa_eap_connection_base (NULL, NULL,
+ flags_for_idx (idx),
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ error_domain_for_idx (idx, 1),
+ error_code_for_idx (idx, 1));
+}
+
+static void
+test_ap_wpa_eap_connection_2 (guint idx)
+{
+ test_ap_wpa_eap_connection_base (NULL, NULL,
+ flags_for_idx (idx),
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ TRUE,
+ error_domain_for_idx (idx, 2),
+ error_code_for_idx (idx, 2));
+}
+
+static void
+test_ap_wpa_eap_connection_3 (guint idx)
+{
+ test_ap_wpa_eap_connection_base (NULL, "open",
+ flags_for_idx (idx),
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ error_domain_for_idx (idx, 3),
+ error_code_for_idx (idx, 3));
+}
+
+static void
+test_ap_wpa_eap_connection_4 (guint idx)
+{
+ test_ap_wpa_eap_connection_base (NULL, "shared",
+ flags_for_idx (idx),
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ error_domain_for_idx (idx, 4),
+ error_code_for_idx (idx, 4));
+}
+
+static void
+test_ap_wpa_eap_connection_5 (guint idx)
+{
+ test_ap_wpa_eap_connection_base ("wpa-eap", "open",
+ flags_for_idx (idx),
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ error_domain_for_idx (idx, 5),
+ error_code_for_idx (idx, 5));
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_empty_connection (void)
+{
+ NMConnection *src, *expected;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *ssid = "blahblah";
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an empty connection is completed to a valid Static WEP
+ * connection when completed with an AP with the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+
+ /* Static WEP connection expected */
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE);
+ fill_wsec (expected, exp_wsec);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+ g_object_unref (expected);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_leap_connection_1 (gboolean add_wifi)
+{
+ NMConnection *src, *expected;
+ const char *ssid = "blahblah";
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *leap_username = "Bill Smith";
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 },
+ { NULL } };
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an minimal LEAP connection specifying only key management and
+ * the LEAP username is completed to a full LEAP connection when completed
+ * with an AP with the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ if (add_wifi)
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* We expect success here; since LEAP APs just set the 'privacy' flag
+ * there's no way to determine from the AP's beacon whether it's static WEP,
+ * dynamic WEP, or LEAP.
+ */
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE);
+ fill_wsec (expected, exp_wsec);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_leap_connection_2 (void)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an minimal LEAP connection specifying only key management and
+ * the LEAP auth alg is completed to a full LEAP connection when completed
+ * with an AP with the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* We expect failure here, we need a LEAP username */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_dynamic_wep_1 (void)
+{
+ NMConnection *src, *expected;
+ const char *ssid = "blahblah";
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+ const KeyData both_8021x[] = {
+ { NM_SETTING_802_1X_EAP, "peap", 0 },
+ { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 },
+ { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 },
+ { NULL } };
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep40", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep104", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep40", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep104", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an minimal Dynamic WEP connection specifying key management,
+ * the auth algorithm, and valid 802.1x setting is completed to a valid
+ * Dynamic WEP connection when completed with an AP with the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ fill_8021x (src, both_8021x);
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+
+ /* We expect a completed Dynamic WEP connection */
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE);
+ fill_wsec (expected, exp_wsec);
+ fill_8021x (expected, both_8021x);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_dynamic_wep_2 (void)
+{
+ NMConnection *src, *expected;
+ const char *ssid = "blahblah";
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+ const KeyData both_8021x[] = {
+ { NM_SETTING_802_1X_EAP, "peap", 0 },
+ { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 },
+ { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 },
+ { NULL } };
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep40", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep104", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep40", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep104", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that an minimal Dynamic WEP connection specifying only the auth
+ * algorithm and a valid 802.1x setting is completed to a valid Dynamic
+ * WEP connection when completed with an AP with the Privacy bit set.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ fill_8021x (src, both_8021x);
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+
+ /* We expect a completed Dynamic WEP connection */
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE);
+ fill_wsec (expected, exp_wsec);
+ fill_8021x (expected, both_8021x);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_dynamic_wep_3 (void)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0 },
+ { NULL } };
+ const KeyData src_8021x[] = {
+ { NM_SETTING_802_1X_EAP, "peap", 0 },
+ { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 },
+ { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Ensure that a basic connection specifying 'shared' auth and an 802.1x
+ * setting is rejected, as 802.1x is incompatible with 'shared' auth.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ fill_8021x (src, src_8021x);
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE,
+ FALSE,
+ src, &error);
+ /* Expect failure; shared is not compatible with dynamic WEP */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_priv_ap_wpa_psk_connection_1 (void)
+{
+ /* Test that a basic WPA-PSK connection is rejected when completion is
+ * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN
+ * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA.
+ */
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_priv_ap_wpa_psk_connection_2 (void)
+{
+ /* Test that a basic WPA-PSK connection is rejected when completion is
+ * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN
+ * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA.
+ */
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ TRUE, NULL);
+}
+
+static void
+test_priv_ap_wpa_psk_connection_3 (void)
+{
+ /* Test that a basic WPA-PSK connection specifying only the auth algorithm
+ * is rejected when completion is attempted with an AP with just the Privacy
+ * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP
+ * or LEAP, not WPA.
+ */
+ test_ap_wpa_psk_connection_base (NULL, "open",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_priv_ap_wpa_psk_connection_4 (void)
+{
+ /* Test that a basic WPA-PSK connection specifying only the auth algorithm
+ * is rejected when completion is attempted with an AP with just the Privacy
+ * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP
+ * or LEAP, not WPA. Second, 'shared' auth is incompatible with WPA.
+ */
+ test_ap_wpa_psk_connection_base (NULL, "shared",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+static void
+test_priv_ap_wpa_psk_connection_5 (void)
+{
+ /* Test that a WPA-PSK connection specifying both the key management and
+ * auth algorithm is rejected when completion is attempted with an AP with
+ * just the Privacy bit set. Lack of WPA/RSN flags means the AP provides
+ * Static/Dynamic WEP or LEAP, not WPA.
+ */
+ test_ap_wpa_psk_connection_base ("wpa-psk", "open",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ NM_802_11_AP_SEC_NONE,
+ NM_802_11_AP_SEC_NONE,
+ FALSE, NULL);
+}
+
+/*******************************************/
+
+static void
+test_wpa_ap_empty_connection (guint idx)
+{
+ NMConnection *src, *expected;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *ssid = "blahblah";
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that a basic WPA-PSK connection specifying just key management and
+ * the auth algorithm is completed successfully when given an AP with WPA
+ * or RSN flags.
+ */
+
+ src = nm_connection_new ();
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE, src, &error);
+
+ /* WPA connection expected */
+ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE);
+ fill_wsec (expected, exp_wsec);
+ COMPARE (src, expected, success, error, 0, 0);
+
+ g_object_unref (src);
+ g_object_unref (expected);
+}
+
+/*******************************************/
+
+static void
+test_wpa_ap_leap_connection_1 (guint idx)
+{
+ NMConnection *src;
+ const char *ssid = "blahblah";
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const char *leap_username = "Bill Smith";
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that completion of a LEAP connection with a WPA-enabled AP is
+ * rejected since WPA APs (usually) do not support LEAP.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection (ssid, bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ src, &error);
+ /* Expect failure here; WPA APs don't support old-school LEAP */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_wpa_ap_leap_connection_2 (guint idx)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that completion of a LEAP connection with a WPA-enabled AP is
+ * rejected since WPA APs (usually) do not support LEAP.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ src, &error);
+ /* We expect failure here, we need a LEAP username */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_wpa_ap_dynamic_wep_connection (guint idx)
+{
+ NMConnection *src;
+ const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ const KeyData src_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 },
+ { NULL } };
+ gboolean success;
+ GError *error = NULL;
+
+ /* Test that completion of a Dynamic WEP connection with a WPA-enabled AP is
+ * rejected since WPA APs (usually) do not support Dynamic WEP.
+ */
+
+ src = nm_connection_new ();
+ fill_wifi_empty (src);
+ fill_wsec (src, src_wsec);
+ success = complete_connection ("blahblah", bssid,
+ NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE,
+ src, &error);
+ /* We expect failure here since Dynamic WEP is incompatible with WPA */
+ COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY);
+
+ g_object_unref (src);
+}
+
+/*******************************************/
+
+static void
+test_wpa_ap_wpa_psk_connection_1 (guint idx)
+{
+ NMConnection *expected;
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+
+ expected = nm_connection_new ();
+ fill_wsec (expected, exp_wsec);
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE, expected);
+ g_object_unref (expected);
+}
+
+static void
+test_wpa_ap_wpa_psk_connection_2 (guint idx)
+{
+ NMConnection *expected;
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+
+ expected = nm_connection_new ();
+ fill_wsec (expected, exp_wsec);
+ test_ap_wpa_psk_connection_base (NULL, NULL,
+ NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ TRUE, expected);
+ g_object_unref (expected);
+}
+
+static void
+test_wpa_ap_wpa_psk_connection_3 (guint idx)
+{
+ NMConnection *expected;
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+
+ expected = nm_connection_new ();
+ fill_wsec (expected, exp_wsec);
+ test_ap_wpa_psk_connection_base (NULL, "open",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE, expected);
+ g_object_unref (expected);
+}
+
+static void
+test_wpa_ap_wpa_psk_connection_4 (guint idx)
+{
+ test_ap_wpa_psk_connection_base (NULL, "shared",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE, NULL);
+}
+
+static void
+test_wpa_ap_wpa_psk_connection_5 (guint idx)
+{
+ NMConnection *expected;
+ const KeyData exp_wsec[] = {
+ { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 },
+ { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 },
+ { NULL } };
+
+ expected = nm_connection_new ();
+ fill_wsec (expected, exp_wsec);
+ test_ap_wpa_psk_connection_base ("wpa-psk", "open",
+ NM_802_11_AP_FLAGS_PRIVACY,
+ wpa_flags_for_idx (idx),
+ rsn_flags_for_idx (idx),
+ FALSE, expected);
+ g_object_unref (expected);
+}
+
+/*******************************************/
+
+static void
+test_strength_dbm (void)
+{
+ /* boundary conditions first */
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-1), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-40), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-30), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-100), ==, 0);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-200), ==, 0);
+
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-81), ==, 32);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-92), ==, 14);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-74), ==, 44);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-81), ==, 32);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (-66), ==, 57);
+}
+
+static void
+test_strength_percent (void)
+{
+ int i;
+
+ /* boundary conditions first */
+ g_assert_cmpint (nm_ap_utils_level_to_quality (0), ==, 0);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (100), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (110), ==, 100);
+
+ for (i = 0; i <= 100; i++)
+ g_assert_cmpint (nm_ap_utils_level_to_quality (i), ==, i);
+}
+
+static void
+test_strength_wext (void)
+{
+ /* boundary conditions that we assume aren't WEXT first */
+ g_assert_cmpint (nm_ap_utils_level_to_quality (256), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (110), ==, 100);
+
+ /* boundary conditions that we assume are WEXT */
+ g_assert_cmpint (nm_ap_utils_level_to_quality (111), ==, 0);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (150), ==, 0);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (225), ==, 100);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (255), ==, 100);
+
+ g_assert_cmpint (nm_ap_utils_level_to_quality (157), ==, 2);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (200), ==, 74);
+ g_assert_cmpint (nm_ap_utils_level_to_quality (215), ==, 99);
+}
+
+/*******************************************/
+
+#if GLIB_CHECK_VERSION(2,25,12)
+typedef GTestFixtureFunc TCFunc;
+#else
+typedef void (*TCFunc)(void);
+#endif
+
+#define TESTCASE(t, d) g_test_create_case (#t, 0, (gconstpointer) d, NULL, (TCFunc) t, NULL)
+
+int main (int argc, char **argv)
+{
+ GTestSuite *suite;
+ gsize i;
+
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ suite = g_test_get_root ();
+
+ g_test_suite_add (suite, TESTCASE (test_lock_bssid, NULL));
+
+ /* Open AP tests; make sure that connections to be completed that have
+ * various security-related settings already set cause the completion
+ * to fail.
+ */
+ g_test_suite_add (suite, TESTCASE (test_open_ap_empty_connection, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, TRUE));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, FALSE));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, TRUE));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, FALSE));
+
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_1, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_3, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_4, NULL));
+ g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_5, NULL));
+
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_OPEN));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_OPEN));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_OPEN));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_OPEN));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_OPEN));
+
+ /* WEP AP tests */
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_empty_connection, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_1, FALSE));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_2, FALSE));
+
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_1, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_3, NULL));
+
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_1, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_2, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_3, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_4, NULL));
+ g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_5, NULL));
+
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_PRIV));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_PRIV));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_PRIV));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_PRIV));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_PRIV));
+
+ /* WPA-PSK tests */
+ for (i = IDX_WPA_PSK_PTKIP_GTKIP; i <= IDX_WPA_RSN_PSK_PCCMP_GCCMP; i++) {
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, i));
+
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, i));
+
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, i));
+
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, i));
+ }
+
+ /* RSN-PSK tests */
+ for (i = IDX_WPA_RSN_PSK_PTKIP_PCCMP_GTKIP; i <= IDX_RSN_PSK_PTKIP_PCCMP_GTKIP; i++) {
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, i));
+
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, i));
+
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, i));
+ g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, i));
+
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, i));
+ g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, i));
+ }
+
+ /* Scanned signal strength conversion tests */
+ g_test_suite_add (suite, TESTCASE (test_strength_dbm, NULL));
+ g_test_suite_add (suite, TESTCASE (test_strength_percent, NULL));
+ g_test_suite_add (suite, TESTCASE (test_strength_wext, NULL));
+
+ return g_test_run ();
+}
+
diff --git a/src/vpn-manager/Makefile.in b/src/vpn-manager/Makefile.in
index 46aebbb24..8903d70ed 100644
--- a/src/vpn-manager/Makefile.in
+++ b/src/vpn-manager/Makefile.in
@@ -38,11 +38,16 @@ subdir = src/vpn-manager
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -65,7 +70,7 @@ AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -96,7 +101,6 @@ ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -105,8 +109,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -123,6 +125,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -131,6 +134,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -139,8 +143,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -155,13 +159,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -169,6 +183,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -177,13 +193,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -209,12 +227,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -229,10 +244,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
diff --git a/src/vpn-manager/nm-vpn-connection-base.c b/src/vpn-manager/nm-vpn-connection-base.c
index 8a6fb2beb..7fde5db06 100644
--- a/src/vpn-manager/nm-vpn-connection-base.c
+++ b/src/vpn-manager/nm-vpn-connection-base.c
@@ -43,7 +43,6 @@ typedef struct {
enum {
PROP_0,
- PROP_SERVICE_NAME,
PROP_CONNECTION,
PROP_SPECIFIC_OBJECT,
PROP_DEVICES,
@@ -141,9 +140,6 @@ get_property (GObject *object, guint prop_id,
NMVpnConnectionBasePrivate *priv = NM_VPN_CONNECTION_BASE_GET_PRIVATE (object);
switch (prop_id) {
- case PROP_SERVICE_NAME:
- nm_active_connection_scope_to_value (priv->connection, value);
- break;
case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->connection));
break;
@@ -184,7 +180,6 @@ nm_vpn_connection_base_class_init (NMVpnConnectionBaseClass *vpn_class)
/* properties */
nm_active_connection_install_properties (object_class,
- PROP_SERVICE_NAME,
PROP_CONNECTION,
PROP_SPECIFIC_OBJECT,
PROP_DEVICES,
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 03e213ff7..601d29bcb 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -30,11 +30,11 @@
#include "NetworkManager.h"
#include "NetworkManagerVPN.h"
#include "nm-vpn-connection.h"
+#include "nm-device-interface.h"
#include "nm-setting-connection.h"
#include "nm-setting-vpn.h"
#include "nm-setting-ip4-config.h"
#include "nm-dbus-manager.h"
-#include "nm-manager.h"
#include "nm-system.h"
#include "nm-logging.h"
#include "nm-utils.h"
@@ -47,21 +47,22 @@
#include "nm-dns-manager.h"
#include "nm-netlink-monitor.h"
#include "nm-glib-compat.h"
+#include "settings/nm-settings-connection.h"
#include "nm-vpn-connection-glue.h"
-static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class);
-
-G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, NM_TYPE_VPN_CONNECTION_BASE, 0,
- G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE,
- secrets_provider_interface_init))
+G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_VPN_CONNECTION_BASE)
typedef struct {
gboolean disposed;
NMConnection *connection;
+ gboolean user_requested;
+ gulong user_uid;
NMActRequest *act_request;
+ guint32 secrets_id;
+ char *username;
NMDevice *parent_dev;
gulong device_monitor;
@@ -201,7 +202,9 @@ device_ip4_config_changed (NMDevice *device,
NMVPNConnection *
nm_vpn_connection_new (NMConnection *connection,
NMActRequest *act_request,
- NMDevice *parent_device)
+ NMDevice *parent_device,
+ gboolean user_requested,
+ gulong user_uid)
{
NMVPNConnection *self;
NMVPNConnectionPrivate *priv;
@@ -216,6 +219,8 @@ nm_vpn_connection_new (NMConnection *connection,
priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ priv->user_requested = user_requested;
+ priv->user_uid = user_uid;
priv->connection = g_object_ref (connection);
priv->parent_dev = g_object_ref (parent_device);
priv->act_request = g_object_ref (act_request);
@@ -470,8 +475,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_BANNER);
if (val) {
- if (priv->banner)
- g_free (priv->banner);
+ g_free (priv->banner);
priv->banner = g_strdup (g_value_get_string (val));
}
@@ -590,8 +594,36 @@ nm_vpn_connection_connect_cb (DBusGProxy *proxy, GError *err, gpointer user_data
}
}
+/* Add a username to a hashed connection */
+static GHashTable *
+_hash_with_username (NMConnection *connection, const char *username)
+{
+ NMConnection *dup;
+ NMSetting *s_vpn;
+ GHashTable *hash;
+ const char *existing;
+
+ /* Shortcut if we weren't given a username or if there already was one in
+ * the VPN setting; don't bother duplicating the connection and everything.
+ */
+ s_vpn = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+ g_assert (s_vpn);
+ existing = nm_setting_vpn_get_user_name (NM_SETTING_VPN (s_vpn));
+ if (username == NULL || existing)
+ return nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
+
+ dup = nm_connection_duplicate (connection);
+ g_assert (dup);
+ s_vpn = nm_connection_get_setting (dup, NM_TYPE_SETTING_VPN);
+ g_assert (s_vpn);
+ g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL);
+ hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ALL);
+ g_object_unref (dup);
+ return hash;
+}
+
static void
-really_activate (NMVPNConnection *connection)
+really_activate (NMVPNConnection *connection, const char *username)
{
NMVPNConnectionPrivate *priv;
GHashTable *hash;
@@ -611,7 +643,7 @@ really_activate (NMVPNConnection *connection)
G_CALLBACK (nm_vpn_connection_ip4_config_get),
connection, NULL);
- hash = nm_connection_to_hash (priv->connection);
+ hash = _hash_with_username (priv->connection, username);
org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy,
hash,
nm_vpn_connection_connect_cb,
@@ -759,55 +791,26 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
/******************************************************************************/
-static gboolean
-secrets_update_setting (NMSecretsProviderInterface *interface,
- const char *setting_name,
- GHashTable *new)
-{
- NMVPNConnection *self = NM_VPN_CONNECTION (interface);
- NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
- GError *error = NULL;
-
- g_return_val_if_fail (priv->connection != NULL, FALSE);
-
- if (strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME))
- return FALSE;
-
- if (!nm_connection_update_secrets (priv->connection, NM_SETTING_VPN_SETTING_NAME, new, &error)) {
- nm_log_warn (LOGD_VPN, "Failed to update VPN secrets: %d %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(none)");
- g_clear_error (&error);
- return FALSE;
- }
- return TRUE;
-}
-
static void
-secrets_result (NMSecretsProviderInterface *interface,
- const char *setting_name,
- RequestSecretsCaller caller,
- const GSList *updated,
- GError *error)
+vpn_secrets_cb (NMSettingsConnection *connection,
+ guint32 call_id,
+ const char *agent_username,
+ const char *setting_name,
+ GError *error,
+ gpointer user_data)
{
- NMVPNConnection *self = NM_VPN_CONNECTION (interface);
+ NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
- g_return_if_fail (priv->connection != NULL);
- g_return_if_fail (caller == SECRETS_CALLER_VPN);
+ g_return_if_fail (NM_CONNECTION (connection) == priv->connection);
+ g_return_if_fail (call_id == priv->secrets_id);
+
+ priv->secrets_id = 0;
if (error)
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
else
- really_activate (self);
-}
-
-static void
-secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class)
-{
- /* interface implementation */
- sp_interface_class->update_setting = secrets_update_setting;
- sp_interface_class->result = secrets_result;
+ really_activate (self, agent_username);
}
static void
@@ -818,6 +821,7 @@ connection_need_secrets_cb (DBusGProxy *proxy,
{
NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ GError *local = NULL;
if (error) {
nm_log_err (LOGD_VPN, "NeedSecrets failed: %s %s",
@@ -828,35 +832,107 @@ connection_need_secrets_cb (DBusGProxy *proxy,
}
if (!setting_name || !strlen (setting_name)) {
+ nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated no additional secrets required",
+ nm_connection_get_uuid (priv->connection),
+ nm_connection_get_id (priv->connection));
+
/* No secrets required */
- really_activate (self);
+ really_activate (self, priv->username);
return;
}
- /* Get the secrets the VPN plugin wants */
- if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self),
- priv->connection,
- setting_name,
- FALSE,
- SECRETS_CALLER_VPN,
- NULL,
- NULL))
+ nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated additional '%s' secrets required",
+ nm_connection_get_uuid (priv->connection),
+ nm_connection_get_id (priv->connection),
+ setting_name);
+
+ priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
+ priv->user_requested,
+ priv->user_uid,
+ setting_name,
+ NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION,
+ NULL,
+ vpn_secrets_cb,
+ self,
+ &local);
+ if (!priv->secrets_id) {
+ if (local)
+ nm_log_err (LOGD_VPN, "failed to get secrets: (%d) %s", local->code, local->message);
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
+ g_clear_error (&local);
+ }
}
static void
-call_need_secrets (NMVPNConnection *vpn_connection)
+existing_secrets_cb (NMSettingsConnection *connection,
+ guint32 call_id,
+ const char *agent_username,
+ const char *setting_name,
+ GError *error,
+ gpointer user_data)
{
- NMVPNConnectionPrivate *priv;
- GHashTable *settings;
-
- priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection);
- settings = nm_connection_to_hash (priv->connection);
- org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy,
- settings,
- connection_need_secrets_cb,
- vpn_connection);
- g_hash_table_destroy (settings);
+ NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ GHashTable *hash;
+
+ g_return_if_fail (NM_CONNECTION (connection) == priv->connection);
+ g_return_if_fail (call_id == priv->secrets_id);
+
+ priv->secrets_id = 0;
+
+ if (error) {
+ nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #2: (%s) %s",
+ g_quark_to_string (error->domain),
+ error->message);
+ nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
+ } else {
+ nm_log_dbg (LOGD_VPN, "(%s/%s) asking service if additional secrets are required",
+ nm_connection_get_uuid (priv->connection),
+ nm_connection_get_id (priv->connection));
+
+ /* Cache the username for later */
+ g_free (priv->username);
+ priv->username = g_strdup (agent_username);
+
+ /* Ask the VPN service if more secrets are required */
+ hash = _hash_with_username (priv->connection, priv->username);
+ org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy,
+ hash,
+ connection_need_secrets_cb,
+ self);
+ g_hash_table_destroy (hash);
+ }
+}
+
+static void
+get_existing_secrets (NMVPNConnection *self)
+{
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+ GError *error = NULL;
+
+ nm_log_dbg (LOGD_VPN, "(%s/%s) requesting existing VPN secrets",
+ nm_connection_get_uuid (priv->connection),
+ nm_connection_get_id (priv->connection));
+
+ /* Just get existing secrets if any so we can ask the VPN service if
+ * any more are required.
+ */
+ priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
+ priv->user_requested,
+ priv->user_uid,
+ NM_SETTING_VPN_SETTING_NAME,
+ NM_SETTINGS_GET_SECRETS_FLAG_NONE,
+ NULL,
+ existing_secrets_cb,
+ self,
+ &error);
+ if (priv->secrets_id == 0) {
+ nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #1: (%s) %s",
+ g_quark_to_string (error->domain),
+ error->message);
+ g_error_free (error);
+ nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
+ }
}
static void
@@ -901,15 +977,11 @@ vpn_cleanup (NMVPNConnection *connection)
priv->gw_route = NULL;
}
- if (priv->banner) {
- g_free (priv->banner);
- priv->banner = NULL;
- }
+ g_free (priv->banner);
+ priv->banner = NULL;
- if (priv->ip_iface) {
- g_free (priv->ip_iface);
- priv->ip_iface = NULL;
- }
+ g_free (priv->ip_iface);
+ priv->ip_iface = NULL;
/* Clear out connection secrets to ensure that the settings service
* gets asked for them next time the connection is activated.
@@ -919,17 +991,25 @@ vpn_cleanup (NMVPNConnection *connection)
}
static void
-connection_state_changed (NMVPNConnection *connection,
+connection_state_changed (NMVPNConnection *self,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason)
{
- NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
- nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request));
+ /* Clear any in-progress secrets request */
+ if (priv->secrets_id) {
+ nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id);
+ priv->secrets_id = 0;
+ }
switch (state) {
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
- call_need_secrets (connection);
+ get_existing_secrets (self);
+ break;
+ case NM_VPN_CONNECTION_STATE_ACTIVATED:
+ /* Secrets no longer needed now that we're connected */
+ nm_connection_clear_secrets (priv->connection);
break;
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
case NM_VPN_CONNECTION_STATE_FAILED:
@@ -945,7 +1025,7 @@ connection_state_changed (NMVPNConnection *connection,
g_object_unref (priv->proxy);
priv->proxy = NULL;
}
- vpn_cleanup (connection);
+ vpn_cleanup (self);
break;
default:
break;
@@ -989,8 +1069,14 @@ dispose (GObject *object)
if (priv->proxy)
g_object_unref (priv->proxy);
+ if (priv->secrets_id) {
+ nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection),
+ priv->secrets_id);
+ }
+
g_object_unref (priv->act_request);
g_object_unref (priv->connection);
+ g_free (priv->username);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
}
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index ab880b17f..fd5ee24e1 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2005 - 2008 Red Hat, Inc.
+ * Copyright (C) 2005 - 2011 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -27,7 +27,6 @@
#include "NetworkManagerVPN.h"
#include "nm-device.h"
#include "nm-activation-request.h"
-#include "nm-secrets-provider-interface.h"
#include "nm-vpn-connection-base.h"
#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ())
@@ -59,7 +58,9 @@ GType nm_vpn_connection_get_type (void);
NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
NMActRequest *act_request,
- NMDevice *parent_device);
+ NMDevice *parent_device,
+ gboolean user_requested,
+ gulong user_uid);
void nm_vpn_connection_activate (NMVPNConnection *connection);
NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection);
diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c
index d3cd10a8b..2bd8f2360 100644
--- a/src/vpn-manager/nm-vpn-manager.c
+++ b/src/vpn-manager/nm-vpn-manager.c
@@ -115,22 +115,26 @@ find_active_vpn_connection_by_connection (NMVPNManager *self, NMConnection *conn
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
GHashTableIter iter;
gpointer data;
- GSList *connections, *elt;
+ GSList *active, *aiter;
+ NMVPNConnection *found = NULL;
g_return_val_if_fail (connection, NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_hash_table_iter_init (&iter, priv->services);
- while (g_hash_table_iter_next (&iter, NULL, &data)) {
- connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data));
- for (elt = connections; elt; elt = g_slist_next (elt)) {
- NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
+ while (g_hash_table_iter_next (&iter, NULL, &data) && (found == NULL)) {
+ active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data));
+ for (aiter = active; aiter; aiter = g_slist_next (aiter)) {
+ NMVPNConnection *vpn = NM_VPN_CONNECTION (aiter->data);
- if (nm_vpn_connection_get_connection (vpn) == connection)
- return vpn;
+ if (nm_vpn_connection_get_connection (vpn) == connection) {
+ found = vpn;
+ break;
+ }
}
+ g_slist_free (active);
}
- return NULL;
+ return found;
}
static void
@@ -159,6 +163,8 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
+ gboolean user_requested,
+ gulong user_uid,
GError **error)
{
NMSettingVPN *vpn_setting;
@@ -205,7 +211,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager,
return NULL;
}
- vpn = nm_vpn_service_activate (service, connection, act_request, device, error);
+ vpn = nm_vpn_service_activate (service, connection, act_request, device, user_requested, user_uid, error);
if (vpn) {
g_signal_connect (vpn, "vpn-state-changed",
G_CALLBACK (connection_vpn_state_changed),
@@ -223,7 +229,8 @@ nm_vpn_manager_deactivate_connection (NMVPNManager *self,
NMVPNManagerPrivate *priv;
GHashTableIter iter;
gpointer data;
- GSList *active, *elt;
+ GSList *active, *aiter;
+ gboolean success = FALSE;
g_return_val_if_fail (self, FALSE);
g_return_val_if_fail (NM_IS_VPN_MANAGER (self), FALSE);
@@ -231,21 +238,23 @@ nm_vpn_manager_deactivate_connection (NMVPNManager *self,
priv = NM_VPN_MANAGER_GET_PRIVATE (self);
g_hash_table_iter_init (&iter, priv->services);
- while (g_hash_table_iter_next (&iter, NULL, &data)) {
+ while (g_hash_table_iter_next (&iter, NULL, &data) && (success == FALSE)) {
active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data));
- for (elt = active; elt; elt = g_slist_next (elt)) {
- NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
+ for (aiter = active; aiter; aiter = g_slist_next (aiter)) {
+ NMVPNConnection *vpn = NM_VPN_CONNECTION (aiter->data);
const char *vpn_path;
vpn_path = nm_vpn_connection_get_active_connection_path (vpn);
if (!strcmp (path, vpn_path)) {
nm_vpn_connection_disconnect (vpn, reason);
- return TRUE;
+ success = TRUE;
+ break;
}
}
+ g_slist_free (active);
}
- return FALSE;
+ return success;
}
void
@@ -256,7 +265,7 @@ nm_vpn_manager_add_active_connections (NMVPNManager *self,
NMVPNManagerPrivate *priv;
GHashTableIter iter;
gpointer data;
- GSList *active, *elt;
+ GSList *active, *aiter;
g_return_if_fail (self);
g_return_if_fail (NM_IS_VPN_MANAGER (self));
@@ -266,8 +275,8 @@ nm_vpn_manager_add_active_connections (NMVPNManager *self,
g_hash_table_iter_init (&iter, priv->services);
while (g_hash_table_iter_next (&iter, NULL, &data)) {
active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data));
- for (elt = active; elt; elt = g_slist_next (elt)) {
- NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
+ for (aiter = active; aiter; aiter = g_slist_next (aiter)) {
+ NMVPNConnection *vpn = NM_VPN_CONNECTION (aiter->data);
const char *path;
if (!filter || (nm_vpn_connection_get_connection (vpn) == filter)) {
@@ -275,6 +284,7 @@ nm_vpn_manager_add_active_connections (NMVPNManager *self,
g_ptr_array_add (array, g_strdup (path));
}
}
+ g_slist_free (active);
}
}
@@ -284,7 +294,7 @@ nm_vpn_manager_get_active_connections (NMVPNManager *self)
NMVPNManagerPrivate *priv;
GHashTableIter iter;
gpointer data;
- GSList *list = NULL, *active, *elt;
+ GSList *list = NULL, *active;
g_return_val_if_fail (self, NULL);
g_return_val_if_fail (NM_IS_VPN_MANAGER (self), NULL);
@@ -293,8 +303,7 @@ nm_vpn_manager_get_active_connections (NMVPNManager *self)
g_hash_table_iter_init (&iter, priv->services);
while (g_hash_table_iter_next (&iter, NULL, &data)) {
active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (data));
- for (elt = active; elt; elt = g_slist_next (elt))
- list = g_slist_append (list, g_object_ref (G_OBJECT (elt->data)));
+ list = g_slist_concat (list, active);
}
return list;
}
diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h
index f14844a9d..6159bb86f 100644
--- a/src/vpn-manager/nm-vpn-manager.h
+++ b/src/vpn-manager/nm-vpn-manager.h
@@ -71,6 +71,8 @@ NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
+ gboolean user_requested,
+ gulong user_uid,
GError **error);
gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager,
diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c
index 3d44d9004..3b4e2b481 100644
--- a/src/vpn-manager/nm-vpn-service.c
+++ b/src/vpn-manager/nm-vpn-service.c
@@ -325,6 +325,8 @@ nm_vpn_service_activate (NMVPNService *service,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
+ gboolean user_requested,
+ gulong user_uid,
GError **error)
{
NMVPNConnection *vpn;
@@ -341,7 +343,7 @@ nm_vpn_service_activate (NMVPNService *service,
clear_quit_timeout (service);
- vpn = nm_vpn_connection_new (connection, act_request, device);
+ vpn = nm_vpn_connection_new (connection, act_request, device, user_requested, user_uid);
g_signal_connect (vpn, "vpn-state-changed",
G_CALLBACK (connection_vpn_state_changed),
service);
@@ -415,7 +417,8 @@ nm_vpn_service_init (NMVPNService *self)
NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
priv->dbus_mgr = nm_dbus_manager_get ();
- priv->name_owner_id = g_signal_connect (priv->dbus_mgr, "name-owner-changed",
+ priv->name_owner_id = g_signal_connect (priv->dbus_mgr,
+ NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (nm_vpn_service_name_owner_changed),
self);
}
diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h
index c7c1b0366..0c2445e26 100644
--- a/src/vpn-manager/nm-vpn-service.h
+++ b/src/vpn-manager/nm-vpn-service.h
@@ -59,6 +59,8 @@ NMVPNConnection * nm_vpn_service_activate (NMVPNService *service,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
+ gboolean user_requested,
+ gulong user_uid,
GError **error);
GSList * nm_vpn_service_get_active_connections (NMVPNService *service);
diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am
new file mode 100644
index 000000000..91f1dc4e0
--- /dev/null
+++ b/src/wimax/Makefile.am
@@ -0,0 +1,40 @@
+INCLUDES = \
+ -I${top_srcdir}/src \
+ -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libwimax.la
+
+libwimax_la_SOURCES = \
+ nm-device-wimax.c \
+ nm-device-wimax.h \
+ nm-wimax-nsp.c \
+ nm-wimax-nsp.h \
+ nm-wimax-types.h \
+ nm-wimax-util.c \
+ nm-wimax-util.h \
+ iwmxsdk.c \
+ iwmxsdk.h
+
+libwimax_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(IWMX_SDK_CFLAGS)
+
+libwimax_la_LIBADD = \
+ $(DBUS_LIBS) \
+ $(IWMX_SDK_LIBS) \
+ $(top_builddir)/marshallers/libmarshallers.la
+
+nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml
+ dbus-binding-tool --prefix=nm_wimax_nsp --mode=glib-server --output=$@ $<
+
+nm-device-wimax-glue.h: $(top_srcdir)/introspection/nm-device-wimax.xml
+ dbus-binding-tool --prefix=nm_device_wimax --mode=glib-server --output=$@ $<
+
+BUILT_SOURCES = \
+ nm-wimax-nsp-glue.h \
+ nm-device-wimax-glue.h
+
+CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/system-settings/Makefile.in b/src/wimax/Makefile.in
index a720c9238..b65d5ea96 100644
--- a/src/system-settings/Makefile.in
+++ b/src/wimax/Makefile.in
@@ -34,15 +34,20 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/system-settings
+subdir = src/wimax
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \
- $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
- $(top_srcdir)/m4/libnl-check.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/introspection.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libnl-check.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -51,30 +56,17 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
-libsystem_settings_la_DEPENDENCIES = \
- $(top_builddir)/libnm-util/libnm-util.la \
- $(top_builddir)/libnm-glib/libnm-glib.la \
- $(top_builddir)/marshallers/libmarshallers.la \
- $(top_builddir)/src/logging/libnm-logging.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am_libsystem_settings_la_OBJECTS = \
- libsystem_settings_la-nm-sysconfig-settings.lo \
- libsystem_settings_la-nm-inotify-helper.lo \
- libsystem_settings_la-nm-system-config-error.lo \
- libsystem_settings_la-nm-system-config-interface.lo \
- libsystem_settings_la-nm-sysconfig-connection.lo \
- libsystem_settings_la-nm-default-wired-connection.lo
-libsystem_settings_la_OBJECTS = $(am_libsystem_settings_la_OBJECTS)
+libwimax_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(top_builddir)/marshallers/libmarshallers.la
+am_libwimax_la_OBJECTS = libwimax_la-nm-device-wimax.lo \
+ libwimax_la-nm-wimax-nsp.lo libwimax_la-nm-wimax-util.lo \
+ libwimax_la-iwmxsdk.lo
+libwimax_la_OBJECTS = $(am_libwimax_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
-libsystem_settings_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) $(libsystem_settings_la_LDFLAGS) \
- $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -99,13 +91,12 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
-SOURCES = $(libsystem_settings_la_SOURCES)
-DIST_SOURCES = $(libsystem_settings_la_SOURCES)
+SOURCES = $(libwimax_la_SOURCES)
+DIST_SOURCES = $(libwimax_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
-ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@
ALL_LINGUAS = @ALL_LINGUAS@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
@@ -114,8 +105,6 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
@@ -132,6 +121,7 @@ DHCLIENT_PATH = @DHCLIENT_PATH@
DHCLIENT_VERSION = @DHCLIENT_VERSION@
DHCPCD_PATH = @DHCPCD_PATH@
DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
+DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@@ -140,6 +130,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
GIO_CFLAGS = @GIO_CFLAGS@
GIO_LIBS = @GIO_LIBS@
@@ -148,8 +139,8 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GMODULE_CFLAGS = @GMODULE_CFLAGS@
GMODULE_LIBS = @GMODULE_LIBS@
-GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
GNUTLS_LIBS = @GNUTLS_LIBS@
GREP = @GREP@
@@ -164,13 +155,23 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
INTLTOOL_MERGE = @INTLTOOL_MERGE@
INTLTOOL_PERL = @INTLTOOL_PERL@
INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
IPTABLES_PATH = @IPTABLES_PATH@
+IWMX_SDK_CFLAGS = @IWMX_SDK_CFLAGS@
+IWMX_SDK_LIBS = @IWMX_SDK_LIBS@
KERNEL_FIRMWARE_DIR = @KERNEL_FIRMWARE_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
@@ -178,6 +179,8 @@ LIBDL = @LIBDL@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
LIBM = @LIBM@
LIBNL_CFLAGS = @LIBNL_CFLAGS@
LIBNL_LIBS = @LIBNL_LIBS@
@@ -186,13 +189,15 @@ LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
@@ -218,12 +223,9 @@ PKGCONFIG_PATH = @PKGCONFIG_PATH@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-POFILES = @POFILES@
POLKIT_CFLAGS = @POLKIT_CFLAGS@
POLKIT_LIBS = @POLKIT_LIBS@
POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@
RANLIB = @RANLIB@
RESOLVCONF_PATH = @RESOLVCONF_PATH@
@@ -238,10 +240,13 @@ UUID_CFLAGS = @UUID_CFLAGS@
UUID_LIBS = @UUID_LIBS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
@@ -290,62 +295,39 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-INCLUDES = -I${top_srcdir} \
- -I${top_srcdir}/include \
- -I${top_srcdir}/libnm-util \
- -I${top_srcdir}/libnm-glib \
- -I${top_srcdir}/src/logging \
- -I${top_srcdir}/src \
- -I${top_builddir}/marshallers
-
-noinst_LTLIBRARIES = libsystem-settings.la
-BUILT_SOURCES = \
- nm-settings-system-glue.h
-
-libsystem_settings_la_SOURCES = \
- nm-sysconfig-settings.c \
- nm-sysconfig-settings.h \
- nm-inotify-helper.c \
- nm-inotify-helper.h \
- nm-polkit-helpers.h \
- nm-system-config-error.c \
- nm-system-config-error.h \
- nm-system-config-interface.c \
- nm-system-config-interface.h \
- nm-sysconfig-connection.c \
- nm-sysconfig-connection.h \
- nm-default-wired-connection.c \
- nm-default-wired-connection.h
-
-libsystem_settings_la_CPPFLAGS = \
+INCLUDES = \
+ -I${top_srcdir}/src \
+ -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libwimax.la
+libwimax_la_SOURCES = \
+ nm-device-wimax.c \
+ nm-device-wimax.h \
+ nm-wimax-nsp.c \
+ nm-wimax-nsp.h \
+ nm-wimax-types.h \
+ nm-wimax-util.c \
+ nm-wimax-util.h \
+ iwmxsdk.c \
+ iwmxsdk.h
+
+libwimax_la_CPPFLAGS = \
$(DBUS_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GMODULE_CFLAGS) \
- $(POLKIT_CFLAGS) \
- -DG_DISABLE_DEPRECATED \
- -DBINDIR=\"$(bindir)\" \
- -DSBINDIR=\"$(sbindir)\" \
- -DLIBEXECDIR=\"$(libexecdir)\" \
- -DDATADIR=\"$(datadir)\" \
- -DSYSCONFDIR=\"$(sysconfdir)\" \
- -DLOCALSTATEDIR=\"$(localstatedir)\" \
- -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
- -DPLUGINDIR=\"$(pkglibdir)\"
-
-libsystem_settings_la_LIBADD = \
- $(top_builddir)/libnm-util/libnm-util.la \
- $(top_builddir)/libnm-glib/libnm-glib.la \
- $(top_builddir)/marshallers/libmarshallers.la \
- $(top_builddir)/src/logging/libnm-logging.la \
+ $(IWMX_SDK_CFLAGS)
+
+libwimax_la_LIBADD = \
$(DBUS_LIBS) \
- $(GLIB_LIBS) \
- $(GMODULE_LIBS) \
- $(POLKIT_LIBS)
+ $(IWMX_SDK_LIBS) \
+ $(top_builddir)/marshallers/libmarshallers.la
-libsystem_settings_la_LDFLAGS = -rdynamic
-CLEANFILES = \
- $(BUILT_SOURCES)
+BUILT_SOURCES = \
+ nm-wimax-nsp-glue.h \
+ nm-device-wimax-glue.h
+CLEANFILES = $(BUILT_SOURCES)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -360,9 +342,9 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/system-settings/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/wimax/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/system-settings/Makefile
+ $(AUTOMAKE) --gnu src/wimax/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -390,8 +372,8 @@ clean-noinstLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libsystem-settings.la: $(libsystem_settings_la_OBJECTS) $(libsystem_settings_la_DEPENDENCIES)
- $(AM_V_CCLD)$(libsystem_settings_la_LINK) $(libsystem_settings_la_OBJECTS) $(libsystem_settings_la_LIBADD) $(LIBS)
+libwimax.la: $(libwimax_la_OBJECTS) $(libwimax_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libwimax_la_OBJECTS) $(libwimax_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -399,12 +381,10 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-default-wired-connection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-inotify-helper.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-sysconfig-connection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-sysconfig-settings.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-system-config-error.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsystem_settings_la-nm-system-config-interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-iwmxsdk.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-device-wimax.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-wimax-nsp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libwimax_la-nm-wimax-util.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -433,53 +413,37 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
-libsystem_settings_la-nm-sysconfig-settings.lo: nm-sysconfig-settings.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-sysconfig-settings.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-sysconfig-settings.Tpo -c -o libsystem_settings_la-nm-sysconfig-settings.lo `test -f 'nm-sysconfig-settings.c' || echo '$(srcdir)/'`nm-sysconfig-settings.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-sysconfig-settings.Tpo $(DEPDIR)/libsystem_settings_la-nm-sysconfig-settings.Plo
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-sysconfig-settings.c' object='libsystem_settings_la-nm-sysconfig-settings.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-sysconfig-settings.lo `test -f 'nm-sysconfig-settings.c' || echo '$(srcdir)/'`nm-sysconfig-settings.c
-
-libsystem_settings_la-nm-inotify-helper.lo: nm-inotify-helper.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-inotify-helper.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-inotify-helper.Tpo -c -o libsystem_settings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-inotify-helper.Tpo $(DEPDIR)/libsystem_settings_la-nm-inotify-helper.Plo
+libwimax_la-nm-device-wimax.lo: nm-device-wimax.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-device-wimax.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-device-wimax.Tpo -c -o libwimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-device-wimax.Tpo $(DEPDIR)/libwimax_la-nm-device-wimax.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-inotify-helper.c' object='libsystem_settings_la-nm-inotify-helper.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-device-wimax.c' object='libwimax_la-nm-device-wimax.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-inotify-helper.lo `test -f 'nm-inotify-helper.c' || echo '$(srcdir)/'`nm-inotify-helper.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-device-wimax.lo `test -f 'nm-device-wimax.c' || echo '$(srcdir)/'`nm-device-wimax.c
-libsystem_settings_la-nm-system-config-error.lo: nm-system-config-error.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-system-config-error.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-system-config-error.Tpo -c -o libsystem_settings_la-nm-system-config-error.lo `test -f 'nm-system-config-error.c' || echo '$(srcdir)/'`nm-system-config-error.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-system-config-error.Tpo $(DEPDIR)/libsystem_settings_la-nm-system-config-error.Plo
+libwimax_la-nm-wimax-nsp.lo: nm-wimax-nsp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-wimax-nsp.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-wimax-nsp.Tpo -c -o libwimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-wimax-nsp.Tpo $(DEPDIR)/libwimax_la-nm-wimax-nsp.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-system-config-error.c' object='libsystem_settings_la-nm-system-config-error.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-nsp.c' object='libwimax_la-nm-wimax-nsp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-system-config-error.lo `test -f 'nm-system-config-error.c' || echo '$(srcdir)/'`nm-system-config-error.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-wimax-nsp.lo `test -f 'nm-wimax-nsp.c' || echo '$(srcdir)/'`nm-wimax-nsp.c
-libsystem_settings_la-nm-system-config-interface.lo: nm-system-config-interface.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-system-config-interface.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-system-config-interface.Tpo -c -o libsystem_settings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-system-config-interface.Tpo $(DEPDIR)/libsystem_settings_la-nm-system-config-interface.Plo
+libwimax_la-nm-wimax-util.lo: nm-wimax-util.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-nm-wimax-util.lo -MD -MP -MF $(DEPDIR)/libwimax_la-nm-wimax-util.Tpo -c -o libwimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-nm-wimax-util.Tpo $(DEPDIR)/libwimax_la-nm-wimax-util.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-system-config-interface.c' object='libsystem_settings_la-nm-system-config-interface.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-wimax-util.c' object='libwimax_la-nm-wimax-util.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-system-config-interface.lo `test -f 'nm-system-config-interface.c' || echo '$(srcdir)/'`nm-system-config-interface.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-nm-wimax-util.lo `test -f 'nm-wimax-util.c' || echo '$(srcdir)/'`nm-wimax-util.c
-libsystem_settings_la-nm-sysconfig-connection.lo: nm-sysconfig-connection.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-sysconfig-connection.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-sysconfig-connection.Tpo -c -o libsystem_settings_la-nm-sysconfig-connection.lo `test -f 'nm-sysconfig-connection.c' || echo '$(srcdir)/'`nm-sysconfig-connection.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-sysconfig-connection.Tpo $(DEPDIR)/libsystem_settings_la-nm-sysconfig-connection.Plo
+libwimax_la-iwmxsdk.lo: iwmxsdk.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libwimax_la-iwmxsdk.lo -MD -MP -MF $(DEPDIR)/libwimax_la-iwmxsdk.Tpo -c -o libwimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libwimax_la-iwmxsdk.Tpo $(DEPDIR)/libwimax_la-iwmxsdk.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-sysconfig-connection.c' object='libsystem_settings_la-nm-sysconfig-connection.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='iwmxsdk.c' object='libwimax_la-iwmxsdk.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-sysconfig-connection.lo `test -f 'nm-sysconfig-connection.c' || echo '$(srcdir)/'`nm-sysconfig-connection.c
-
-libsystem_settings_la-nm-default-wired-connection.lo: nm-default-wired-connection.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libsystem_settings_la-nm-default-wired-connection.lo -MD -MP -MF $(DEPDIR)/libsystem_settings_la-nm-default-wired-connection.Tpo -c -o libsystem_settings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsystem_settings_la-nm-default-wired-connection.Tpo $(DEPDIR)/libsystem_settings_la-nm-default-wired-connection.Plo
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nm-default-wired-connection.c' object='libsystem_settings_la-nm-default-wired-connection.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsystem_settings_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libsystem_settings_la-nm-default-wired-connection.lo `test -f 'nm-default-wired-connection.c' || echo '$(srcdir)/'`nm-default-wired-connection.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libwimax_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libwimax_la-iwmxsdk.lo `test -f 'iwmxsdk.c' || echo '$(srcdir)/'`iwmxsdk.c
mostlyclean-libtool:
-rm -f *.lo
@@ -689,8 +653,11 @@ uninstall-am:
pdf pdf-am ps ps-am tags uninstall uninstall-am
-nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $<
+nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml
+ dbus-binding-tool --prefix=nm_wimax_nsp --mode=glib-server --output=$@ $<
+
+nm-device-wimax-glue.h: $(top_srcdir)/introspection/nm-device-wimax.xml
+ dbus-binding-tool --prefix=nm_device_wimax --mode=glib-server --output=$@ $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c
new file mode 100644
index 000000000..dd78d5a46
--- /dev/null
+++ b/src/wimax/iwmxsdk.c
@@ -0,0 +1,1479 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ *
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <net/if.h>
+
+#include <glib.h>
+
+#include <WiMaxType.h>
+#include <WiMaxAPI.h>
+#include <WiMaxAPIEx.h>
+
+#include "logging/nm-logging.h"
+#include "iwmxsdk.h"
+
+static WIMAX_API_DEVICE_ID g_api;
+static GStaticMutex add_remove_mutex = G_STATIC_MUTEX_INIT;
+
+/* Misc utilities */
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+/* Misc values */
+enum {
+ /*
+ * WARNING!!!!!
+ *
+ * ONLY ONE DEVICE SUPPORTED
+ *
+ * - on removal, there is no way to know which device was
+ * removed (the removed device is removed from the list and
+ * the callback doesn't have any more information than the
+ * index in the list that getlistdevice would return -- racy
+ * as hell).
+ *
+ * - on insertion, there is not enough information provided.
+ */
+ IWMX_SDK_DEV_MAX = 1,
+};
+
+/* Yes, this is dirty; see above on IWMX_SDK_DEV_MAX */
+static struct wmxsdk *g_iwmx_sdk_devs[IWMX_SDK_DEV_MAX];
+
+static struct wmxsdk *deviceid_to_wmxsdk(WIMAX_API_DEVICE_ID *device_id)
+{
+ unsigned cnt;
+ for (cnt = 0; cnt < IWMX_SDK_DEV_MAX; cnt++) {
+ struct wmxsdk *wmxsdk = g_iwmx_sdk_devs[cnt];
+ if (wmxsdk &&
+ wmxsdk->device_id.deviceIndex == device_id->deviceIndex)
+ return wmxsdk;
+ }
+ return NULL;
+}
+
+static int deviceid_to_index(WIMAX_API_DEVICE_ID *device_id)
+{
+ unsigned cnt;
+
+ for (cnt = 0; cnt < IWMX_SDK_DEV_MAX; cnt++) {
+ struct wmxsdk *wmxsdk = g_iwmx_sdk_devs[cnt];
+ if (wmxsdk && wmxsdk->device_id.deviceIndex == device_id->deviceIndex)
+ return cnt;
+ }
+ return -1;
+}
+
+struct wmxsdk *iwmx_sdk_get_wmxsdk_for_iface(const char *iface)
+{
+ unsigned cnt;
+
+ for (cnt = 0; cnt < IWMX_SDK_DEV_MAX; cnt++) {
+ struct wmxsdk *wmxsdk = g_iwmx_sdk_devs[cnt];
+ if (wmxsdk && !strcmp(wmxsdk->ifname, iface))
+ return wmxsdk;
+ }
+ return NULL;
+}
+
+/*
+ * FIXME: pulled it it out of some hole
+ *
+ * the cinr to percentage computation comes from the L3/L4 doc
+ *
+ * But some other places (L4 code) have a more complex, seemingly
+ * logarithmical computation.
+ *
+ * Oh well...
+ *
+ */
+static int cinr_to_percentage(int cinr)
+{
+ int strength;
+ if (cinr <= -5)
+ strength = 0;
+ else if (cinr >= 25)
+ strength = 100;
+ else /* Calc percentage on the value from -5 to 25 */
+ strength = ((100UL * (cinr - -5)) / (25 - -5));
+ return strength;
+}
+
+/**************************************************************/
+
+typedef struct {
+ WimaxNewWmxsdkFunc callback;
+ void *user_data;
+} NewSdkCallback;
+
+GStaticMutex new_callbacks_mutex = G_STATIC_MUTEX_INIT;
+static GSList *new_callbacks = NULL;
+
+void iwmx_sdk_new_callback_register(WimaxNewWmxsdkFunc callback, void *user_data)
+{
+ NewSdkCallback *cb;
+
+ cb = g_malloc0 (sizeof (NewSdkCallback));
+ g_assert (cb);
+ cb->callback = callback;
+ cb->user_data = user_data;
+
+ g_static_mutex_lock (&new_callbacks_mutex);
+ new_callbacks = g_slist_append (new_callbacks, cb);
+ g_static_mutex_unlock (&new_callbacks_mutex);
+}
+
+void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_data)
+{
+ GSList *iter;
+ NewSdkCallback *found = NULL;
+
+ g_static_mutex_lock (&new_callbacks_mutex);
+ for (iter = new_callbacks; iter; iter = g_slist_next (iter)) {
+ NewSdkCallback *cb = iter->data;
+
+ if (cb->callback == callback && cb->user_data == user_data) {
+ found = cb;
+ break;
+ }
+ }
+
+ if (found) {
+ new_callbacks = g_slist_remove (new_callbacks, found);
+ g_free (found);
+ }
+ g_static_mutex_unlock (&new_callbacks_mutex);
+}
+
+static void iwmx_sdk_call_new_callbacks(struct wmxsdk *wmxsdk)
+{
+ GSList *iter;
+
+ g_static_mutex_lock (&new_callbacks_mutex);
+ for (iter = new_callbacks; iter; iter = g_slist_next (iter)) {
+ NewSdkCallback *cb = iter->data;
+
+ cb->callback (wmxsdk, cb->user_data);
+ }
+ g_static_mutex_unlock (&new_callbacks_mutex);
+}
+
+/****************************************************************/
+
+typedef struct {
+ struct wmxsdk *wmxsdk;
+ WIMAX_API_DEVICE_STATUS new_status;
+ WIMAX_API_DEVICE_STATUS old_status;
+ WIMAX_API_STATUS_REASON reason;
+} StateChangeInfo;
+
+static gboolean
+state_change_handler(gpointer user_data)
+{
+ StateChangeInfo *info = user_data;
+
+ if (info->wmxsdk->state_change_cb) {
+ info->wmxsdk->state_change_cb(info->wmxsdk,
+ info->new_status,
+ info->old_status,
+ info->reason,
+ info->wmxsdk->callback_data);
+ }
+ wmxsdk_unref(info->wmxsdk);
+ memset(info, 0, sizeof(*info));
+ free(info);
+ return FALSE;
+}
+
+static void
+_schedule_state_change(struct wmxsdk *wmxsdk,
+ WIMAX_API_DEVICE_STATUS new_status,
+ WIMAX_API_DEVICE_STATUS old_status,
+ WIMAX_API_STATUS_REASON reason)
+{
+ StateChangeInfo *info;
+
+ info = malloc(sizeof (*info));
+ if (!info)
+ return;
+
+ memset(info, 0, sizeof(*info));
+ info->wmxsdk = wmxsdk;
+ info->new_status = new_status;
+ info->old_status = old_status;
+ info->reason = reason;
+
+ wmxsdk_ref(wmxsdk);
+ g_idle_add(state_change_handler, info);
+}
+
+typedef struct {
+ struct wmxsdk *wmxsdk;
+ WIMAX_API_MEDIA_STATUS media_status;
+} MediaStatusInfo;
+
+static gboolean
+media_status_change_handler(gpointer user_data)
+{
+ MediaStatusInfo *info = user_data;
+
+ if (info->wmxsdk->media_status_cb) {
+ info->wmxsdk->media_status_cb(info->wmxsdk,
+ info->media_status,
+ info->wmxsdk->callback_data);
+ }
+ wmxsdk_unref(info->wmxsdk);
+ memset(info, 0, sizeof(*info));
+ free(info);
+ return FALSE;
+}
+
+static void
+_schedule_media_status_change(struct wmxsdk *wmxsdk,
+ WIMAX_API_MEDIA_STATUS media_status)
+{
+ MediaStatusInfo *info;
+
+ info = malloc(sizeof (*info));
+ if (!info)
+ return;
+
+ memset(info, 0, sizeof(*info));
+ info->wmxsdk = wmxsdk;
+ info->media_status = media_status;
+
+ wmxsdk_ref(wmxsdk);
+ g_idle_add(media_status_change_handler, info);
+}
+
+typedef struct {
+ struct wmxsdk *wmxsdk;
+ WIMAX_API_NETWORK_CONNECTION_RESP result;
+} ConnectResultInfo;
+
+static gboolean
+connect_result_handler(gpointer user_data)
+{
+ ConnectResultInfo *info = user_data;
+
+ if (info->wmxsdk->connect_result_cb) {
+ info->wmxsdk->connect_result_cb(info->wmxsdk,
+ info->result,
+ info->wmxsdk->callback_data);
+ }
+ wmxsdk_unref(info->wmxsdk);
+ memset(info, 0, sizeof(*info));
+ free(info);
+ return FALSE;
+}
+
+static void
+_schedule_connect_result(struct wmxsdk *wmxsdk,
+ WIMAX_API_NETWORK_CONNECTION_RESP resp)
+{
+ ConnectResultInfo *info;
+
+ info = malloc(sizeof (*info));
+ if (!info)
+ return;
+
+ memset(info, 0, sizeof(*info));
+ info->wmxsdk = wmxsdk;
+ info->result = resp;
+
+ wmxsdk_ref(wmxsdk);
+ g_idle_add(connect_result_handler, info);
+}
+
+typedef struct {
+ struct wmxsdk *wmxsdk;
+ WIMAX_API_NSP_INFO_EX *nsps;
+ guint num_nsps;
+} ScanResultInfo;
+
+static gboolean
+scan_result_handler(gpointer user_data)
+{
+ ScanResultInfo *info = user_data;
+
+ if (info->wmxsdk->scan_result_cb) {
+ info->wmxsdk->scan_result_cb(info->wmxsdk,
+ info->nsps,
+ info->num_nsps,
+ info->wmxsdk->callback_data);
+ }
+ wmxsdk_unref(info->wmxsdk);
+ free(info->nsps);
+ memset(info, 0, sizeof(*info));
+ free(info);
+ return FALSE;
+}
+
+static void
+_schedule_scan_result(struct wmxsdk *wmxsdk,
+ WIMAX_API_NSP_INFO_EX *nsps,
+ guint num_nsps)
+{
+ ScanResultInfo *info;
+ size_t nsps_size;
+ int i, tmp;
+
+ info = malloc(sizeof (*info));
+ if (!info)
+ return;
+
+ memset(info, 0, sizeof(*info));
+ info->wmxsdk = wmxsdk;
+
+ nsps_size = num_nsps * sizeof (WIMAX_API_NSP_INFO_EX);
+ info->nsps = malloc(nsps_size);
+ memcpy(info->nsps, nsps, nsps_size);
+ info->num_nsps = num_nsps;
+
+ /* CAPI may report link quality as zero -- if it does check if it is a bug
+ * by computing it based on CINR. If it is different, use the computed one.
+ */
+ for (i = 0; i < num_nsps; i++) {
+ WIMAX_API_NSP_INFO_EX *nsp = &info->nsps[i];
+
+ if (nsp->linkQuality == 0) {
+ tmp = cinr_to_percentage(nsp->CINR - 10);
+ if (tmp != nsp->linkQuality)
+ nsp->linkQuality = tmp;
+ }
+ }
+
+ wmxsdk_ref(wmxsdk);
+ g_idle_add(scan_result_handler, info);
+}
+
+static gboolean
+removed_handler(gpointer user_data)
+{
+ struct wmxsdk *wmxsdk = user_data;
+
+ if (wmxsdk->removed_cb)
+ wmxsdk->removed_cb(wmxsdk, wmxsdk->callback_data);
+ wmxsdk_unref(wmxsdk);
+ return FALSE;
+}
+
+static void
+_schedule_removed(struct wmxsdk *wmxsdk)
+{
+ wmxsdk_ref(wmxsdk);
+ g_idle_add(removed_handler, wmxsdk);
+}
+
+/****************************************************************/
+
+/*
+ * Convert a WiMAX API status to an string.
+ */
+const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status)
+{
+ switch (status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ return "uninitialized";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ return "rf off";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ return "rf off (hard-block)";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ return "rf off (soft-block)";
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ return "ready";
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ return "scanning";
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ return "connecting";
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ return "connected";
+ default:
+ return "unknown";
+ }
+}
+
+const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason)
+{
+ switch (reason) {
+ case WIMAX_API_STATUS_REASON_Normal:
+ return "normal";
+
+ /**< Failed to complete NW entry with the selected operator (unspecified reason). */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_to_NW:
+ return "unspecified failure";
+
+ /**< Failed to complete ranging */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_Ranging:
+ return "ranging failed";
+
+ /**< SBC phase failed */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_SBC:
+ return "sbc failed";
+
+ /**< Security error. EAP authentication failed device level */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_EAP_AUTH_Device:
+ return "EAP device auth failed";
+
+ /**< Security error. EAP authentication failed user level */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_EAP_AUTH_user:
+ return "EAP user auth failed";
+
+ /**< Security error. Handshake failed */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_3_Way_Handshake:
+ return "3 way handshake failed";
+
+ /**< Registration failed */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_REG:
+ return "registration failed";
+
+ /**< Failed to initialize the data path (failed to perform DSA to one UL and one DL SFs). */
+ case WIMAX_API_STATUS_REASON_Fail_to_connect_datapath:
+ return "datapath failed";
+
+ default:
+ return "unknown";
+ }
+}
+
+const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status)
+{
+ switch (status) {
+ case WIMAX_API_MEDIA_STATUS_LINK_UP:
+ return "link-up";
+ case WIMAX_API_MEDIA_STATUS_LINK_DOWN:
+ return "link-down";
+ case WIMAX_API_MEDIA_STATUS_LINK_RENEW:
+ return "link-renew";
+ default:
+ return "unknown";
+ }
+}
+
+/*
+ * Get the device's status from the device
+ *
+ * Does NOT cache the result
+ * Does NOT trigger a state change in NetworkManager
+ *
+ * Returns < 0 errno code on error, status code if ok.
+ */
+static WIMAX_API_DEVICE_STATUS iwmx_sdk_get_device_status(struct wmxsdk *wmxsdk)
+{
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ WIMAX_API_DEVICE_STATUS dev_status;
+ WIMAX_API_CONNECTION_PROGRESS_INFO pi;
+
+ r = GetDeviceStatus(&wmxsdk->device_id, &dev_status, &pi);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot read device state: %d (%s)", r, errstr);
+ dev_status = -EIO;
+ }
+ return dev_status;
+}
+
+/*
+ * Get the device's status from the device but return a string describing it
+ *
+ * Same conditions as iwmx_sdk_get_device_status().
+ */
+static const char *iwmx_sdk_get_device_status_str(struct wmxsdk *wmxsdk)
+{
+ const char *result;
+ WIMAX_API_DEVICE_STATUS dev_status;
+
+ dev_status = iwmx_sdk_get_device_status(wmxsdk);
+ if ((int) dev_status < 0)
+ result = "cannot read device state";
+ else
+ result = iwmx_sdk_dev_status_to_str(dev_status);
+ return result;
+}
+
+/*
+ * If the device is connected but we don't know about the network,
+ * create the knowledge of it.
+ *
+ * Asks the WiMAX API to report which NSP we are connected to and we
+ * create/update a network_el in the device's network list. Then
+ * return it.
+ *
+ * Returns NULL on error.
+ *
+ */
+WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk)
+{
+ WIMAX_API_CONNECTED_NSP_INFO_EX *nsp_info = NULL;
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ nsp_info = malloc(sizeof (*nsp_info));
+ if (!nsp_info) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: cannot allocate NSP info");
+ return NULL;
+ }
+
+ r = GetConnectedNSPEx(&wmxsdk->device_id, nsp_info);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get connected NSP info: %d (%s)", r, errstr);
+ free (nsp_info);
+ nsp_info = NULL;
+ } else {
+ /* Migth be 0 sometimes; fix that up */
+ if (nsp_info->linkQuality == 0) {
+ int linkq_expected = cinr_to_percentage(nsp_info->CINR - 10);
+ if (linkq_expected != nsp_info->linkQuality)
+ nsp_info->linkQuality = linkq_expected;
+ }
+ }
+
+ return nsp_info;
+}
+
+/*
+ * Asks the WiMAX API to report current link statistics.
+ *
+ * Returns NULL on error.
+ *
+ */
+WIMAX_API_LINK_STATUS_INFO_EX *iwmx_sdk_get_link_status_info(struct wmxsdk *wmxsdk)
+{
+ WIMAX_API_LINK_STATUS_INFO_EX *stats = NULL;
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ /* Only report if connected */
+ if (iwmxsdk_status_get(wmxsdk) < WIMAX_API_DEVICE_STATUS_Connecting) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: cannot get link status info unless connected");
+ return NULL;
+ }
+
+ stats = malloc(sizeof (*stats));
+ if (!stats) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: cannot allocate links status info");
+ return NULL;
+ }
+
+ r = GetLinkStatusEx(&wmxsdk->device_id, stats);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get link status info: %d (%s)", r, errstr);
+ free (stats);
+ stats = NULL;
+ }
+
+ return stats;
+}
+
+/*
+ * Callback for a RF State command
+ *
+ * Called by the WiMAX API when a command sent to change the RF state
+ * is completed. This is just a confirmation of what happened with the
+ * command.
+ *
+ * We don't do anything, as when the device changes state, the state
+ * change callback is called and that will fiddle with the NetworkManager
+ * internals.
+ */
+static void __iwmx_sdk_rf_state_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_RF_STATE rf_state)
+{
+ nm_log_dbg(LOGD_WIMAX, "rf_state changed to %d", rf_state);
+}
+
+/*
+ * Turn the radio on or off
+ *
+ * First it checks that we are in the right state before doing
+ * anything; there might be no need to do anything.
+ *
+ * Issue a command to the WiMAX API, wait for a callback confirming it
+ * is done. Sometimes the callback is missed -- in that case, do force
+ * a state change evaluation.
+ *
+ * Frustration note:
+ *
+ * Geezoos efing Xist, they make difficult even the most simple
+ * of the operations
+ *
+ * This thing is definitely a pain. If the radio is ON already
+ * and you switch it on again...well, there is no way to tell
+ * because you don't get a callback saying it basically
+ * suceeded. But on the other hand, if the thing was in a
+ * different state and action needs to be taken, you have to wait
+ * for a callback to confirm it's done. However, there is also an
+ * state change callback, which is almost the same, so now you
+ * have to handle things in two "unrelated" threads of execution.
+ *
+ * How the shpx are you expected to tell the difference? Check
+ * status first? On timeout? Nice gap (eighteen wheeler size) for
+ * race conditions.
+ */
+int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state)
+{
+ int result;
+
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+ WIMAX_API_DEVICE_STATUS dev_status;
+
+ g_assert(rf_state == WIMAX_API_RF_ON || rf_state == WIMAX_API_RF_OFF);
+
+ /* Guess what the current radio state is; if it is ON
+ * already, don't redo it. */
+ dev_status = iwmx_sdk_get_device_status(wmxsdk);
+ if ((int) dev_status < 0) {
+ result = dev_status;
+ goto error_get_status;
+ }
+ switch (dev_status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ result = -EINVAL;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ nm_log_err(LOGD_WIMAX, "wmxsdk: cannot turn on radio: hw switch is off");
+ result = -EPERM;
+ goto error_cant_do;
+ break;
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ if (rf_state == WIMAX_API_RF_OFF) {
+ result = 0;
+ nm_log_dbg(LOGD_WIMAX, "radio is already off");
+ goto out_done;
+ }
+ break;
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ if (rf_state == WIMAX_API_RF_ON) {
+ result = 0;
+ nm_log_dbg(LOGD_WIMAX, "radio is already on");
+ goto out_done;
+ }
+ break;
+ default:
+ g_assert(1);
+ }
+ /* Ok, flip the radio */
+ r = CmdControlPowerManagement(&wmxsdk->device_id, rf_state);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot flip radio to %d: %d (%s) [device is in state %s]",
+ rf_state, r, errstr, iwmx_sdk_get_device_status_str(wmxsdk));
+ result = -EIO;
+ } else
+ result = -EINPROGRESS;
+out_done:
+error_cant_do:
+error_get_status:
+ return result;
+}
+
+/*
+ * Read the cached device status
+ */
+WIMAX_API_DEVICE_STATUS iwmxsdk_status_get(struct wmxsdk *wmxsdk)
+{
+ WIMAX_API_DEVICE_STATUS status;
+
+ g_mutex_lock(wmxsdk->status_mutex);
+ status = wmxsdk->status;
+ g_mutex_unlock(wmxsdk->status_mutex);
+ return status;
+}
+
+/*
+ * Callback for a Connect command
+ *
+ * Called by the WiMAX API when a command sent to connect is
+ * completed. This is just a confirmation of what happened with the
+ * command.
+ *
+ * WE DON'T DO MUCH HERE -- the real meat happens when a state change
+ * callback is sent, where we detect we move to connected state (or
+ * from disconnecting to something else); the state change callback is
+ * called and that will fiddle with the NetworkManager internals.
+ */
+static void __iwmx_sdk_connect_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NETWORK_CONNECTION_RESP resp)
+{
+ WIMAX_API_DEVICE_STATUS status;
+ struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
+
+ status = iwmxsdk_status_get(wmxsdk);
+ if (resp == WIMAX_API_CONNECTION_SUCCESS) {
+ if (status != WIMAX_API_DEVICE_STATUS_Data_Connected) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: error: connect worked, but state"
+ " didn't change (now it is %d [%s])",
+ status,
+ iwmx_sdk_dev_status_to_str(status));
+ }
+ } else {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: failed to connect (status %d: %s)",
+ status, iwmx_sdk_dev_status_to_str(status));
+ }
+
+ _schedule_connect_result(wmxsdk, resp);
+}
+
+/*
+ * Connect to a network
+ *
+ * This function starts the connection process to a given network;
+ * when the device changes status, the status change callback will
+ * tell NetworkManager if the network is finally connected or not.
+ *
+ * One of the reasons it is done like that is to allow external tools
+ * to control the device and the plugin just passing the status so
+ * NetworkManager displays the right info.
+ */
+int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name)
+{
+ int result = 0;
+
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+ WIMAX_API_DEVICE_STATUS dev_status;
+ char sdk_name[MAX_SIZE_OF_NSP_NAME];
+
+ g_mutex_lock(wmxsdk->connect_mutex);
+ /* Guess what the current radio state is; if it is ON
+ * already, don't redo it. */
+ dev_status = iwmxsdk_status_get(wmxsdk);
+ if ((int) dev_status < 0) {
+ result = dev_status;
+ goto error_get_status;
+ }
+ switch (dev_status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ nm_log_err(LOGD_WIMAX, "wmxsdk: SW BUG? HW is uninitialized");
+ result = -EINVAL;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot connect: radio is off");
+ result = -EPERM;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ break;
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ nm_log_dbg(LOGD_WIMAX, "Connect already pending, waiting for it");
+ result = -EINPROGRESS;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ nm_log_err(LOGD_WIMAX, "wmxsdk: BUG? need to disconnect?");
+ result = -EINVAL;
+ goto error_cant_do;
+ default:
+ g_assert(1);
+ }
+
+ /* The SDK treats the network name as wchar_t* while the contents are
+ * actually just UTF-8... WTF? Hand it a full buffer to work around
+ * boundary cases where the NSP name contains an odd # of characters.
+ */
+ memset(sdk_name, 0, sizeof (sdk_name));
+ memcpy(sdk_name, nsp_name, strlen (nsp_name));
+
+ /* Ok, do the connection, wait for a callback */
+ r = CmdConnectToNetwork(&wmxsdk->device_id, &sdk_name[0], 0, 0);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot connect to network %s: %d (%s) - device is in state '%s'",
+ nsp_name, r, errstr,
+ iwmx_sdk_get_device_status_str(wmxsdk));
+ result = -EIO;
+ }
+
+error_cant_do:
+error_get_status:
+ g_mutex_unlock(wmxsdk->connect_mutex);
+ return result;
+}
+
+/*
+ * Callback for a Disconnect command
+ *
+ * Called by the WiMAX API when a command sent to connect is
+ * completed. This is just a confirmation of what happened with the
+ * command.
+ *
+ * When the device changes state, the state change callback is called
+ * and that will fiddle with the NetworkManager internals.
+ *
+ * We just update the result of the command and wake up anybody who is
+ * waiting for this conditional variable.
+ */
+static void __iwmx_sdk_disconnect_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NETWORK_CONNECTION_RESP resp)
+{
+ struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
+ WIMAX_API_DEVICE_STATUS status;
+
+ status = iwmxsdk_status_get(wmxsdk);
+ if (resp == WIMAX_API_CONNECTION_SUCCESS) {
+ if (status == WIMAX_API_DEVICE_STATUS_Data_Connected) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: error: disconnect worked, "
+ "but state didn't change (now it is %d [%s])", status,
+ iwmx_sdk_dev_status_to_str(status));
+ }
+ } else
+ nm_log_err(LOGD_WIMAX, "wmxsdk: failed to disconnect (status %d: %s)",
+ status, iwmx_sdk_dev_status_to_str(status));
+}
+
+/*
+ * Disconnect from a network
+ *
+ * This function tells the device to disconnect; the state change
+ * callback will take care of inform NetworkManager's internals.
+ */
+int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk)
+{
+ int result;
+
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+ WIMAX_API_DEVICE_STATUS dev_status;
+
+ g_mutex_lock(wmxsdk->connect_mutex);
+ /* Guess what the current radio state is; if it is ON
+ * already, don't redo it. */
+ dev_status = iwmx_sdk_get_device_status(wmxsdk);
+ if ((int) dev_status < 0) {
+ result = dev_status;
+ goto error_get_status;
+ }
+ switch (dev_status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ nm_log_err(LOGD_WIMAX, "wmxsdk: SW BUG? HW is uninitialized");
+ result = -EINVAL;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, radio is off; ignoring");
+ result = 0;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, already disconnected; ignoring");
+ result = 0;
+ goto error_cant_do;
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ break;
+ default:
+ g_assert(1);
+ }
+ /* Ok, flip the radio */
+ r = CmdDisconnectFromNetwork(&wmxsdk->device_id);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot disconnect from network: %d (%s)", r, errstr);
+ result = -EIO;
+ } else
+ result = -EINPROGRESS;
+error_cant_do:
+error_get_status:
+ g_mutex_unlock(wmxsdk->connect_mutex);
+ return result;
+}
+
+/*
+ * Turn fast reconnect capability on/off
+ *
+ * This function tells wimaxd to turn fast reconnect on or off.
+ */
+int iwmx_sdk_set_fast_reconnect_enabled(struct wmxsdk *wmxsdk, int enabled)
+{
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ r = SetFastReconnectCapabilityStatus(&wmxsdk->device_id, !!enabled);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot set fast reconnect to %d: %d (%s)",
+ enabled, r, errstr);
+ return -EIO;
+ }
+ return 0;
+}
+
+static void __iwmx_sdk_media_status_update_cb (WIMAX_API_DEVICE_ID_P device_id,
+ WIMAX_API_MEDIA_STATUS mediaStatus)
+{
+ struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
+
+ /* Ignore redundant LINK_UP events */
+ if ( mediaStatus == WIMAX_API_MEDIA_STATUS_LINK_UP
+ && wmxsdk->media_status == WIMAX_API_MEDIA_STATUS_LINK_UP)
+ return;
+
+ wmxsdk->media_status = mediaStatus;
+
+ nm_log_dbg(LOGD_WIMAX, "wmxsdk: media status change to (%d) %s",
+ mediaStatus, iwmx_sdk_media_status_to_str (mediaStatus));
+
+ _schedule_media_status_change(wmxsdk, mediaStatus);
+}
+
+/*
+ * Callback for state change messages
+ *
+ * Just pass them to the state transition handler
+ */
+static void __iwmx_sdk_state_change_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_DEVICE_STATUS status,
+ WIMAX_API_STATUS_REASON reason,
+ WIMAX_API_CONNECTION_PROGRESS_INFO pi)
+{
+ struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
+ WIMAX_API_DEVICE_STATUS old_status;
+
+ nm_log_dbg(LOGD_WIMAX, "wmxsdk: state change to (%d) %s reason (%d) %s",
+ status, iwmx_sdk_dev_status_to_str (status),
+ reason, iwmx_sdk_reason_to_str (reason));
+
+ g_mutex_lock(wmxsdk->status_mutex);
+ old_status = wmxsdk->status;
+ wmxsdk->status = status;
+ g_mutex_unlock(wmxsdk->status_mutex);
+
+ _schedule_state_change(wmxsdk, status, old_status, reason);
+}
+
+/*
+ * Called by _iwmx_sdk_*scan_cb() when [wide or preferred] scan results
+ * are available.
+ *
+ * From here we update NetworkManager's idea of which networks are available.
+ */
+static void __iwmx_sdk_scan_common_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NSP_INFO_EX *nsp_list,
+ UINT32 nsp_list_size)
+{
+ struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id);
+
+ g_static_mutex_lock(&wmxsdk->network_mutex);
+ _schedule_scan_result(wmxsdk, nsp_list, nsp_list_size);
+ g_static_mutex_unlock(&wmxsdk->network_mutex);
+}
+
+/*
+ * Called by the WiMAX API when we get a wide scan result
+ *
+ * We treat them same as wide, so we just call that.
+ */
+static void __iwmx_sdk_wide_scan_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NSP_INFO_EX *nsp_list,
+ UINT32 nsp_list_size)
+{
+ __iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size);
+}
+
+/*
+ * Called by the WiMAX API when we get a normal (non wide) scan result
+ *
+ * We treat them same as wide, so we just call that.
+ */
+static void __iwmx_sdk_scan_cb(WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NSP_INFO_EX *nsp_list,
+ UINT32 nsp_list_size, UINT32 searchProgress)
+{
+ __iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size);
+}
+
+/*
+ * Called to ask the device to scan for networks
+ *
+ * We don't really scan as the WiMAX SDK daemon scans in the
+ * background for us. We just get the results and hand them back via
+ * the scan_result_cb callback.
+ */
+int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk)
+{
+ int result;
+
+ UINT32 nsp_list_length = 10;
+ WIMAX_API_NSP_INFO_EX nsp_list[10]; /* FIXME: up to 32? */
+
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ r = GetNetworkListEx(&wmxsdk->device_id, nsp_list, &nsp_list_length);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get network list: %d (%s)", r, errstr);
+ result = -EIO;
+ goto error_scan;
+ }
+
+ if (nsp_list_length == 0) {
+ nm_log_dbg(LOGD_WIMAX, "no networks");
+ } else
+ __iwmx_sdk_scan_common_cb(&wmxsdk->device_id, nsp_list,
+ nsp_list_length);
+ result = 0;
+error_scan:
+ return result;
+}
+
+/*
+ * Initialize the WiMAX API, register with it, setup callbacks
+ *
+ */
+static int iwmx_sdk_setup(struct wmxsdk *wmxsdk)
+{
+ int result, status;
+
+ WIMAX_API_RET r;
+
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ result = -ENFILE;
+
+ /* device_id initialized by iwmx_sdk_dev_add */
+
+ r = WiMaxDeviceOpen(&wmxsdk->device_id);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot open device: %d (%s)", r, errstr);
+ goto error_wimaxdeviceopen;
+ }
+
+ /*
+ * We scan in auto mode (in the background)
+ *
+ * Otherwise is messy -- if we have NetworkManager triggering a scan
+ * when we call iwmx_nm_scan() -> iwmx_sdk_scan(), most of the
+ * times that causes a race condition when the UI asks for a
+ * scan right before displaying the network menu. As there is
+ * no way to cancel an ongoing scan before connecting, we are
+ * stuck. So we do auto bg and have iwmx_sdk_scan() just return
+ * the current network list.
+ */
+ r = SetConnectionMode(&wmxsdk->device_id,
+ WIMAX_API_CONNECTION_AUTO_SCAN_MANUAL_CONNECT);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot set connectin mode to manual: %d (%s)", r, errstr);
+ goto error_connection_mode;
+ }
+
+ r = SubscribeControlPowerManagement(&wmxsdk->device_id,
+ __iwmx_sdk_rf_state_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to radio change events: %u (%s)", r, errstr);
+ result = -EIO;
+ goto error_subscribe_rf_state;
+ }
+
+ r = SubscribeDeviceStatusChange(&wmxsdk->device_id,
+ __iwmx_sdk_state_change_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to state chaneg events: %d (%s)", r, errstr);
+ goto error_subscribe_state_change;
+ }
+
+ r = SubscribeNetworkSearchWideScanEx(&wmxsdk->device_id,
+ __iwmx_sdk_wide_scan_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to wide scan events: %d (%s)", r, errstr);
+ goto error_subscribe_wide_scan;
+ }
+ r = SubscribeNetworkSearchEx(&wmxsdk->device_id, __iwmx_sdk_scan_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to scan events: %d (%s)", r, errstr);
+ goto error_subscribe_scan;
+ }
+
+ r = SubscribeConnectToNetwork(&wmxsdk->device_id,
+ __iwmx_sdk_connect_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to connect events: %d (%s)", r, errstr);
+ goto error_subscribe_connect;
+ }
+
+ r = SubscribeDisconnectToNetwork(&wmxsdk->device_id,
+ __iwmx_sdk_disconnect_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to disconnect events: %d (%s)", r, errstr);
+ goto error_subscribe_disconnect;
+ }
+
+ r = SubscribeMediaStatusUpdate(&wmxsdk->device_id, __iwmx_sdk_media_status_update_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to media status events: %d (%s)", r, errstr);
+ goto error_subscribe_media_status;
+ }
+
+ status = iwmx_sdk_get_device_status(wmxsdk);
+ if ((int) status < 0)
+ status = WIMAX_API_DEVICE_STATUS_UnInitialized;
+
+ g_mutex_lock(wmxsdk->status_mutex);
+ wmxsdk->status = status;
+ g_mutex_unlock(wmxsdk->status_mutex);
+
+ _schedule_state_change(wmxsdk,
+ status,
+ WIMAX_API_DEVICE_STATUS_UnInitialized,
+ WIMAX_API_STATUS_REASON_Normal);
+
+ return 0;
+
+ UnsubscribeMediaStatusUpdate(&wmxsdk->device_id);
+error_subscribe_media_status:
+ UnsubscribeDisconnectToNetwork(&wmxsdk->device_id);
+error_subscribe_disconnect:
+ UnsubscribeConnectToNetwork(&wmxsdk->device_id);
+error_subscribe_connect:
+ UnsubscribeNetworkSearchEx(&wmxsdk->device_id);
+error_subscribe_scan:
+ UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id);
+error_subscribe_wide_scan:
+ UnsubscribeDeviceStatusChange(&wmxsdk->device_id);
+error_subscribe_state_change:
+ UnsubscribeControlPowerManagement(&wmxsdk->device_id);
+error_subscribe_rf_state:
+error_connection_mode:
+ WiMaxDeviceClose(&wmxsdk->device_id);
+error_wimaxdeviceopen:
+ return result;
+}
+
+/*
+ * Called when a device is torn down
+ *
+ * Cleanup all that is done in iwmx_sdk_setup(). Remove callbacks,
+ * unregister from the WiMAX API.
+ */
+static void iwmx_sdk_remove(struct wmxsdk *wmxsdk)
+{
+ UnsubscribeMediaStatusUpdate(&wmxsdk->device_id);
+ UnsubscribeDisconnectToNetwork(&wmxsdk->device_id);
+ UnsubscribeConnectToNetwork(&wmxsdk->device_id);
+ UnsubscribeNetworkSearchEx(&wmxsdk->device_id);
+ UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id);
+ UnsubscribeDeviceStatusChange(&wmxsdk->device_id);
+ UnsubscribeControlPowerManagement(&wmxsdk->device_id);
+ WiMaxDeviceClose(&wmxsdk->device_id);
+}
+
+void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk,
+ WimaxStateChangeFunc state_change_cb,
+ WimaxMediaStatusFunc media_status_cb,
+ WimaxConnectResultFunc connect_result_cb,
+ WimaxScanResultFunc scan_result_cb,
+ WimaxRemovedFunc removed_cb,
+ void *user_data)
+{
+ wmxsdk->state_change_cb = state_change_cb;
+ wmxsdk->media_status_cb = media_status_cb;
+ wmxsdk->connect_result_cb = connect_result_cb;
+ wmxsdk->scan_result_cb = scan_result_cb;
+ wmxsdk->removed_cb = removed_cb;
+ wmxsdk->callback_data = user_data;
+}
+
+/* Initialize a [zeroed] struct wmxsdk */
+static struct wmxsdk *wmxsdk_new(void)
+{
+ struct wmxsdk *wmxsdk;
+
+ wmxsdk = malloc(sizeof(*wmxsdk));
+ if (wmxsdk) {
+ memset(wmxsdk, 0, sizeof(*wmxsdk));
+
+ wmxsdk->refcount = 1;
+ g_static_mutex_init(&wmxsdk->network_mutex);
+
+ wmxsdk->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
+ wmxsdk->status_mutex = g_mutex_new();
+ g_assert(wmxsdk->status_mutex);
+
+ wmxsdk->connect_mutex = g_mutex_new();
+ g_assert(wmxsdk->connect_mutex);
+ }
+ return wmxsdk;
+}
+
+struct wmxsdk *wmxsdk_ref(struct wmxsdk *wmxsdk)
+{
+ g_atomic_int_add(&wmxsdk->refcount, 1);
+ return wmxsdk;
+}
+
+void wmxsdk_unref(struct wmxsdk *wmxsdk)
+{
+ if (g_atomic_int_dec_and_test(&wmxsdk->refcount)) {
+ g_mutex_free(wmxsdk->status_mutex);
+ g_mutex_free(wmxsdk->connect_mutex);
+ memset(wmxsdk, 0, sizeof(*wmxsdk));
+ free(wmxsdk);
+ }
+}
+
+static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name)
+{
+ int ifindex;
+ struct wmxsdk *wmxsdk;
+ const char *s;
+
+ if (idx >= IWMX_SDK_DEV_MAX) {
+ nm_log_err(LOGD_WIMAX, "BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)", idx, IWMX_SDK_DEV_MAX);
+ goto error_bug;
+ }
+ if (g_iwmx_sdk_devs[idx] != NULL) {
+ nm_log_err(LOGD_WIMAX, "BUG! device index %u already enumerated?", idx);
+ goto error_bug;
+ }
+
+ wmxsdk = wmxsdk_new();
+ if (wmxsdk == NULL) {
+ nm_log_err(LOGD_WIMAX, "Can't allocate %zu bytes", sizeof(*wmxsdk));
+ goto error_bug;
+ }
+
+ /*
+ * This depends on a hack in the WiMAX Network Service; it has
+ * to return, as part of the device name, a string "if:IFNAME"
+ * where the OS's device name is stored.
+ */
+ s = strstr(name, "if:");
+ if (s == NULL
+ || sscanf(s, "if:%15[^ \f\n\r\t\v]", wmxsdk->ifname) != 1) {
+ nm_log_err(LOGD_WIMAX, "Cannot extract network interface name off '%s'",
+ name);
+ goto error_noifname;
+ }
+ nm_log_dbg(LOGD_WIMAX, "network interface name: '%s'", wmxsdk->ifname);
+
+ ifindex = if_nametoindex(wmxsdk->ifname);
+ if (ifindex <= 0) {
+ nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot find interface index", wmxsdk->ifname);
+ goto error_noifname;
+ }
+
+ strncpy(wmxsdk->name, name, sizeof(wmxsdk->name));
+ wmxsdk->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
+ wmxsdk->device_id.deviceIndex = api_idx;
+
+ if (iwmx_sdk_setup(wmxsdk) != 0) {
+ nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot set up interface", wmxsdk->ifname);
+ goto error_setup;
+ }
+
+ g_iwmx_sdk_devs[idx] = wmxsdk;
+
+ /* Notify listeners of new devices */
+ iwmx_sdk_call_new_callbacks (wmxsdk);
+ return;
+
+error_setup:
+error_noifname:
+ wmxsdk_unref(wmxsdk);
+error_bug:
+ return;
+}
+
+static void iwmx_sdk_dev_rm(unsigned idx)
+{
+ struct wmxsdk *wmxsdk;
+
+ if (idx >= IWMX_SDK_DEV_MAX) {
+ nm_log_err(LOGD_WIMAX, "BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)", idx, IWMX_SDK_DEV_MAX);
+ return;
+ }
+
+ wmxsdk = g_iwmx_sdk_devs[idx];
+ _schedule_removed(wmxsdk);
+ iwmx_sdk_remove(wmxsdk);
+ wmxsdk_unref(wmxsdk);
+ g_iwmx_sdk_devs[idx] = NULL;
+}
+
+static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid,
+ BOOL presence)
+{
+ unsigned int cnt;
+ WIMAX_API_RET r;
+ WIMAX_API_HW_DEVICE_ID device_id_list[5];
+ UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ g_static_mutex_lock(&add_remove_mutex);
+
+ nm_log_dbg(LOGD_WIMAX, "cb: handle %u index #%u is %d", devid->sdkHandle,
+ devid->deviceIndex, presence);
+
+ r = GetListDevice(devid, device_id_list, &device_id_list_size);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(devid, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr);
+ goto out;
+ }
+
+ if (device_id_list_size == 0) {
+ nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported");
+ } else {
+ for (cnt = 0; cnt < device_id_list_size; cnt++) {
+ WIMAX_API_HW_DEVICE_ID *dev =
+ device_id_list + cnt;
+ nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt,
+ dev->deviceIndex, dev->deviceName);
+ }
+ }
+
+ if (presence) {
+ WIMAX_API_HW_DEVICE_ID *dev;
+
+ /* Make sure the wimax NS isn't lying to us */
+ if (device_id_list_size < devid->deviceIndex) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)",
+ devid->deviceIndex, device_id_list_size);
+ goto out;
+ }
+
+ /* Add the device to our internal list */
+ dev = device_id_list + devid->deviceIndex;
+ iwmx_sdk_dev_add(devid->deviceIndex, dev->deviceIndex, dev->deviceName);
+ } else {
+ /* Remove the device from our internal list */
+ cnt = deviceid_to_index(devid);
+ if (cnt >= 0)
+ iwmx_sdk_dev_rm(cnt);
+ }
+
+out:
+ g_static_mutex_unlock(&add_remove_mutex);
+}
+
+/*
+ * Initialize the WiMAX API, register with it, setup callbacks for
+ * device coming up / dissapearing
+ */
+int iwmx_sdk_api_init(void)
+{
+ int result;
+ unsigned int cnt;
+ WIMAX_API_RET r;
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ WIMAX_API_HW_DEVICE_ID device_id_list[5];
+ UINT32 device_id_list_size = ARRAY_SIZE(device_id_list);
+
+ memset(&g_api, 0, sizeof(g_api));
+ g_api.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
+
+ result = -EIO;
+ r = WiMaxAPIOpen(&g_api);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&g_api, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: WiMaxAPIOpen failed with %d (%s)", r, errstr);
+ goto error_wimaxapiopen;
+ }
+
+ r = SubscribeDeviceInsertRemove(&g_api, iwmx_sdk_addremove_cb);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&g_api, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: insert/remove subscribe failed with %d (%s)", r, errstr);
+ goto error_close;
+ }
+
+ r = GetListDevice(&g_api, device_id_list, &device_id_list_size);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&g_api, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr);
+ goto error_close;
+ }
+ if (device_id_list_size < g_api.deviceIndex) {
+ nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)",
+ g_api.deviceIndex, device_id_list_size);
+ }
+
+ if (device_id_list_size == 0) {
+ nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported");
+ } else {
+ for (cnt = 0; cnt < device_id_list_size; cnt++) {
+ WIMAX_API_HW_DEVICE_ID *dev = device_id_list + cnt;
+ nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt, dev->deviceIndex, dev->deviceName);
+ iwmx_sdk_dev_add(cnt, dev->deviceIndex, dev->deviceName);
+ }
+ }
+ return 0;
+
+error_close:
+ WiMaxAPIClose(&g_api);
+error_wimaxapiopen:
+ return result;
+}
+
+void iwmx_sdk_api_exit(void)
+{
+ WIMAX_API_RET r;
+
+ char errstr[512];
+ UINT32 errstr_size = sizeof(errstr);
+
+ r = WiMaxAPIClose(&g_api);
+ if (r != WIMAX_API_RET_SUCCESS) {
+ GetErrorString(&g_api, r, errstr, &errstr_size);
+ nm_log_err(LOGD_WIMAX, "wmxsdk: WiMaxAPIClose failed with %d (%s)", r, errstr);
+ }
+ return;
+}
diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h
new file mode 100644
index 000000000..bd55679ab
--- /dev/null
+++ b/src/wimax/iwmxsdk.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ *
+ * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef IWMXSDK_H
+#define IWMXSDK_H
+
+#include <wimax/WiMaxType.h>
+#include <wimax/WiMaxTypesEx.h>
+#include <wimax/WiMaxAPIEx.h>
+
+struct wmxsdk;
+
+typedef void (*WimaxNewWmxsdkFunc) (struct wmxsdk *wmxsdk, void *user_data);
+
+typedef void (*WimaxStateChangeFunc) (struct wmxsdk *wmxsdk,
+ WIMAX_API_DEVICE_STATUS new_status,
+ WIMAX_API_DEVICE_STATUS old_status,
+ WIMAX_API_STATUS_REASON reason,
+ void *user_data);
+
+typedef void (*WimaxMediaStatusFunc) (struct wmxsdk *wmxsdk,
+ WIMAX_API_MEDIA_STATUS media_status,
+ void *user_data);
+
+typedef void (*WimaxConnectResultFunc) (struct wmxsdk *wmxsdk,
+ WIMAX_API_NETWORK_CONNECTION_RESP resp,
+ void *user_data);
+
+typedef void (*WimaxScanResultFunc) (struct wmxsdk *wmxsdk,
+ WIMAX_API_NSP_INFO_EX *nsps,
+ guint num_nsps,
+ void *user_data);
+
+typedef void (*WimaxRemovedFunc) (struct wmxsdk *wmxsdk, void *user_data);
+
+struct wmxsdk {
+ gint refcount;
+
+ WIMAX_API_DEVICE_ID device_id;
+
+ WimaxStateChangeFunc state_change_cb;
+ WimaxMediaStatusFunc media_status_cb;
+ WimaxConnectResultFunc connect_result_cb;
+ WimaxScanResultFunc scan_result_cb;
+ WimaxRemovedFunc removed_cb;
+ void *callback_data;
+
+ GStaticMutex network_mutex;
+
+ WIMAX_API_DEVICE_STATUS status;
+ WIMAX_API_MEDIA_STATUS media_status;
+ GMutex *status_mutex;
+
+ GMutex *connect_mutex;
+
+ char name[100];
+ char ifname[16];
+};
+
+struct wmxsdk *iwmx_sdk_get_wmxsdk_for_iface(const char *iface);
+
+struct wmxsdk *wmxsdk_ref(struct wmxsdk *wmxsdk);
+void wmxsdk_unref(struct wmxsdk *wmxsdk);
+
+/* Register/unregister callbacks when a new wmxsdk is set up */
+void iwmx_sdk_new_callback_register(WimaxNewWmxsdkFunc callback, void *user_data);
+void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_data);
+
+void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk,
+ WimaxStateChangeFunc state_change_cb,
+ WimaxMediaStatusFunc media_status_func,
+ WimaxConnectResultFunc connect_result_cb,
+ WimaxScanResultFunc scan_result_cb,
+ WimaxRemovedFunc removed_cb,
+ void *user_data);
+
+WIMAX_API_DEVICE_STATUS iwmxsdk_status_get(struct wmxsdk *wmxsdk);
+int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name);
+int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk);
+int iwmx_sdk_set_fast_reconnect_enabled(struct wmxsdk *wmxsdk, int enabled);
+WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk);
+WIMAX_API_LINK_STATUS_INFO_EX *iwmx_sdk_get_link_status_info(struct wmxsdk *wmxsdk);
+const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status);
+const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason);
+const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status);
+int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state);
+int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk);
+int iwmx_sdk_api_init(void);
+void iwmx_sdk_api_exit(void);
+
+#endif /* IWMXSDK_H */
diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c
new file mode 100644
index 000000000..12db7e272
--- /dev/null
+++ b/src/wimax/nm-device-wimax.c
@@ -0,0 +1,1566 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+
+#include <WiMaxAPI.h>
+#include <WiMaxAPIEx.h>
+
+#include "nm-device-wimax.h"
+#include "nm-wimax-util.h"
+#include "nm-logging.h"
+#include "nm-device-interface.h"
+#include "nm-device-private.h"
+#include "nm-system.h"
+#include "NetworkManagerUtils.h"
+#include "nm-properties-changed-signal.h"
+#include "nm-connection.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-wimax.h"
+#include "nm-utils.h"
+#include "nm-rfkill.h"
+#include "iwmxsdk.h"
+
+static gboolean impl_device_get_nsp_list (NMDeviceWimax *device, GPtrArray **list, GError **error);
+
+#include "nm-device-wimax-glue.h"
+
+static void device_interface_init (NMDeviceInterface *iface_class);
+
+G_DEFINE_TYPE_EXTENDED (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init))
+
+enum {
+ PROP_0,
+ PROP_HW_ADDRESS,
+ PROP_ACTIVE_NSP,
+ PROP_CENTER_FREQ,
+ PROP_RSSI,
+ PROP_CINR,
+ PROP_TX_POWER,
+ PROP_BSID,
+
+ LAST_PROP
+};
+
+enum {
+ NSP_ADDED,
+ NSP_REMOVED,
+ PROPERTIES_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define NM_DEVICE_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_DEVICE_WIMAX, \
+ NMDeviceWimaxPrivate))
+
+typedef struct {
+ gboolean disposed;
+
+ struct wmxsdk *sdk;
+ WIMAX_API_DEVICE_STATUS status;
+ gboolean connect_failed;
+
+ gboolean enabled;
+ gboolean wimaxd_enabled;
+ struct ether_addr hw_addr;
+ guint activation_timeout_id;
+
+ guint sdk_action_defer_id;
+
+ guint link_timeout_id;
+ guint poll_id;
+
+ GSList *nsp_list;
+ NMWimaxNsp *current_nsp;
+
+ /* interesting stuff when connected */
+ guint center_freq;
+ gint rssi;
+ gint cinr;
+ gint tx_power;
+ char *bsid;
+} NMDeviceWimaxPrivate;
+
+/***********************************************************/
+
+typedef enum
+{
+ NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0,
+ NM_WIMAX_ERROR_CONNECTION_INVALID,
+ NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE,
+ NM_WIMAX_ERROR_NSP_NOT_FOUND,
+} NMWimaxError;
+
+#define NM_WIMAX_ERROR (nm_wimax_error_quark ())
+#define NM_TYPE_WIMAX_ERROR (nm_wimax_error_get_type ())
+
+static GQuark
+nm_wimax_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("nm-wimax-error");
+ return quark;
+}
+
+/* This should really be standard. */
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+static GType
+nm_wimax_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* Connection was not a wired connection. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX, "ConnectionNotWimax"),
+ /* Connection was not a valid wired connection. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
+ /* Connection does not apply to this device. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
+ /* NSP not found in the scan list. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_NSP_NOT_FOUND, "NspNotFound"),
+ { 0, 0, 0 }
+ };
+ etype = g_enum_register_static ("NMWimaxError", values);
+ }
+ return etype;
+}
+
+/***********************************************************/
+
+void
+nm_device_wimax_get_hw_address (NMDeviceWimax *self, struct ether_addr *addr)
+{
+ NMDeviceWimaxPrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE_WIMAX (self));
+ g_return_if_fail (addr != NULL);
+
+ priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ memcpy (addr, &(priv->hw_addr), sizeof (struct ether_addr));
+}
+
+guint32
+nm_device_wimax_get_center_frequency (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->center_freq;
+}
+
+gint
+nm_device_wimax_get_rssi (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->rssi;
+}
+
+gint
+nm_device_wimax_get_cinr (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->cinr;
+}
+
+gint
+nm_device_wimax_get_tx_power (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->tx_power;
+}
+
+const char *
+nm_device_wimax_get_bsid (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), NULL);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->bsid;
+}
+
+static gboolean
+impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ GSList *iter;
+
+ *nsps = g_ptr_array_sized_new (g_slist_length (priv->nsp_list));
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ const char *path;
+
+ path = nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data));
+ if (path)
+ g_ptr_array_add (*nsps, g_strdup (path));
+ }
+
+ return TRUE;
+}
+
+static void
+set_current_nsp (NMDeviceWimax *self, NMWimaxNsp *new_nsp)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ NMWimaxNsp *old_nsp;
+ char *old_path = NULL;
+
+ old_nsp = priv->current_nsp;
+ if (old_nsp) {
+ old_path = g_strdup (nm_wimax_nsp_get_dbus_path (old_nsp));
+ priv->current_nsp = NULL;
+ }
+
+ if (new_nsp)
+ priv->current_nsp = g_object_ref (new_nsp);
+
+ if (old_nsp)
+ g_object_unref (old_nsp);
+
+ /* Only notify if it's really changed */
+ if ( (!old_path && new_nsp)
+ || (old_path && !new_nsp)
+ || (old_path && new_nsp && strcmp (old_path, nm_wimax_nsp_get_dbus_path (new_nsp))))
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
+
+ g_free (old_path);
+}
+
+NMWimaxNsp *
+nm_device_wimax_get_active_nsp (NMDeviceWimax *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), NULL);
+
+ return NM_DEVICE_WIMAX_GET_PRIVATE (self)->current_nsp;
+}
+
+static gboolean
+activation_timed_out (gpointer data)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (data);
+
+ priv->activation_timeout_id = 0;
+ nm_device_state_changed (NM_DEVICE (data), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+
+ return FALSE;
+}
+
+static void
+remove_all_nsps (NMDeviceWimax *self)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ while (g_slist_length (priv->nsp_list)) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (priv->nsp_list->data);
+
+ priv->nsp_list = g_slist_remove (priv->nsp_list, nsp);
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ g_object_unref (nsp);
+ }
+
+ g_slist_free (priv->nsp_list);
+ priv->nsp_list = NULL;
+}
+
+static NMWimaxNsp *
+get_nsp_by_name (NMDeviceWimax *self, const char *name)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), name))
+ return nsp;
+ }
+
+ return NULL;
+}
+
+static gboolean
+update_availability (NMDeviceWimax *self, gboolean old_available)
+{
+ NMDevice *device = NM_DEVICE (self);
+ NMDeviceState state;
+ gboolean new_available, changed = FALSE;
+
+ new_available = nm_device_is_available (device);
+ if (new_available == old_available)
+ return FALSE;
+
+ state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+ if (state == NM_DEVICE_STATE_UNAVAILABLE) {
+ if (new_available == TRUE) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_DISCONNECTED,
+ NM_DEVICE_STATE_REASON_NONE);
+ changed = TRUE;
+ }
+ } else if (state >= NM_DEVICE_STATE_DISCONNECTED) {
+ if (new_available == FALSE) {
+ nm_device_state_changed (device,
+ NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_NONE);
+ changed = TRUE;
+ }
+ }
+
+ return changed;
+}
+
+/* NMDeviceInterface interface */
+
+static void
+real_set_enabled (NMDeviceInterface *device, gboolean enabled)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ gboolean old_available;
+ int ret;
+ const char *iface;
+
+ iface = nm_device_get_iface (NM_DEVICE (self));
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): setting radio enabled %d -> %d",
+ iface, priv->enabled, enabled);
+ if (priv->enabled == enabled)
+ return;
+
+ old_available = nm_device_is_available (NM_DEVICE (device));
+ priv->enabled = enabled;
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s",
+ iface, priv->enabled ? "enabled" : "disabled");
+
+ /* Set the WiMAX device RF state to the current user-specified enabled state */
+ if (priv->sdk) {
+ ret = iwmx_sdk_rf_state_set (priv->sdk,
+ enabled ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF);
+ if (ret < 0 && ret != -EINPROGRESS) {
+ nm_log_warn (LOGD_WIMAX, "(%s): failed to %s radio",
+ iface, priv->enabled ? "enable" : "disable");
+ }
+ }
+
+ update_availability (self, old_available);
+}
+
+/* NMDevice methods */
+
+static void
+real_take_down (NMDevice *device)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+
+ set_current_nsp (self, NULL);
+ remove_all_nsps (self);
+}
+
+static gboolean
+real_hw_is_up (NMDevice *device)
+{
+ return nm_system_device_is_up (device);
+}
+
+static gboolean
+real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (dev);
+
+ if (!priv->enabled || !priv->wimaxd_enabled)
+ return FALSE;
+
+ return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+}
+
+static void
+real_hw_take_down (NMDevice *dev)
+{
+ nm_system_device_set_up_down (dev, FALSE, NULL);
+}
+
+static void
+real_update_hw_address (NMDevice *dev)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (dev);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ struct ifreq req;
+ int fd;
+ const char *iface;
+
+ iface = nm_device_get_iface (dev);
+
+ fd = socket (PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ nm_log_warn (LOGD_HW, "(%s): couldn't open control socket.", iface);
+ return;
+ }
+
+ memset (&req, 0, sizeof (struct ifreq));
+ strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
+
+ errno = 0;
+ if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) {
+ nm_log_err (LOGD_HW | LOGD_WIMAX,
+ "(%s): failed to read hardware address (error %d)",
+ iface, errno);
+ } else {
+ memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, ETH_ALEN);
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_HW_ADDRESS);
+ }
+
+ close (fd);
+}
+
+static gboolean
+real_check_connection_compatible (NMDevice *device,
+ NMConnection *connection,
+ GError **error)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ NMSettingConnection *s_con;
+ NMSettingWimax *s_wimax;
+ const char *connection_type;
+ const GByteArray *mac;
+
+ s_con = nm_connection_get_setting_connection (connection);
+ g_assert (s_con);
+
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME)) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX,
+ "The connection was not a WiMAX connection.");
+ return FALSE;
+ }
+
+ s_wimax = nm_connection_get_setting_wimax (connection);
+ if (!s_wimax) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INVALID,
+ "The connection was not a valid WiMAX connection.");
+ return FALSE;
+ }
+
+ mac = nm_setting_wimax_get_mac_address (s_wimax);
+ if (mac && memcmp (mac->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE,
+ "The connection's MAC address did not match this device.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+real_complete_connection (NMDevice *device,
+ NMConnection *connection,
+ const char *specific_object,
+ const GSList *existing_connections,
+ GError **error)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ NMSettingWimax *s_wimax;
+ const GByteArray *setting_mac;
+ char *format;
+ const char *nsp_name = NULL;
+ NMWimaxNsp *nsp = NULL;
+ GSList *iter;
+
+ s_wimax = nm_connection_get_setting_wimax (connection);
+
+ if (!specific_object) {
+ /* If not given a specific object, we need at minimum an NSP name */
+ if (!s_wimax) {
+ g_set_error_literal (error,
+ NM_WIMAX_ERROR,
+ NM_WIMAX_ERROR_CONNECTION_INVALID,
+ "A 'wimax' setting is required if no NSP path was given.");
+ return FALSE;
+ }
+
+ nsp_name = nm_setting_wimax_get_network_name (s_wimax);
+ if (!nsp_name || !strlen (nsp_name)) {
+ g_set_error_literal (error,
+ NM_WIMAX_ERROR,
+ NM_WIMAX_ERROR_CONNECTION_INVALID,
+ "A 'wimax' setting with a valid network name is required if no NSP path was given.");
+ return FALSE;
+ }
+
+ /* Find a compatible NSP in the list */
+ nsp = get_nsp_by_name (self, nsp_name);
+
+ /* If we still don't have an NSP, then the WiMAX settings needs to be
+ * fully specified by the client. Might not be able to find the NSP
+ * if the scan didn't find the NSP yet.
+ */
+ if (!nsp) {
+ if (!nm_setting_verify (NM_SETTING (s_wimax), NULL, error))
+ return FALSE;
+ }
+ } else {
+ /* Find a compatible NSP in the list */
+ for (iter = priv->nsp_list; iter; iter = g_slist_next (iter)) {
+ if (!strcmp (specific_object, nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))) {
+ nsp = NM_WIMAX_NSP (iter->data);
+ break;
+ }
+ }
+
+ if (!nsp) {
+ g_set_error (error,
+ NM_WIMAX_ERROR,
+ NM_WIMAX_ERROR_NSP_NOT_FOUND,
+ "The NSP %s was not in the scan list.",
+ specific_object);
+ return FALSE;
+ }
+
+ nsp_name = nm_wimax_nsp_get_name (nsp);
+ }
+
+ /* Add a WiMAX setting if one doesn't exist */
+ if (!s_wimax) {
+ s_wimax = (NMSettingWimax *) nm_setting_wimax_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wimax));
+ }
+
+ g_assert (nsp_name);
+ format = g_strdup_printf ("%s %%d", nsp_name);
+ nm_utils_complete_generic (connection,
+ NM_SETTING_WIMAX_SETTING_NAME,
+ existing_connections,
+ format,
+ nsp_name,
+ TRUE);
+ g_free (format);
+ g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL);
+
+ setting_mac = nm_setting_wimax_get_mac_address (s_wimax);
+ if (setting_mac) {
+ /* Make sure the setting MAC (if any) matches the device's permanent MAC */
+ if (memcmp (setting_mac->data, &priv->hw_addr.ether_addr_octet, ETH_ALEN)) {
+ g_set_error (error,
+ NM_SETTING_WIMAX_ERROR,
+ NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIMAX_MAC_ADDRESS);
+ return FALSE;
+ }
+ } else {
+ GByteArray *mac;
+ const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+ /* Lock the connection to this device by default */
+ if (memcmp (&priv->hw_addr.ether_addr_octet, null_mac, ETH_ALEN)) {
+ mac = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (mac, priv->hw_addr.ether_addr_octet, ETH_ALEN);
+ g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL);
+ g_byte_array_free (mac, TRUE);
+ }
+ }
+
+ return TRUE;
+}
+
+static NMConnection *
+real_get_best_auto_connection (NMDevice *device,
+ GSList *connections,
+ char **specific_object)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ GSList *iter;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *connection = NM_CONNECTION (iter->data);
+ NMSettingConnection *s_con;
+ NMSettingWimax *s_wimax;
+ const char *connection_type;
+ const GByteArray *mac;
+
+ s_con = nm_connection_get_setting_connection (connection);
+ g_assert (s_con);
+
+ if (!nm_setting_connection_get_autoconnect (s_con))
+ continue;
+
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME))
+ continue;
+
+ s_wimax = nm_connection_get_setting_wimax (connection);
+ if (!s_wimax)
+ continue;
+
+ mac = nm_setting_wimax_get_mac_address (s_wimax);
+ if (mac && memcmp (mac->data, priv->hw_addr.ether_addr_octet, ETH_ALEN))
+ continue;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (nm_wimax_nsp_check_compatible (nsp, connection)) {
+ *specific_object = (char *) nm_wimax_nsp_get_dbus_path (nsp);
+ return connection;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static guint32
+real_get_generic_capabilities (NMDevice *dev)
+{
+ return NM_DEVICE_CAP_NM_SUPPORTED;
+}
+
+static gboolean
+real_is_available (NMDevice *device)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ const char *iface = nm_device_get_iface (device);
+
+ if (!priv->enabled) {
+ nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled", iface);
+ return FALSE;
+ }
+
+ if (!priv->wimaxd_enabled) {
+ nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled in wimaxd", iface);
+ return FALSE;
+ }
+
+ if (!nm_wimax_util_sdk_is_initialized ()) {
+ nm_log_dbg (LOGD_WIMAX, "(%s): not available because WiMAX SDK not initialized", iface);
+ return FALSE;
+ }
+
+ if (!priv->sdk) {
+ nm_log_dbg (LOGD_WIMAX, "(%s): not available because not known to WiMAX SDK", iface);
+ return FALSE;
+ }
+
+ return iwmxsdk_status_get (priv->sdk) >= WIMAX_API_DEVICE_STATUS_Ready;
+}
+
+static void
+clear_activation_timeout (NMDeviceWimax *self)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (priv->activation_timeout_id) {
+ g_source_remove (priv->activation_timeout_id);
+ priv->activation_timeout_id = 0;
+ }
+
+ priv->connect_failed = FALSE;
+}
+
+static void
+clear_link_timeout (NMDeviceWimax *self)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (priv->link_timeout_id) {
+ g_source_remove (priv->link_timeout_id);
+ priv->link_timeout_id = 0;
+ }
+}
+
+static void
+clear_connected_poll (NMDeviceWimax *self)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (priv->poll_id) {
+ g_source_remove (priv->poll_id);
+ priv->poll_id = 0;
+ }
+}
+
+static NMActStageReturn
+real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ NMActRequest *req;
+ GSList *iter;
+ const char *path;
+
+ clear_link_timeout (NM_DEVICE_WIMAX (device));
+
+ req = nm_device_get_act_request (device);
+ if (!req)
+ goto err;
+
+ path = nm_act_request_get_specific_object (req);
+ if (!path)
+ goto err;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (!strcmp (path, nm_wimax_nsp_get_dbus_path (nsp))) {
+ set_current_nsp (NM_DEVICE_WIMAX (device), nsp);
+ return NM_ACT_STAGE_RETURN_SUCCESS;
+ }
+ }
+
+ err:
+ *reason = NM_DEVICE_STATE_REASON_NONE;
+ return NM_ACT_STAGE_RETURN_FAILURE;
+}
+
+static NMActStageReturn
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ NMConnection *connection;
+ NMSettingWimax *s_wimax;
+ const char *nsp_name, *iface;
+ int ret;
+
+ iface = nm_device_get_iface (device);
+ g_assert (iface);
+
+ connection = nm_act_request_get_connection (nm_device_get_act_request (device));
+ g_assert (connection);
+
+ s_wimax = nm_connection_get_setting_wimax (connection);
+ g_assert (s_wimax);
+
+ nsp_name = nm_setting_wimax_get_network_name (s_wimax);
+ g_assert (nsp_name);
+
+ nm_log_info (LOGD_WIMAX, "(%s): connecting to NSP '%s'",
+ iface, nsp_name);
+
+ priv->connect_failed = FALSE;
+ ret = iwmx_sdk_connect (priv->sdk, nsp_name);
+ if (ret < 0 && ret != -EINPROGRESS) {
+ nm_log_err (LOGD_WIMAX, "(%s): failed to connect to NSP '%s'",
+ iface, nsp_name);
+ *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+
+ /* FIXME: Is 40 seconds good estimation? I have no idea */
+ priv->activation_timeout_id = g_timeout_add_seconds (40, activation_timed_out, device);
+
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+}
+
+static void
+force_disconnect (NMDeviceWimax *self, struct wmxsdk *sdk)
+{
+ WIMAX_API_DEVICE_STATUS status;
+ int ret;
+ const char *iface;
+
+ g_return_if_fail (sdk != NULL);
+
+ iface = nm_device_get_iface (NM_DEVICE (self));
+
+ status = iwmxsdk_status_get (sdk);
+ if ((int) status < 0) {
+ nm_log_err (LOGD_WIMAX, "(%s): failed to read WiMAX device status: %d",
+ iface, status);
+ return;
+ }
+
+ if ( status == WIMAX_API_DEVICE_STATUS_Connecting
+ || status == WIMAX_API_DEVICE_STATUS_Data_Connected) {
+ nm_log_dbg (LOGD_WIMAX, "(%s): requesting disconnect", iface);
+ ret = iwmx_sdk_disconnect (sdk);
+ if (ret < 0 && ret != -EINPROGRESS) {
+ nm_log_err (LOGD_WIMAX, "(%s): failed to disconnect WiMAX device: %d",
+ iface, ret);
+ }
+ }
+}
+
+static void
+real_deactivate (NMDevice *device)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ clear_activation_timeout (self);
+ clear_link_timeout (self);
+ clear_connected_poll (self);
+
+ set_current_nsp (self, NULL);
+
+ if (priv->sdk) {
+ /* Read explicit status here just to make sure we have the most
+ * up-to-date status and to ensure we disconnect if needed.
+ */
+ force_disconnect (self, priv->sdk);
+ }
+}
+
+/*************************************************************************/
+
+static void
+wmx_state_change_cb (struct wmxsdk *wmxsdk,
+ WIMAX_API_DEVICE_STATUS new_status,
+ WIMAX_API_DEVICE_STATUS old_status,
+ WIMAX_API_STATUS_REASON reason,
+ void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ NMDeviceState state;
+ const char *iface;
+ gboolean old_available = FALSE;
+ const char *nsp_name = NULL;
+
+ if (new_status == old_status)
+ return;
+
+ iface = nm_device_get_iface (NM_DEVICE (self));
+ state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+ old_available = nm_device_is_available (NM_DEVICE (self));
+
+ priv->status = new_status;
+ if (priv->current_nsp)
+ nsp_name = nm_wimax_nsp_get_name (priv->current_nsp);
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)",
+ iface,
+ iwmx_sdk_dev_status_to_str (old_status),
+ iwmx_sdk_dev_status_to_str (new_status),
+ reason);
+
+ switch (new_status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ if (priv->wimaxd_enabled) {
+ priv->wimaxd_enabled = FALSE;
+ if (update_availability (self, old_available))
+ return;
+ }
+ break;
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ /* If for some reason we're initially connected, force a disconnect here */
+ if (state < NM_DEVICE_STATE_DISCONNECTED)
+ force_disconnect (self, wmxsdk);
+ /* Fall through */
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ if (priv->wimaxd_enabled == FALSE) {
+ priv->wimaxd_enabled = TRUE;
+ if (update_availability (self, old_available))
+ return;
+ }
+ break;
+ default:
+ nm_log_warn (LOGD_WIMAX, "(%s): unhandled WiMAX device state %d",
+ iface, new_status);
+ break;
+ }
+
+ /* Handle activation success and failure */
+ if (IS_ACTIVATING_STATE (state)) {
+ if (new_status == WIMAX_API_DEVICE_STATUS_Data_Connected) {
+ /* Success */
+ clear_activation_timeout (self);
+
+ nm_log_info (LOGD_WIMAX, "(%s): connected to '%s'",
+ iface, nsp_name);
+ nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
+ return;
+ }
+
+ if (priv->connect_failed) {
+ /* Connection attempt failed */
+ nm_log_info (LOGD_WIMAX, "(%s): connection to '%s' failed: (%d) %s",
+ iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason));
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+ return;
+ }
+ }
+
+ /* Handle disconnection */
+ if (state == NM_DEVICE_STATE_ACTIVATED) {
+ if ( old_status == WIMAX_API_DEVICE_STATUS_Data_Connected
+ && new_status < WIMAX_API_DEVICE_STATUS_Connecting) {
+
+ nm_log_info (LOGD_WIMAX, "(%s): disconnected from '%s': (%d) %s",
+ iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason));
+
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+ }
+ }
+}
+
+static gboolean
+link_timeout_cb (gpointer user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ priv->link_timeout_id = 0;
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): link timed out", nm_device_get_iface (NM_DEVICE (self)));
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_CARRIER);
+
+ return FALSE;
+}
+
+static void
+wmx_media_status_cb (struct wmxsdk *wmxsdk,
+ WIMAX_API_MEDIA_STATUS new_status,
+ void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ NMDeviceState state;
+ const char *iface;
+
+ iface = nm_device_get_iface (NM_DEVICE (self));
+ state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %s",
+ iface, iwmx_sdk_media_status_to_str (new_status));
+
+ /* We only care about media events while activated */
+ if (state != NM_DEVICE_STATE_ACTIVATED)
+ return;
+
+ clear_link_timeout (self);
+
+ switch (new_status) {
+ case WIMAX_API_MEDIA_STATUS_LINK_UP:
+ break;
+ case WIMAX_API_MEDIA_STATUS_LINK_DOWN:
+ nm_log_dbg (LOGD_WIMAX, "(%s): starting link timeout", iface);
+ priv->link_timeout_id = g_timeout_add (15, link_timeout_cb, self);
+ break;
+ case WIMAX_API_MEDIA_STATUS_LINK_RENEW:
+ nm_log_dbg (LOGD_WIMAX, "(%s): renewing DHCP lease", iface);
+ if (!nm_device_dhcp4_renew (NM_DEVICE (self), TRUE)) {
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_DHCP_FAILED);
+ }
+ break;
+ default:
+ nm_log_err (LOGD_WIMAX, "(%s): unhandled media status %d", iface, new_status);
+ break;
+ }
+}
+
+static void
+wmx_connect_result_cb (struct wmxsdk *wmxsdk,
+ WIMAX_API_NETWORK_CONNECTION_RESP result,
+ void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ NMDeviceState state;
+
+ state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+ if (IS_ACTIVATING_STATE (state)) {
+ priv->connect_failed = (result == WIMAX_API_CONNECTION_SUCCESS);
+ /* Wait for the state change so we can get the reason code; we
+ * cache the connect failure so we don't have to wait for the
+ * activation timeout.
+ */
+ }
+}
+
+static void
+remove_outdated_nsps (NMDeviceWimax *self,
+ WIMAX_API_NSP_INFO_EX *nsp_list,
+ guint32 list_size)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ GSList *iter;
+ GSList *to_remove = NULL;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+ gboolean found = FALSE;
+ int i;
+
+ for (i = 0; i < list_size; i++) {
+ WIMAX_API_NSP_INFO_EX *info = &nsp_list[i];
+
+ if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), (char *) info->NSPName)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ to_remove = g_slist_prepend (to_remove, nsp);
+ }
+
+ for (iter = to_remove; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ priv->nsp_list = g_slist_remove (priv->nsp_list, nsp);
+ g_object_unref (nsp);
+ }
+
+ g_slist_free (to_remove);
+}
+
+static void
+wmx_scan_result_cb (struct wmxsdk *wmxsdk,
+ WIMAX_API_NSP_INFO_EX *nsps,
+ guint num_nsps,
+ void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ const char *iface = nm_device_get_iface (NM_DEVICE (self));
+ int i;
+
+ remove_outdated_nsps (self, nsps, num_nsps);
+
+ /* Add new NSPs and update existing ones */
+ for (i = 0; i < num_nsps; i++) {
+ WIMAX_API_NSP_INFO_EX *sdk_nsp = &nsps[i];
+ const char *nsp_name = (const char *) sdk_nsp->NSPName;
+ NMWimaxNspNetworkType net_type;
+ guint signalq;
+ NMWimaxNsp *nsp;
+ gboolean new_nsp;
+
+ nsp = get_nsp_by_name (self, nsp_name);
+ new_nsp = (nsp == NULL);
+ if (new_nsp) {
+ nsp = nm_wimax_nsp_new (nsp_name);
+ nm_log_dbg (LOGD_WIMAX, "(%s): new WiMAX NSP '%s'", iface, nsp_name);
+ }
+
+ net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType);
+ if (net_type != nm_wimax_nsp_get_network_type (nsp))
+ g_object_set (nsp, NM_WIMAX_NSP_NETWORK_TYPE, net_type, NULL);
+
+ signalq = CLAMP (sdk_nsp->linkQuality, 0, 100);
+ if (signalq != nm_wimax_nsp_get_signal_quality (nsp))
+ g_object_set (nsp, NM_WIMAX_NSP_SIGNAL_QUALITY, signalq, NULL);
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d",
+ iface, nsp_name, sdk_nsp->linkQuality, net_type);
+
+ if (new_nsp) {
+ priv->nsp_list = g_slist_append (priv->nsp_list, nsp);
+ nm_wimax_nsp_export_to_dbus (nsp);
+ g_signal_emit (self, signals[NSP_ADDED], 0, nsp);
+ }
+ }
+}
+
+static void
+wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (priv->sdk) {
+ /* Clear callbacks just in case we don't hold the last reference */
+ iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
+
+ wmxsdk_unref (priv->sdk);
+ priv->sdk = NULL;
+
+ priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_NONE);
+ }
+}
+
+/*************************************************************************/
+
+static inline gint
+sdk_rssi_to_dbm (guint raw_rssi)
+{
+ /* Values range from 0x00 to 0x53, where -123dBm is encoded as 0x00 and
+ * -40dBm encoded as 0x53 in 1dB increments.
+ */
+ return raw_rssi - 123;
+}
+
+static inline gint
+sdk_cinr_to_db (guint raw_cinr)
+{
+ /* Values range from 0x00 to 0x3F, where -10dB is encoded as 0x00 and
+ * 53dB encoded as 0x3F in 1dB increments.
+ */
+ return raw_cinr - 10;
+}
+
+static inline gint
+sdk_tx_pow_to_dbm (guint raw_tx_pow)
+{
+ /* Values range from 0x00 to 0xFF, where -84dBm is encoded as 0x00 and
+ * 43.5dBm is encoded as 0xFF in 0.5dB increments. Normalize so that
+ * 0 dBm == 0.
+ */
+ return (int) (((double) raw_tx_pow / 2.0) - 84) * 2;
+}
+
+static void
+set_link_status (NMDeviceWimax *self, WIMAX_API_LINK_STATUS_INFO_EX *link_status)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ guint center_freq = 0;
+ gint conv_rssi = 0, conv_cinr = 0, conv_tx_pow = 0;
+ char *new_bsid = NULL;
+
+ if (link_status) {
+ center_freq = link_status->centerFrequency;
+ conv_rssi = sdk_rssi_to_dbm (link_status->RSSI);
+ conv_cinr = sdk_cinr_to_db (link_status->CINR);
+ conv_tx_pow = sdk_tx_pow_to_dbm (link_status->txPWR);
+ new_bsid = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ link_status->bsId[0], link_status->bsId[1],
+ link_status->bsId[2], link_status->bsId[3],
+ link_status->bsId[4], link_status->bsId[5]);
+ }
+
+ if (priv->center_freq != center_freq) {
+ priv->center_freq = center_freq;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_CENTER_FREQUENCY);
+ }
+
+ if (priv->rssi != conv_rssi) {
+ priv->rssi = conv_rssi;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_RSSI);
+ }
+
+ if (priv->cinr != conv_cinr) {
+ priv->cinr = conv_cinr;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_CINR);
+ }
+
+ if (priv->tx_power != conv_tx_pow) {
+ priv->tx_power = conv_tx_pow;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_TX_POWER);
+ }
+
+ if (g_strcmp0 (priv->bsid, new_bsid) != 0) {
+ g_free (priv->bsid);
+ priv->bsid = new_bsid;
+ g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_BSID);
+ } else
+ g_free (new_bsid);
+}
+
+static gboolean
+connected_poll_cb (gpointer user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ WIMAX_API_CONNECTED_NSP_INFO_EX *sdk_nsp;
+ WIMAX_API_LINK_STATUS_INFO_EX *link_status;
+
+ g_return_val_if_fail (priv->sdk != NULL, FALSE);
+
+ /* Get details of the connected NSP */
+ sdk_nsp = iwmx_sdk_get_connected_network (priv->sdk);
+ if (sdk_nsp) {
+ const char *nsp_name = (const char *) sdk_nsp->NSPName;
+ NMWimaxNsp *nsp;
+
+ nsp = get_nsp_by_name (self, nsp_name);
+ if (nsp) {
+ NMWimaxNspNetworkType net_type;
+ guint signalq;
+
+ net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType);
+ if (net_type != nm_wimax_nsp_get_network_type (nsp))
+ g_object_set (nsp, NM_WIMAX_NSP_NETWORK_TYPE, net_type, NULL);
+
+ signalq = sdk_nsp->linkQuality;
+ if (signalq != nm_wimax_nsp_get_signal_quality (nsp))
+ g_object_set (nsp, NM_WIMAX_NSP_SIGNAL_QUALITY, signalq, NULL);
+
+ nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d",
+ nm_device_get_iface (NM_DEVICE (self)),
+ nsp_name, sdk_nsp->linkQuality, net_type);
+ }
+ free (sdk_nsp);
+ }
+
+ /* Get details of the current radio link */
+ link_status = iwmx_sdk_get_link_status_info (priv->sdk);
+ if (link_status) {
+ set_link_status (self, link_status);
+ free (link_status);
+ }
+
+ return TRUE; /* reschedule */
+}
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ gpointer user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (new_state < NM_DEVICE_STATE_DISCONNECTED)
+ remove_all_nsps (self);
+
+ /* Request initial NSP list */
+ if ( new_state == NM_DEVICE_STATE_DISCONNECTED
+ && old_state < NM_DEVICE_STATE_DISCONNECTED) {
+ if (priv->sdk)
+ iwmx_sdk_get_networks (priv->sdk);
+ }
+
+ if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED)
+ clear_activation_timeout (self);
+
+ if (new_state == NM_DEVICE_STATE_ACTIVATED) {
+ /* poll link quality and BSID */
+ clear_connected_poll (self);
+ priv->poll_id = g_timeout_add_seconds (10, connected_poll_cb, self);
+ connected_poll_cb (self);
+ } else {
+ clear_link_timeout (self);
+ clear_connected_poll (self);
+ set_link_status (self, NULL);
+ }
+}
+
+/*************************************************************************/
+
+static gboolean
+sdk_action_defer_cb (gpointer user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ gboolean old_available = nm_device_is_available (NM_DEVICE (self));
+
+ NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0;
+ update_availability (self, old_available);
+ return FALSE;
+}
+
+static void
+wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ /* If we now have the SDK, schedule an idle handler to start the device up */
+ if (!priv->sdk) {
+ priv->sdk = wmxsdk_ref (sdk);
+ iwmx_sdk_set_callbacks(priv->sdk,
+ wmx_state_change_cb,
+ wmx_media_status_cb,
+ wmx_connect_result_cb,
+ wmx_scan_result_cb,
+ wmx_removed_cb,
+ self);
+ iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);
+
+ if (!priv->sdk_action_defer_id)
+ priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
+ }
+}
+
+/*************************************************************************/
+
+NMDevice *
+nm_device_wimax_new (const char *udi,
+ const char *iface,
+ const char *driver)
+{
+ NMDevice *device;
+
+ g_return_val_if_fail (udi != NULL, NULL);
+ g_return_val_if_fail (iface != NULL, NULL);
+ g_return_val_if_fail (driver != NULL, NULL);
+
+ device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIMAX,
+ NM_DEVICE_INTERFACE_UDI, udi,
+ NM_DEVICE_INTERFACE_IFACE, iface,
+ NM_DEVICE_INTERFACE_DRIVER, driver,
+ NM_DEVICE_INTERFACE_TYPE_DESC, "WiMAX",
+ NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIMAX,
+ NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WIMAX,
+ NULL);
+ if (device) {
+ struct wmxsdk *sdk;
+
+ nm_wimax_util_sdk_ref ();
+ g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), NULL);
+
+ /* See if the SDK already knows about this interface */
+ sdk = iwmx_sdk_get_wmxsdk_for_iface (iface);
+ if (sdk)
+ wmx_new_sdk_cb (sdk, device);
+
+ /* If it doesn't, we want to be notified when it does */
+ iwmx_sdk_new_callback_register (wmx_new_sdk_cb, device);
+ }
+
+ return device;
+}
+
+static void
+device_interface_init (NMDeviceInterface *iface_class)
+{
+ iface_class->set_enabled = real_set_enabled;
+}
+
+static void
+nm_device_wimax_init (NMDeviceWimax *self)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (object);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+ struct ether_addr hw_addr;
+
+ switch (prop_id) {
+ case PROP_HW_ADDRESS:
+ nm_device_wimax_get_hw_address (self, &hw_addr);
+ g_value_take_string (value, nm_ether_ntop (&hw_addr));
+ break;
+ case PROP_ACTIVE_NSP:
+ if (priv->current_nsp)
+ g_value_set_boxed (value, nm_wimax_nsp_get_dbus_path (priv->current_nsp));
+ else
+ g_value_set_boxed (value, "/");
+ break;
+ case PROP_CENTER_FREQ:
+ g_value_set_uint (value, priv->center_freq);
+ break;
+ case PROP_RSSI:
+ g_value_set_int (value, priv->rssi);
+ break;
+ case PROP_CINR:
+ g_value_set_int (value, priv->cinr);
+ break;
+ case PROP_TX_POWER:
+ g_value_set_int (value, priv->tx_power);
+ break;
+ case PROP_BSID:
+ g_value_set_string (value, priv->bsid);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (object);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ if (priv->disposed)
+ goto done;
+
+ priv->disposed = TRUE;
+
+ clear_activation_timeout (self);
+ clear_link_timeout (self);
+ clear_connected_poll (self);
+
+ if (priv->sdk_action_defer_id)
+ g_source_remove (priv->sdk_action_defer_id);
+
+ if (priv->sdk) {
+ iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
+ wmxsdk_unref (priv->sdk);
+ }
+
+ g_free (priv->bsid);
+
+ set_current_nsp (self, NULL);
+
+ g_slist_foreach (priv->nsp_list, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->nsp_list);
+
+ iwmx_sdk_new_callback_unregister (wmx_new_sdk_cb, self);
+ nm_wimax_util_sdk_unref ();
+
+done:
+ G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object);
+}
+
+static void
+nm_device_wimax_class_init (NMDeviceWimaxClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMDeviceWimaxPrivate));
+
+ /* Virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ device_class->take_down = real_take_down;
+ device_class->hw_is_up = real_hw_is_up;
+ device_class->hw_bring_up = real_hw_bring_up;
+ device_class->hw_take_down = real_hw_take_down;
+ device_class->update_hw_address = real_update_hw_address;
+ device_class->check_connection_compatible = real_check_connection_compatible;
+ device_class->complete_connection = real_complete_connection;
+ device_class->get_best_auto_connection = real_get_best_auto_connection;
+ device_class->get_generic_capabilities = real_get_generic_capabilities;
+ device_class->is_available = real_is_available;
+ device_class->act_stage1_prepare = real_act_stage1_prepare;
+ device_class->act_stage2_config = real_act_stage2_config;
+ device_class->deactivate = real_deactivate;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_HW_ADDRESS,
+ g_param_spec_string (NM_DEVICE_WIMAX_HW_ADDRESS,
+ "MAC Address",
+ "Hardware MAC address",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class, PROP_ACTIVE_NSP,
+ g_param_spec_boxed (NM_DEVICE_WIMAX_ACTIVE_NSP,
+ "Active NSP",
+ "Currently active NSP",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_CENTER_FREQ,
+ g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY,
+ "Center frequency",
+ "Center frequency",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_RSSI,
+ g_param_spec_int (NM_DEVICE_WIMAX_RSSI,
+ "RSSI",
+ "RSSI",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_CINR,
+ g_param_spec_int (NM_DEVICE_WIMAX_CINR,
+ "CINR",
+ "CINR",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_TX_POWER,
+ g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER,
+ "TX Power",
+ "TX Power",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (object_class, PROP_BSID,
+ g_param_spec_string (NM_DEVICE_WIMAX_BSID,
+ "BSID",
+ "BSID",
+ NULL,
+ G_PARAM_READABLE));
+
+ /* Signals */
+ signals[NSP_ADDED] =
+ g_signal_new ("nsp-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMDeviceWimaxClass, nsp_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ signals[NSP_REMOVED] =
+ g_signal_new ("nsp-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMDeviceWimaxClass, nsp_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class, G_STRUCT_OFFSET (NMDeviceWimaxClass, properties_changed));
+
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_nm_device_wimax_object_info);
+
+ dbus_g_error_domain_register (NM_WIMAX_ERROR, NULL, NM_TYPE_WIMAX_ERROR);
+}
diff --git a/src/wimax/nm-device-wimax.h b/src/wimax/nm-device-wimax.h
new file mode 100644
index 000000000..d70380acc
--- /dev/null
+++ b/src/wimax/nm-device-wimax.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2010 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_DEVICE_WIMAX_H
+#define NM_DEVICE_WIMAX_H
+
+#include <net/ethernet.h>
+#include "nm-device.h"
+#include "nm-wimax-nsp.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_WIMAX (nm_device_wimax_get_type ())
+#define NM_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimax))
+#define NM_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass))
+#define NM_IS_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIMAX))
+#define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX))
+#define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass))
+
+#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address"
+#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp"
+#define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency"
+#define NM_DEVICE_WIMAX_RSSI "rssi"
+#define NM_DEVICE_WIMAX_CINR "cinr"
+#define NM_DEVICE_WIMAX_TX_POWER "tx-power"
+#define NM_DEVICE_WIMAX_BSID "bsid"
+
+typedef struct {
+ NMDevice parent;
+} NMDeviceWimax;
+
+typedef struct {
+ NMDeviceClass parent;
+
+ /* Signals */
+ void (*nsp_added) (NMDeviceWimax *wimax, NMWimaxNsp *nsp);
+ void (*nsp_removed) (NMDeviceWimax *wimax, NMWimaxNsp *nsp);
+ void (*properties_changed) (NMDeviceWimax *wimax, GHashTable *properties);
+} NMDeviceWimaxClass;
+
+GType nm_device_wimax_get_type (void);
+
+NMDevice *nm_device_wimax_new (const char *udi,
+ const char *iface,
+ const char *driver);
+
+void nm_device_wimax_get_hw_address (NMDeviceWimax *self,
+ struct ether_addr *addr);
+
+NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *self);
+
+guint nm_device_wimax_get_center_frequency (NMDeviceWimax *self);
+
+gint nm_device_wimax_get_rssi (NMDeviceWimax *self);
+
+gint nm_device_wimax_get_cinr (NMDeviceWimax *self);
+
+gint nm_device_wimax_get_tx_power (NMDeviceWimax *self);
+
+const char *nm_device_wimax_get_bsid (NMDeviceWimax *self);
+
+G_END_DECLS
+
+#endif /* NM_DEVICE_WIMAX_H */
diff --git a/src/wimax/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c
new file mode 100644
index 000000000..b10cee399
--- /dev/null
+++ b/src/wimax/nm-wimax-nsp.c
@@ -0,0 +1,246 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+#include "nm-wimax-nsp.h"
+#include "NetworkManager.h"
+#include "nm-dbus-manager.h"
+#include "nm-setting-wimax.h"
+#include "nm-properties-changed-signal.h"
+#include "nm-wimax-nsp-glue.h"
+#include "nm-utils.h"
+
+G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, G_TYPE_OBJECT)
+
+enum {
+ PROPERTIES_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+enum {
+ PROP_0,
+
+ PROP_NAME,
+ PROP_SIGNAL_QUALITY,
+ PROP_NETWORK_TYPE,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_NSP, NMWimaxNspPrivate))
+
+typedef struct {
+ char *dbus_path;
+
+ char *name;
+ guint32 signal_quality;
+ NMWimaxNspNetworkType network_type;
+} NMWimaxNspPrivate;
+
+NMWimaxNsp *
+nm_wimax_nsp_new (const char *name)
+{
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return NM_WIMAX_NSP (g_object_new (NM_TYPE_WIMAX_NSP,
+ NM_WIMAX_NSP_NAME, name,
+ NULL));
+}
+
+const char *
+nm_wimax_nsp_get_name (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), NULL);
+
+ return GET_PRIVATE (self)->name;
+}
+
+guint32
+nm_wimax_nsp_get_signal_quality (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), 0);
+
+ return GET_PRIVATE (self)->signal_quality;
+}
+
+NMWimaxNspNetworkType
+nm_wimax_nsp_get_network_type (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), 0);
+
+ return GET_PRIVATE (self)->network_type;
+}
+
+void
+nm_wimax_nsp_export_to_dbus (NMWimaxNsp *self)
+{
+ NMWimaxNspPrivate *priv;
+ NMDBusManager *mgr;
+ DBusGConnection *g_connection;
+ static guint32 counter = 0;
+
+ g_return_if_fail (NM_IS_WIMAX_NSP (self));
+
+ priv = GET_PRIVATE (self);
+
+ g_return_if_fail (priv->dbus_path == NULL);
+
+ mgr = nm_dbus_manager_get ();
+ g_assert (mgr);
+
+ g_connection = nm_dbus_manager_get_connection (mgr);
+ g_assert (g_connection);
+
+ priv->dbus_path = g_strdup_printf (NM_DBUS_PATH_WIMAX_NSP "/%d", counter++);
+ dbus_g_connection_register_g_object (g_connection, priv->dbus_path, G_OBJECT (self));
+
+ g_object_unref (mgr);
+}
+
+const char *
+nm_wimax_nsp_get_dbus_path (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), NULL);
+
+ return GET_PRIVATE (self)->dbus_path;
+}
+
+gboolean
+nm_wimax_nsp_check_compatible (NMWimaxNsp *self,
+ NMConnection *connection)
+{
+ NMWimaxNspPrivate *priv;
+ NMSettingWimax *s_wimax;
+
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+ priv = GET_PRIVATE (self);
+
+ s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX));
+ if (!s_wimax)
+ return FALSE;
+
+ return g_strcmp0 (nm_wimax_nsp_get_name (self), nm_setting_wimax_get_network_name (s_wimax)) == 0;
+}
+
+static void
+nm_wimax_nsp_init (NMWimaxNsp *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMWimaxNspPrivate *priv = GET_PRIVATE (object);
+ guint32 quality;
+ guint network_type;
+
+ switch (prop_id) {
+ case PROP_NAME:
+ /* Construct only */
+ priv->name = g_value_dup_string (value);
+ break;
+ case PROP_SIGNAL_QUALITY:
+ quality = g_value_get_uint (value);
+ if (quality != priv->signal_quality) {
+ priv->signal_quality = CLAMP (quality, 0, 100);
+ g_object_notify (object, NM_WIMAX_NSP_SIGNAL_QUALITY);
+ }
+ break;
+ case PROP_NETWORK_TYPE:
+ network_type = g_value_get_uint (value);
+ if (network_type != priv->network_type) {
+ priv->network_type = network_type;
+ g_object_notify (object, NM_WIMAX_NSP_NETWORK_TYPE);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMWimaxNsp *self = NM_WIMAX_NSP (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, nm_wimax_nsp_get_name (self));
+ break;
+ case PROP_SIGNAL_QUALITY:
+ g_value_set_uint (value, nm_wimax_nsp_get_signal_quality (self));
+ break;
+ case PROP_NETWORK_TYPE:
+ g_value_set_uint (value, nm_wimax_nsp_get_network_type (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ NMWimaxNspPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->name);
+ g_free (priv->dbus_path);
+
+ G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->finalize (object);
+}
+
+static void
+nm_wimax_nsp_class_init (NMWimaxNspClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMWimaxNspPrivate));
+
+ /* Virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ g_object_class_install_property
+ (object_class, PROP_NAME,
+ g_param_spec_string (NM_WIMAX_NSP_NAME,
+ "Name",
+ "Name",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_SIGNAL_QUALITY,
+ g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY,
+ "SignalQuality",
+ "SignalQuality",
+ 0,
+ 100,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_NETWORK_TYPE,
+ g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE,
+ "NetworkType",
+ "NetworkType",
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER,
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ G_PARAM_READWRITE));
+
+ /* Signals */
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class,
+ G_STRUCT_OFFSET (NMWimaxNspClass, properties_changed));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_nm_wimax_nsp_object_info);
+}
diff --git a/src/wimax/nm-wimax-nsp.h b/src/wimax/nm-wimax-nsp.h
new file mode 100644
index 000000000..a74b68a79
--- /dev/null
+++ b/src/wimax/nm-wimax-nsp.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_NSP_H
+#define NM_WIMAX_NSP_H
+
+#include <glib-object.h>
+#include "nm-wimax-types.h"
+#include "nm-connection.h"
+
+#define NM_TYPE_WIMAX_NSP (nm_wimax_nsp_get_type ())
+#define NM_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNsp))
+#define NM_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+#define NM_IS_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_NSP))
+#define NM_IS_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIMAX_NSP))
+#define NM_WIMAX_NSP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+
+#define NM_WIMAX_NSP_NAME "name"
+#define NM_WIMAX_NSP_SIGNAL_QUALITY "signal-quality"
+#define NM_WIMAX_NSP_NETWORK_TYPE "network-type"
+
+typedef struct {
+ GObject parent;
+} NMWimaxNsp;
+
+typedef struct {
+ GObjectClass parent;
+
+ /* Signals */
+ void (*properties_changed) (NMWimaxNsp *nsp, GHashTable *properties);
+} NMWimaxNspClass;
+
+GType nm_wimax_nsp_get_type (void);
+
+NMWimaxNsp *nm_wimax_nsp_new (const char *name);
+const char *nm_wimax_nsp_get_name (NMWimaxNsp *self);
+guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *self);
+NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *self);
+
+void nm_wimax_nsp_export_to_dbus (NMWimaxNsp *self);
+const char *nm_wimax_nsp_get_dbus_path (NMWimaxNsp *self);
+
+gboolean nm_wimax_nsp_check_compatible (NMWimaxNsp *self,
+ NMConnection *connection);
+
+#endif /* NM_WIMAX_NSP_H */
diff --git a/src/wimax/nm-wimax-types.h b/src/wimax/nm-wimax-types.h
new file mode 100644
index 000000000..8c807fd8a
--- /dev/null
+++ b/src/wimax/nm-wimax-types.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_TYPES_H
+#define NM_WIMAX_TYPES_H
+
+typedef enum {
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ NM_WIMAX_NSP_NETWORK_TYPE_HOME,
+ NM_WIMAX_NSP_NETWORK_TYPE_PARTNER,
+ NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER
+} NMWimaxNspNetworkType;
+
+#endif /* NM_WIMAX_TYPES_H */
diff --git a/src/wimax/nm-wimax-util.c b/src/wimax/nm-wimax-util.c
new file mode 100644
index 000000000..bca25a1db
--- /dev/null
+++ b/src/wimax/nm-wimax-util.c
@@ -0,0 +1,82 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include <WiMaxAPI.h>
+#include "nm-wimax-util.h"
+#include "nm-utils.h"
+#include "iwmxsdk.h"
+#include "nm-logging.h"
+
+static guint sdk_refcount = 0;
+
+void
+nm_wimax_util_sdk_ref (void)
+{
+ int ret = 0;
+
+ if (sdk_refcount == 0) {
+ ret = iwmx_sdk_api_init ();
+ if (ret != 0) {
+ nm_log_warn (LOGD_WIMAX, "Failed to initialize WiMAX: %d", ret);
+ return;
+ }
+ }
+ sdk_refcount++;
+}
+
+gboolean
+nm_wimax_util_sdk_is_initialized (void)
+{
+ return sdk_refcount > 0;
+}
+
+void
+nm_wimax_util_sdk_unref (void)
+{
+ g_return_if_fail (sdk_refcount > 0);
+
+ sdk_refcount--;
+ if (sdk_refcount == 0)
+ iwmx_sdk_api_exit ();
+}
+
+NMWimaxNspNetworkType
+nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type)
+{
+ NMWimaxNspNetworkType type;
+
+ switch (wimax_network_type) {
+ case WIMAX_API_HOME:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_HOME;
+ break;
+ case WIMAX_API_PARTNER:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_PARTNER;
+ break;
+ case WIMAX_API_ROAMING_PARTNER:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER;
+ break;
+ default:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN;
+ break;
+ }
+
+ return type;
+}
+
diff --git a/src/wimax/nm-wimax-util.h b/src/wimax/nm-wimax-util.h
new file mode 100644
index 000000000..71f5aa29d
--- /dev/null
+++ b/src/wimax/nm-wimax-util.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_UTIL_H
+#define NM_WIMAX_UTIL_H
+
+#include <glib.h>
+
+#include <WiMaxType.h>
+#include <WiMaxError.h>
+#include "nm-wimax-types.h"
+
+void nm_wimax_util_sdk_ref (void);
+
+gboolean nm_wimax_util_sdk_is_initialized (void);
+
+void nm_wimax_util_sdk_unref (void);
+
+NMWimaxNspNetworkType nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type);
+
+#endif /* NM_WIMAX_UTIL_H */